我有一个本地FTP服务器(使用FileZilla服务器创建),并且XLS文件很少。我需要将文件输入流返回到我的Java应用程序,以便可以解析数据等。
为此,我尝试使用FTPClient,但是由于某种原因,试图从文件(大于40KB或以上)返回输入流时,FTPClient.retrieveFileStream()挂起。
我知道也有类似的问题,并且我已经阅读了所有这些问题,至少我能找到的所有问题,没有任何帮助。这真的很烦人,如果可能的话,我需要一些帮助。
相关代码部分:
public FTPwrapper(){
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Properties props = (Properties) context.getBean("ftp_props");
this.FTPhost = props.getProperty("host");
this.FTPuser = props.getProperty("user");
this.FTPpass = props.getProperty("pass");
this.FTPport = Integer.parseInt(props.getProperty("port"));
this.filesPath = props.getProperty("filesPath");
//start ftp connection
try {
client.connect(this.FTPhost, this.FTPport);
client.login(this.FTPuser, this.FTPpass);
client.setBufferSize(1024 * 1024);
client.enterLocalPassiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE);
} catch (IOException e) {
e.printStackTrace();
}
}
public InputStream returnFileStream(String FileName){
InputStream inputstream = null;
try {
String remoteFile = this.filesPath+FileName;
inputstream = client.retrieveFileStream(remoteFile);
client.completePendingCommand();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (client.isConnected()) {
client.logout();
client.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return inputstream;
}
public static void main(String[] args){
FTPwrapper ftp = new FTPwrapper();
InputStream inputstream = ftp.returnFileStream("2012 m muzieju statistika.xls");
}
FPT日志:
...login commands...
227 Entering Passive Mode
RETR /vtipsis_data/KT/2012 m muzieju statistika.xls
50 Opening data channel for file download from server of "/vtipsis_data/KT/2012 m muzieju statistika.xls" //Hangs...
在ftp连接最终超时后,我得到了Java异常:
java.io.IOException: Your file contains 383 sectors, but the initial DIFAT array at index 4 referenced block # 505. This isn't allowed and your file is corrupt
at org.apache.poi.poifs.storage.BlockAllocationTableReader.<init>(BlockAllocationTableReader.java:103)
at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:151)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:322)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:303)
我认为此异常是因为仅返回了我的XLS文件inputstream的一部分。就是这样,我的问题。任何想法如何解决这个问题?
最佳答案
这不是我想要的答案,而是一种解决方法,该解决方案就足够了。我不是使用retrieveFileStream
直接尝试检索流,而是使用retrieveFile
将文件下载为临时系统文件,并转换了OutputStream,我从retrieveFile
到InputStream。之后,我只是删除下载的临时文件。
使用it.sauronsoftware.ftp4j
尝试过,但是它没有与retrieveFileStream
类似的方法/功能,只能下载文件。
编辑:
我找到了一种无需使用retrieveFileStream
或下载文件即可返回文件inputstream的方法。由于retrieveFile
返回OutputStream,所以我可以将OutputStream转换为InputStream(为什么以前没有想到?),如下所示:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
client.retrieveFile(remoteFile, outputStream);
InputStream inputstream = new ByteArrayInputStream(outputStream.toByteArray());