2

FTP服务会在传输数据的时候开通新的端口号,这样有的端口号没有被服务器收入合法,所以一直不好使。但我这边测试的时候win上下载可以,Linux文件超过100k的时候会下载不下来。不清楚什么原因可能是流的传输方式不同。下边贴上测试好的代码

Windos版

public static void dowmloadFtpWindos(String fileUuid, HttpServletRequest request,HttpServletResponse response) {
        LmpFileInfo finfo = lmpFileInfoServiceClient.getByUuid(fileUuid);
        String dfname = processFileName(request, finfo.getName());
        response.setContentType("multipart/form-data;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName=" + dfname);
        FtpUtil ftpUtil = new FtpUtil();
        try {
            String saveurl = finfo.getSaveurl();
            String targetPath = "";
            String fileName = "";
            if (saveurl != null && saveurl.lastIndexOf('/') > 0) {
                targetPath = finfo.getSaveurl().substring(0, saveurl.lastIndexOf('/'));
                fileName = finfo.getSaveurl().substring(saveurl.lastIndexOf('/') + 1);
            }
            ftpUtil.downFile(targetPath,fileName,response);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ftpUtil.disConFtp();
        }
    }
    
public boolean downFile(String remotePath, String fileName, HttpServletResponse response) {
        boolean success = false;
        try {
            // ftpClient.enterLocalPassiveMode();//在lunix下不可用
            ftpClient.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
            FTPFile[] fs = ftpClient.listFiles();
            for (int i = 0; i < fs.length; i++) {
                FTPFile ff = fs[i];
                if (ff.getName().equals(fileName)) {
                    // File localFile = new
                    // File("D:"+File.separator+ff.getName());
                    OutputStream is = response.getOutputStream();
                    OutputStream out = new BufferedOutputStream(is);
                    // 注意此处retrieveFile的第一个参数由GBK转为ISO-8859-1编码。否则下载后的文件内容为空。
                    // 原因可能是由于aix系统默认的编码为ISO-8859-1
                    ftpClient.retrieveFile(new String(ff.getName().getBytes("GBK"), "ISO-8859-1"), out);
                    out.flush();
                    is.close();
                    out.close();
                }
            }
            ftpClient.logout();
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }

Linux版

public static String dowmloadFtpLunix(String fileUuid, HttpServletRequest request, HttpServletResponse response) {
        LmpFileInfo finfo = lmpFileInfoServiceClient.getByUuid(fileUuid);
        String dfname = processFileName(request, finfo.getName());
        response.setContentType("multipart/form-data;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName=" + dfname);
        FtpUtil ftpUtil = new FtpUtil();
        try {
            FTPClient ftp = ftpUtil.getFtpClient();
            // 设置PassiveMode传输
            ftp.enterLocalPassiveMode();
            // 设置以二进制流的方式传输
            ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            String saveurl = finfo.getSaveurl();
            String targetPath = "";
            String fileName = "";
            if (saveurl != null && saveurl.lastIndexOf('/') > 0) {
                targetPath = finfo.getSaveurl().substring(0, saveurl.lastIndexOf('/'));
                fileName = finfo.getSaveurl().substring(saveurl.lastIndexOf('/') + 1);
            }
            ftp.changeWorkingDirectory(targetPath);
            InputStream input = ftp.retrieveFileStream(new String(fileName.getBytes("GBK"),"ISO-8859-1"));
            OutputStream out = response.getOutputStream();
            int buf = -1;
            while ((buf = input.read()) != -1) {
                out.write(buf);
            }
            out.flush();
            input.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            ftpUtil.disConFtp();
        }
        // 返回值要注意,要不然就出现下面这句错误!
        // java+getOutputStream() has already been called for this response
        return null;
    }

唯一不同的点就是
ftpClient.retrieveFile和ftp.retrieveFileStream这两个方法不一样。
希望能给遇到问题的人一点提示。后边再研究到底为啥?


刘小西
4 声望0 粉丝