1. 程式人生 > >FTPClient上傳和下載檔案,中文亂碼問題解決

FTPClient上傳和下載檔案,中文亂碼問題解決

 使用類:

           org.apache.commons.net.ftp.FTPClient

   問題描述:

      建立中文目錄、上傳中文檔名時,目錄名及檔名中的中文顯示亂碼

   解決方法:

           在網上Google了一些資料, FTP協議裡面,規定檔名編碼為iso-8859-1,所以目錄名或檔名需要轉碼。

    所以網上很多人的解決方法為: 

                  將中文的目錄或檔名轉為iso-8859-1編碼的字元。參考程式碼:

                  String name="目錄名或檔名";

                  name=new String(name.getBytes("GBK"),"iso-8859-1");

           很多人改為上述操作後,發現上傳後中文不再亂碼了,就以為解決了問題

           還有人處理方法為:

                 ftpClient.setControlEncoding("GBK");

                 FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);

                 conf.setServerLanguageCode("zh");  

上述的處理方法,我都試過,發現在我自己搭建的FTP伺服器上,上傳的檔案中文是正常的,不是亂碼,我當時以為中文問題就解決了,但是測試部的同事在將檔案上傳到他們搭建的FTP伺服器上時,檔案中文路徑仍然是亂碼,所以上述的解決方法是錯誤的。

 

          上面的方法之所以錯誤的原因是因為是沒有考慮ftp伺服器的編碼格式。我搭建的Ftp伺服器(windows2003 server)支援GBK編碼方式,所以上述的解決方法可以,但是測試部的同事搭建的Ftp伺服器(serv-u)是支援UTF-8格式的,所以此時在客戶端的編碼方式是GBK的,而搭設的ftp伺服器中的設定就已經是utf-8的編碼,所以肯定還是會出現亂碼的問題。

         那麼正確的解決方法時是什麼呢,我們可以仿照FlashFXP、FileZilla等ftp 客戶端連線工具,看看他們是如何實現的,下面的兩張圖就是FileZilla的配置資訊和連線時的命令資訊。

   

           圖1:FileZilla配置資訊 

                                                                                    圖2:FileZilla連線時資訊 

從圖2中我們可以看到原來它向伺服器傳送了OPTS UTF8 ON命令,來開啟伺服器對UTF-8的支援。所以我們也可以仿照FileZilla那樣向伺服器傳送該命令。如果伺服器支援UTF-8我們就用UTTF-8,否則我們就用本地編碼(GBK)來處理中文檔名。

下面是Java程式碼:

/** 本地字元編碼 */
private static String LOCAL_CHARSET = "GBK";
 
// FTP協議裡面,規定檔名編碼為iso-8859-1
private static String SERVER_CHARSET = "ISO-8859-1";
 
private void connectFtpServer() {
if (ftpClient == null) {
ftpClient = new FTPClient();
}
if (ftpClient.isConnected()) {
return;
}
String host = getConfigValue(ADDRESS);
int port = Integer.valueOf(getConfigValue(PORT));
String user = getConfigValue(USER);
String password = getConfigValue(PASSWORD);
try {
ftpClient.connect(host, port);
if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
if (ftpClient.login(user, password)) {
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(
"OPTS UTF8", "ON"))) {// 開啟伺服器對UTF-8的支援,如果伺服器支援就用UTF-8編碼,否則就使用本地編碼(GBK).
LOCAL_CHARSET = "UTF-8";
}
ftpClient.setControlEncoding(LOCAL_CHARSET);
ftpClient.enterLocalPassiveMode();// 設定被動模式
ftpClient.setFileType(getTransforModule());// 設定傳輸的模式
return;
} else {
throw new FileStorageException(
"Connet ftpServer error! Please check user or password");
}
}
} catch (IOException e) {
disConnectServer();
throw new FileStorageException(
"Connet ftpServer error! Please check the Configuration");
}
}
上傳檔案時,檔名稱需要做編碼轉換
fileName = new String(fileName.getBytes(LOCAL_CHARSET),
SERVER_CHARSET);

通過上述方法,就能解決了中文亂碼的問題

-----------------------------------------------------------------------------以上為轉載,出處:http://www.linuxidc.com/Linux/2014-10/107585.htm-----------------

servlet+jsp用FileZilla Server伺服器完成檔案上傳及下載。

需注意的地方:上傳:1.後臺獲取前臺jsp頁面選擇的檔案路徑(包含中文)時,要對路徑進行編碼

《部分程式碼》 String filePath = request.getParameter("fileName");
            String name = filePath.substring(filePath.lastIndexOf("\\")+1);//獲得檔名
           System.out.println(name+"-----------"+filePath);
            //為中文檔案設定編碼格式,正確解析
name = new String(name.getBytes("iso-8859-1"),"utf-8");
            filePath = new String(filePath.getBytes("iso-8859-1"),"utf-8");

 File srcFile = new File(filePath); 
            fis = new FileInputStream(srcFile); 
            //設定上傳目錄 
            ftpClient.changeWorkingDirectory("/upload"); 
            ftpClient.setBufferSize(1024); 
            //設定檔案型別(二進位制) 
           ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); 
           ftpClient.storeFile(new String(name.getBytes("gbk"), "iso-8859-1") , fis); 

下載:2.提供兩種下載方式

String fileName =  request.getParameter("fileName");
fileName = new String(fileName.getBytes("iso-8859-1"),"utf-8");
FTPClient ftp = new FTPClient();
FileOutputStream fos = null;
String localPath = request.getRealPath("") + File.separator + "Download" + File.separator;
File localFile = new File(localPath + "" + fileName);
// 下載檔案的路徑
String path = localPath+ "" + fileName;

/*
  * 使用FTP下載:把FTP伺服器上面的檔案下到Tomcat工程目錄下,指定下載路徑。

  */
try{
ftp.connect("127.0.0.1");
ftp.login("shmily", "shmily");
String remoteFileName = "/Download/"+ "" + fileName;
ftp.changeWorkingDirectory(remoteFileName);
fos = new FileOutputStream(path); 
ftp.retrieveFile(new String(remoteFileName.getBytes("gbk"), "iso-8859-1"), fos);}catch (IOException e) { 
            e.printStackTrace(); 
            throw new RuntimeException("FTP客戶端出錯!", e); 
        } finally { 
            IOUtils.closeQuietly(fos); 
            try { 
                ftp.disconnect(); 
            } catch (IOException e) { 
                e.printStackTrace(); 
                throw new RuntimeException("關閉FTP連線發生異常!", e); 
            } 
        } 
/*
 * 使用瀏覽器下載:將Tomcat工程路徑下的檔案下到本地,可選擇下載路徑。

 */
if (!localFile.exists())
localFile.createNewFile();
response.setContentType("application/x-download");// 設定為下載application/x-download
fileName = URLEncoder.encode(fileName, "UTF-8");
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);// 下載檔案時,顯示的檔名
OutputStream output = response.getOutputStream();
FileInputStream fis = new FileInputStream(path);


byte[] b = new byte[10240];
int i = 0;


while ((i = fis.read(b)) > 0) {
output.write(b, 0, i);
}
output.flush();
fis.close();
output.close();