天天看點

FTP上傳下載下傳失敗或檔案為空

這兩天做了一個ftp檔案上傳和下載下傳功能,開發中發現上傳失敗,沒有将檔案上傳到伺服器上面,下載下傳的時候隻是建立了一個檔案,檔案大小為0kb,兩個ftp伺服器互相傳輸也會出現種現象。這中現象都是因為編碼格式導緻的,也就是檔案名中有中文,沒有中文的時候應該都是正常的。

使用的環境:

工具IDEA,jdk1.8,

jar包有commons-net-3.8.0.jar、jakarta-oro-2.0.8.jar

1、上傳時調用FTPClient的storeFile()方法沒有成功上傳檔案到伺服器。

有人說要先調用FTPClient的enterLocalPassiveMode()方法,試過之後還是不成功,後來看網上有人說檔案名需要處理下,代碼入下:

boolean b = ftpClient.storeFile(new String(file2.getName().getBytes("GB2312"),"ISO-8859-1"), inputStream);
           

調用上面方法後,檔案上傳成功。

原因還沒有研究,隻是這樣調用之後就上傳成功了。

2、調用FTPClient的retrieveFile()方法,這時下載下傳了一個大小為0kb的檔案。

也是講檔案名做過處理之後就下載下傳成功了,代碼如下:

ftpClient.retrieveFile(new String(ftpFile.getName().getBytes("GB2312"),"ISO-8859-1"), outputStream);
           

3、一個ftp伺服器通過Java向另外一個ftp伺服器傳送檔案,出現上傳0kb檔案問題。

這個也是由于編碼問題引起的(檔案名中有中文),話不多說上代碼:

/**
     *
     * @param ftpUp 上傳ftp連接配接
     * @param ftpDown 源檔案ftp連接配接
     */
    public void twoFTPTransfer(FTPClient ftpUp, FTPClient ftpDown){
        try {
            //先設定源檔案的編碼格式
            ftpDown.setControlEncoding("GBK");
            FTPFile[] ftpFiles = ftpDown.listFiles();
            for (FTPFile ftpFile : ftpFiles){
                //擷取上傳檔案流
                OutputStream outputStream = ftpUp.storeFileStream(new String(ftpFile.getName().getBytes("GB2312"), FTP.DEFAULT_CONTROL_ENCODING));
                //這句話是把檔案從ftpDown複制到ftpUp中,通過流outputStream
                boolean b = ftpDown.retrieveFile(new String(ftpFile.getName().getBytes("GB2312"), FTP.DEFAULT_CONTROL_ENCODING), outputStream);
                outputStream.close();
                ftpUp.completePendingCommand();
                System.out.println("ftpFile:" + ftpFile);
                System.out.println("ftpFile.getName():" + ftpFile.getName());
                System.out.println(new String(ftpFile.getName().getBytes("GB2312"), FTP.DEFAULT_CONTROL_ENCODING));
            }
        } catch (Exception e) {
            logger.error("ftp傳輸失敗:" + e);
        }
    }
           

上面的代碼裡面的  ftpDown.setControlEncoding("GBK"); 這句不要忘記寫了,擷取輸出流或者寫檔案的時候會有問題。

下面是我擷取ftp連接配接的代碼,為了友善對着看我也拿上來了

/**
     * 擷取ftp連接配接
     * @param ftp
     * @return
     * @throws IOException
     */
    public static FTPClient connectFtp(Ftp ftp) throws IOException {
        FTPClient ftpClient = new FTPClient();
        int reply;
        if(ftp.getPort() == null){
            ftpClient.connect(ftp.getIpAddr(), 21);
        }else {
            ftpClient.connect(ftp.getIpAddr(), ftp.getPort());
        }
        ftpClient.login(ftp.getUserName(), ftp.getPwd());
        ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
        reply = ftpClient.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)){
            //關閉與FTP伺服器的連接配接并将連接配接參數恢複為預設值。
            ftpClient.disconnect();
            return null;
        }
        //ftpClient.makeDirectory(pathname);
        ftpClient.enterLocalPassiveMode();
        //檔案路徑中有中文的時候需要将路徑做處理
        ftpClient.changeWorkingDirectory(ftp.getPath());

        return ftpClient;
    }