概述:
org.apache.commons.net.ftp 下载多个文件时,程序出现假死状态。
详述:
以下代码为使用 org.apache.commons.net.ftp 下载某个文件目录下的所有文件。(已经确定该目录下只存在文件,不再存在子目录)  /**
 * 
 * @param localWorkingDir ftp 工作目录,(即要下在该目录下的所有文件)
 * @param bufferSize
 * @throws IOException
 */
private void downloadFile(String localWorkingDir,int bufferSize) throws IOException{
FTPClient fc = getConnectedFTPClient();
fc.setBufferSize(bufferSize);
fc.setFileType(FTPClient.BINARY_FILE_TYPE);

localWorkingDir = localWorkingDir.concat(File.separator);
FTPFile[] sourceFiles = fc.listFiles();
     String localFilePath = null;
     String soucceFileName = null;
     for(FTPFile sourceFile : sourceFiles){
     if(sourceFile.isFile()){
     soucceFileName = sourceFile.getName();
         localFilePath = localWorkingDir.concat(soucceFileName);
     try {
         FileOutputStream os = new FileOutputStream(localFilePath);
     fc.retrieveFile(soucceFileName, os); //sign1
     System.out.println(soucceFileName);
     os.close();
     } catch (IOException e) {
     e.printStackTrace();
     }
         }
     }
    }

/**
 * 获取已经连接好的 FTPClient
 * @return
 */
private FTPClient getConnectedFTPClient(){
..........
..........
}
我需要下载的文件大概有4千多个,可是这段代码下载了几百个(最多一千多个)文件后就在 sign1 处停滞。循环不再执行(System.out.println(soucceFileName);不再执行)。程序也无法自然结束。没有任何异常和信息。换成 retrieveFileStream(String remote)也不行。现象与 retrieveFile 一样 

解决方案 »

  1.   

    推测
    1.FTP断开链接
    2.传输大的文件中
      

  2.   


    FTP 没有断开。文件也不大,最大的200多k
      

  3.   

    看了一下ftpClient的源代码,下载文件就是使用socket建立连接
    然后调用了Util.copyStream(...)来把远程的stream读进来
    进一步看Util.copyStream(...),里面有这么一行注释102                    // Technically, some read(byte[]) methods may return 0 and we cannot
    103                    // accept that as an indication of EOF.
    104    
    105                    if (bytes == 0)
    106                    {
    107                        bytes = source.read();
    108                        if (bytes < 0)
    109                            break;
    110                        dest.write(bytes);
    111                        if(flush)
    112                          dest.flush();
    113                        ++total;
    114                        if (listener != null)
    115                            listener.bytesTransferred(total, 1, streamSize);
    116                        continue;
    117                    }
    然而InputStream的read()方法的javadoc上又这么写着This method blocks until input data is available, the end of the stream is detected, or an exception is thrown. 
    所以我想,可能是这个read停住不动了
    也就是FtpClient本身的问题Util.copyStream参看
    http://commons.apache.org/net/apidocs/src-html/org/apache/commons/net/io/Util.html解决方法嘛,可以换个第三方的ftpclient的包
    或者绕个圈去解决这个问题,例如设个timeout,timer之类的,到时间还没有新数据,就断开,然后从断开的文件处继续继续下载
      

  4.   

    代码改成重复下载同一个文件,执行到三千多次的时候就卡住了。下载源码以后发现是在FTPClient的_openDataConnection_方法中,执行socket = server.accept();时卡住的
      

  5.   

    通过设置超时ftpclient.setDataTimeout(3 * 1000);可以在等待一段时间后抛出异常,不过我觉得这不是最好的办法,还是得找出原因为什么会卡住