我有一个本地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());

09-25 20:18