Java下载海量文件,在一段时间后在互联网网址上显示连接关机/重置

时间:2017-05-10 19:32:58

标签: java swing httpurlconnection

我正在构建一个swing应用程序,通过互联网下载多个文件并保存到Windows文件共享。我已经使用了SwingWroker,它在内部使用ExecutorService,它在内部对它们进行排队并一次下载10个,但由于某种原因,下载后说2 - 3 MB的文件它会停止并转移到下一个下载文件,它们将被批量下载10个因为SwingWorker已将其固定为Executor Service的线程数。

我必须在Windows文件共享中编写这些文件,并且我使用nio.FileChannels来执行此操作。有50-60个文件,每个重约300MB - 500MB。文件链接位于我通过互联网使用登录页面上的凭据(带有帖子请求)登录的网页上,然后我在开头指定CookieHandler.setDefault(new CookieManager()),因此它的行为类似于浏览器对我来说。

另一个观察是当我在本地下载它们(而不是Windows服务器共享)时,它们可以正常工作。

这是我正在使用的代码

import java.io.File;
import java.io.FileOutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;

import javax.swing.SwingWorker;

public class DownloadProcess extends SwingWorker<Boolean, String> {

  private String urlPath, filePath;
  public DownloadProcess(String urlPath, String filePath){
    this.urlPath = urlPath;
    this.filePath = filePath;
  }             
  @Override
  protected Boolean doInBackground() {
    boolean taskState = true;
    URLConnection httpConn = null;
    ReadableByteChannel readableByteChannel = null;
    FileOutputStream fileOutputStream = null;
    FileChannel fileOutputChannel = null;
    try{
      //String filePath = "\\\\fileshare.server\\xyz.txt";
      //String urlPath = "http://example.com/anyBigFile.1GB.docx";
      File localFile = new File(filePath);//File share
      boolean itsThere = localFile!=null && localFile.exists();
      long done = itsThere ? localFile.length() : 0;
      URL url = new URL(urlPath);
      httpConn = url.openConnection();
      httpConn.setRequestProperty("Connection", "keep-alive");
      if(itsThere) {
        httpConn.setRequestProperty("Range","bytes="+done+"-");
      }
      readableByteChannel = Channels.newChannel(httpConn.getInputStream());
      fileOutputStream = itsThere ? new FileOutputStream(filePath) : new FileOutputStream(filePath,true);
      fileOutputChannel = fileOutputStream.getChannel();
      for (long position = done, size = httpConn.getContentLength(); position < size && !isCancelled(); ) {
        position += fileOutputChannel.transferFrom(readableByteChannel, position, 1 << 16);
      }
      //done
    }catch(Exception e){
      taskState = false;
      e.printStackTrace();

    }finally{
            //close streams conns etc
    }
    return taskState;
  }

}

这是我在下载5-10分钟后得到的错误堆栈跟踪

/*
  javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: Connection reset
  at sun.security.ssl.SSLSocketImpl.checkEOF(Unknown Source)
  at sun.security.ssl.AppInputStream.read(Unknown Source)
  at java.io.BufferedInputStream.read1(Unknown Source)
  at java.io.BufferedInputStream.read(Unknown Source)
  at sun.net.www.MeteredStream.read(Unknown Source)
  at java.io.FilterInputStream.read(Unknown Source)
  at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
  at java.nio.channels.Channels$ReadableByteChannelImpl.read(Unknown Source)
  at com.objects.DownloadByteChannel.read(DownloadByteChannel.java:117)
  at sun.nio.ch.FileChannelImpl.transferFromArbitraryChannel(Unknown Source)
  at sun.nio.ch.FileChannelImpl.transferFrom(Unknown Source)
  at com.core.DownloadTask.doInBackground(DownloadTask.java:154)
  at com.core.DownloadTask.doInBackground(DownloadTask.java:59)
  at com.util.ZSwingWorker$1.call(ZSwingWorker.java:286)
  at java.util.concurrent.FutureTask.run(Unknown Source)
  at com.util.ZSwingWorker.run(ZSwingWorker.java:325)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
  at java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLException: java.net.SocketException: Connection reset
  at sun.security.ssl.Alerts.getSSLException(Unknown Source)
  at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
  at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
  at sun.security.ssl.SSLSocketImpl.handleException(Unknown Source)
  at sun.security.ssl.SSLSocketImpl.handleException(Unknown Source)
  ... 18 more
Caused by: java.net.SocketException: Connection reset
  at java.net.SocketInputStream.read(Unknown Source)
  at java.net.SocketInputStream.read(Unknown Source)
  at sun.security.ssl.InputRecord.readFully(Unknown Source)
  at sun.security.ssl.InputRecord.read(Unknown Source)
  at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
  at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
  ... 18 more
*/

用法:

public static void main(String[] args){
  int counter = 1;
  for(String url: urls){  
    new DownloadProcess(url,"\\\\fileshare.server\\xyz"+(counter++)+".txt").execute();
  }      
}

2 个答案:

答案 0 :(得分:3)

您将不得不更改连接超时服务器端。如果它们具有任何重要性,我会在路上找到一些链接:

Modify Session Security settings

Lengthening salesforce session timeout

希望这会有所帮助,祝你好运,让我知道:)

答案 1 :(得分:0)

连接重置意味着远程端正在使用TCP RST(重置)数据包关闭连接。你需要找出远程方不喜欢和解决它的问题。

如果远程端是Apache,则可能是您遇到了KeepAliveTimeout值。默认为5秒。这听起来好像你在远程端遇到某种配置限制。当发生这种情况时,服务器会因重置而踢你。