When I try to upload Chinese file name via commons-net, I get this error : 550 can't access file. The complete log is as bellows:
220-written by Tim Kosse (Tim.Kosse@gmx.de) 220 Please visit http://sourceforge.net/projects/filezilla/ USER ******* 331 Password required for chtuser PASS ******* 230 Logged on TYPE I 200 Type set to I CWD /tcpb 250 CWD successful. "/tcpb" is current directory. PASV 227 Entering Passive Mode (192,168,32,66,8,2) STOR 中文測試.zip 150 Connection accepted 550 can't access file. QUIT 221 Goodbye
FtpService is as following:
package test.service; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import org.apache.commons.net.PrintCommandListener; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import lombok.extern.slf4j.Slf4j; @Slf4j @Service public class FtpService { @Value("${ftp.host}") private String host; @Value("${ftp.port}") private Integer port; @Value("${ftp.user}") private String user; @Value("${ftp.password}") private String password; private FTPClient client; /** * Stores a file on the server using the given name. * * @param directory * specific working directory * @param file * local file * @throws IOException */ public void uploadFile(String directory, File file) throws IOException { try (InputStream is = new FileInputStream(file);) { connect(); client.changeWorkingDirectory(directory); client.storeFile(file.getName(), is); } catch (IOException e) { throw new IOException("fail to upload file", e); } finally { disconnect(); } } /** * Connect to FTP server. * * @throws IOException */ private void connect() throws IOException { try { client = new FTPClient(); client.addProtocolCommandListener( new PrintCommandListener(new PrintWriter(System.out), true)); client.connect(host, port); int reply = client.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { client.disconnect(); throw new IOException("Exception in connecting to FTP Server"); } client.login(user, password); client.enterLocalPassiveMode(); client.setFileType(FTP.BINARY_FILE_TYPE); log.debug("connect to FTP server succesfully"); } catch (IOException e) { throw new IOException("fail to connect to FTP server", e); } } /** * Disconnect from FTP server. * * @throws IOException */ private void disconnect() throws IOException { try { if (client.isConnected()) { client.logout(); client.disconnect(); } log.debug("disconnect from FTP server succesfully"); } catch (IOException e) { throw new IOException("fail to disconnect from FTP server", e); } } }
How-To
Owning to the FTP server does not know the file name encoding, so you need to convert file name encoding to iso-8859-1. The uploadFile method should be modified as bellows:
/** * Stores a file on the server using the given name. * * @param directory * specific working directory * @param file * local file * @throws IOException */ public void uploadFile(String directory, File file) throws IOException { try (InputStream is = new FileInputStream(file);) { connect(); client.changeWorkingDirectory(directory); client.storeFile(new String(file.getName().getBytes(), "iso-8859-1"), is); } catch (IOException e) { throw new IOException("fail to upload file", e); } finally { disconnect(); } }
No comments:
Post a Comment