[color=gray]http://blog.163.com/comfort_122/blog/static/489044092010101205144475/
[color=gray]环境:FTP Server是Windows 2003 IIS ; 开发环境客户端是在windows下tomcat的一个web应用 ; 部署环境是在 linux redhat 下的tomcat的一个web应用。
问题:通过struts2的stream返回类型返回由ftpclient从ftp服务器上取得的文件。文件类型可能是excel或者rar压缩包。在开发环境运行正常,但部署后,发现部分excel文件和全部的rar文件下载后都无法打开。
解决:
以某个不能打开的excel文件为例子,从windows下取得的文件大小是52115字节,从linux下取得的文件大小是52114字节,原始的文件是52115字节,linux下载的少了一个什么呢?
用Beyond Compare比较两个文件的十六进制。原始的文件(或通过windows下载的)有一处是“0D 0A”,而linux下载的是“ 0A”。
比较Ascii值,可以判断是由于换行符引起的问题,windows是\r\n ,而linux下是\n 。
那么意味着ftpclient取得文件时做了换行符号的转换。
如何禁止ftp传输过程的换行符转换?查阅一下ftpclient的api,里面有个setFileType方法,与我们用ftp工具或者命令行方式设置ftp传输方式一致。
看一下ftpclient类的源码 :“__fileType = FTP.ASCII_FILE_TYPE;” 。默认的传输方式是ASCII,这样确实会由于换行符引起一些问题,比如在windows下编辑shell传到服务器就常常会收到“syntax error near unexpected token” 这样的问题,可以用dos2unix命令转换行,或者将编辑器如editplus的换行格式设为unix格式。
那么在ftpclient登录成功后,和开始下载文件前设置传输类型即可。
ftpclient.login(user, password);
ftpclient.setFileType(FTP.BINARY_FILE_TYPE);
经过分析发现,linux环境与win环境的ftp操作有以下差别:
1、文件中的数据回车换行符不同
win的回车换行时:/r/n
linux的回车换行是:/n
//从FTP上下载文件并打成ZIP包给用户下载
FTPClient ftpClient = null;
ZipOutputStream zipOut = null;
try {
// 创建ftp连接对象
ftpClient = new FTPClient();
ftpClient.connect(FtpContants.FTP_IP, FtpContants.FTP_PORT);
// 登陆ftp服务器
ftpClient.login(FtpContants.FTP_USERNAME, FtpContants.FTP_PWD);
// 设置文件的传输类型,默认是ASCII,修改为二进制
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// printWorkingDirectory是用户的工作目录
String basePath = ftpClient.printWorkingDirectory() + "/download/data";
// 切换到指定目录中,如果切换失败说明目录不存在
boolean boo = ftpClient.changeWorkingDirectory(basePath);
// 如果切换路径失败,说明拼接的路径有问题,抛出异常
if (!boo) {
LogUtil.printErrorLog("the directory does not exist ,"
+ "or the user don't hava the enterence to this directory " + basePath);
return;
}
// 这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据
ftpClient.enterLocalPassiveMode();
// 遍历路径下的所有文件
FTPFile[] fileList = ftpClient.listFiles();
response.reset();
// 设置导出文件头
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment;filename=" + new String(zipFileName.getBytes(LANGUE_GBK), LANGUE_ISO));
// 定义Zip输出流
zipOut = new ZipOutputStream(response.getOutputStream());
byte[] byteReader = new byte[BYTE_INIT_SIZE];
ByteArrayOutputStream os = null;
for (FTPFile tempFile : fileList) {
if (tempFile.isFile()) {
os = new ByteArrayOutputStream();
String downFileName = new String(tempFile.getName().getBytes(LANGUE_GBK), LANGUE_ISO);
// 从FTP上下载downFileName该文件把该文件转化为字节数组的输出流
ftpClient.retrieveFile(downFileName, os);
byte[] bytes = os.toByteArray();
InputStream ins = new ByteArrayInputStream(bytes);
int len;
zipOut.putNextEntry(new ZipEntry(tempFile.getName()));
// 读入需要下载的文件的内容,打包到zip文件
while ((len = ins.read(byteReader)) > 0) {
zipOut.write(byteReader, 0, len);
}
}
}
zipOut.flush();
} catch (IOException e) {
LogUtil.printErrorLog(e.getMessage());
throw new SopSystemException(e.getMessage());
} finally {
// 关闭ftp连接
if (null != ftpClient) {
try {
ftpClient.disconnect();
} catch (IOException e) {
LogUtil.printErrorLog("close Ftp connection error :" + e.getMessage());
}
}
// 关闭zip文件输出流
if (null != zipOut) {
try {
zipOut.closeEntry();
zipOut.close();
} catch (IOException e) {
LogUtil.printErrorLog("close ZipOutputStream connection error :" + e.getMessage());
}
}
}
分享到:
相关推荐
在IT行业中,FTP(File Transfer Protocol)是一种广泛用于在互联网上传输文件的标准协议。通过FTP,用户可以连接到远程服务器,进行文件的上传、下载、查看属性等操作。本篇文章将详细讲解如何编写源码来获取FTP...
FTP是一种用于在Internet上进行文件传输的标准协议。Java提供了一个内置的`java.net.FTPClient`类,可以方便地进行FTP操作。为了实现文件上传,我们需要创建一个`FTPClient`实例,连接到FTP服务器,然后调用`...
此类可能会有一个`uploadFile`方法,接收大文件和FTPClient实例作为参数,内部使用`java.nio`包进行高效的文件读取和上传。 总的来说,实现Java大文件上传至FTP服务器并显示同步进度条涉及的关键技术点包括:...
FTP(File Transfer Protocol)是一种广泛使用的网络协议,用于在互联网上进行文件传输。在这个场景中,我们使用FTP协议来实现在远程服务器上上传和下载文件的功能。C#和Asp.NET是开发此类应用的主要编程语言和技术...
根据给定文件的信息,本文将详细介绍如何利用Java代码来实现从FTP服务器下载文件的过程,并对代码中的关键步骤进行深入解析。 ### Java下载FTP文件 在实际应用开发中,经常需要与FTP服务器进行交互,比如上传文件...
在Java编程环境中,FTP(File Transfer Protocol)文件下载是一个常见的任务,特别是在处理大量数据传输时。本场景中,我们关注的重点是如何实现一个功能完善的FTP下载工具,它支持断点续传,即当下载中断后可以从...
FTP(File Transfer Protocol)是一种用于在网络上进行文件传输的标准协议,主要用于在不同主机之间传输文件。`FTPClient`是Apache Commons Net包中的一个类,提供了一种简单的方式来实现FTP客户端的功能,包括文件...
ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分功能。可以将ftp4j嵌到你的Java应用中,来传输文件(包括上传和下载),浏览远程FTP服务器上的目录和文件,创建、删除、重命,移动远程目录和文件。ftp...
FTPClient是一款基于C# 2.0开发的Windows应用程序,它实现了FTP(文件传输协议)客户端的功能,允许用户与FTP服务器进行交互,如上传、下载、列出目录、删除文件等。这个源码对于学习和理解网络编程,尤其是FTP协议...
FTP(File Transfer Protocol)是一种广泛使用的网络协议,用于在互联网上进行文件的上传和下载。FTP使得用户可以方便地在本地计算机与远程服务器之间交换数据。在这个场景中,我们主要探讨FTP客户端如何实现文件的...
为了提高效率,可以考虑使用FTP的批量操作,例如,如果需要上传或下载多个文件,可以一次性设置传输模式,然后在一个会话中处理所有文件。 8. **安全性考虑** 虽然FTP是常见的文件传输方式,但它不提供内置的加密...
在上传文件时,使用`FTPClient`的`storeFile()`方法,并传递当前已上传的字节数: ```java OutputStream outputStream = null; try { outputStream = ftpClient.storeFileStream("remote_file_path"); ...
FTP(File Transfer Protocol)是一种广泛使用的网络协议,用于在互联网上进行文件的传输。FTP上传下载工具类通常是指一个编程接口或代码库,为开发者提供便捷的FTP客户端功能,包括连接到FTP服务器、上传文件、下载...
FTP(File Transfer Protocol)是一种用于在网络上进行文件传输的标准协议,而断续上传和下载则是FTP协议的一个扩展功能,允许用户在文件传输过程中暂停并继续,避免了因网络中断或其他问题导致的文件传输失败。...
为了在WPF应用中实现FTP功能,我们需要使用一个支持FTP的库,如`System.Net.FtpClient` 或第三方库如 `FluentFTP`。这些库提供了FTP命令的封装,使开发者能够方便地进行文件操作。 接下来,我们关注断点续传。断点...
2. **Java FTP库**:Java标准库提供了一个名为`java.net.Socket`的类来处理基本的FTP连接,但通常开发人员会使用更高级的库,如Apache Commons Net库,它提供了一个完善的FTPClient类,简化了FTP操作。 3. **Apache...
具体做法是在FTP客户端库提供的接口中注册一个监听器,监听文件传输过程中的字节变化,从而计算当前传输的百分比。 ```java ftpClient.addTransferListener(new TransferListener() { public void bytes...
FTP(File Transfer Protocol)是一种广泛使用的互联网协议,用于在不同网络之间传输文件。在这个实例中,我们关注的是如何实现一个带有进度条的FTP文件上传功能。这个FTP上传实例提供了可视化的进度反馈,使得用户...
在Java中实现FTP(File Transfer Protocol)文件上传和下载时,可能会遇到各种问题,如速度慢、中文乱码以及多文件下载等。以下将详细解释如何解决这些问题,并提供相关的代码示例。 首先,针对文件上传慢的问题,...
在这个“FTP上传下载工具”中,开发者使用Java语言构建了一个功能强大的客户端应用,它能够实现文件和文件夹的上传与下载,并且带有进度显示,极大地提高了用户在处理大文件时的体验。 1. **Java FTP库**: 这个...