Reputation: 1334
I have a local FTP server (created with FileZilla server), and there are few XLS files. I need to return file input stream to my Java app so I could parse data etc.
To do so, I tried using FTPClient, but for some reason, while trying to return inputstream from files (bigger than 40KB or) FTPClient.retrieveFileStream() hangs.
I know there are similar questions to this, and I've read them all, at least all that I could find, and nothing helped me. This is really annoying and I'd like some help if possible.
Relevant code parts:
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 log:
...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...
After ftp connection finally time outs, I get java exception:
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)
I assume this exception is because only part of my XLS file inputstream is returned. So there it is, my problem. Any ideas how to solve this?
Upvotes: 3
Views: 9956
Reputation: 1334
This is not the answer I wanted, but a workaround which will have to suffice... Instead of trying to retrieve stream directly, using retrieveFileStream
, I used retrieveFile
to download file as a temporary system file, and converted OutputStream, which I got from retrieveFile
to InputStream. After that I just delete downloaded temporary file.
Tried using it.sauronsoftware.ftp4j
, but It has no method/function similar to retrieveFileStream
and can only download file.
EDIT:
I found a way to return file inputstream without using retrieveFileStream
or downloading file. Since retrieveFile
returns OutputStream, I can just convert OutputStream to InputStream (Why didn't I think of this before?) like:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
client.retrieveFile(remoteFile, outputStream);
InputStream inputstream = new ByteArrayInputStream(outputStream.toByteArray());
Upvotes: 7