问题描述:
  在客户端有一个大文件,要使用多线程将其上传到服务器端主要有以下问题。
一、怎样将这个文件拆分,以便每个线程传递其一部分,当然在客户端将其拆分好,再上传肯定是可以的。我的意思是可不可以先获得文件的输入流FileInputStream(new File(文件名)),然后在流里面控制要传递哪部分data。二、当这些被切割的文件传到服务器后,怎样在服务器端将其还原为原来的文件呢?
如果不能对服务器端编程,就不可能还原文件?

解决方案 »

  1.   

    我给个思路吧.可以后台做个线程池,线程池里假设有4个线程,你把文件的长度统计一下(或者大致分配一下.)
    每个线程从固定的点开始读文件(读固定长度.)假设:文件有200个字节.
    4个线程 分别从 0 50 100 150开始读,每个线程读50个字节,这样速度就能快很多.等上传完后再合并文件.我只知道一个合并文件的方法:
    COPY:[源盘][路径]〈源文件名1〉〈源文件名2〉…[目标盘][路径]〈目标文件名〉;
      

  2.   

    to ssnec
    思路的确是这样的,可是问题就在于怎样获得这个流的分割。我尝试了几种方案结果都不行。
    一、用InputStream的skip(int len)方法过滤,因为只能跳转掉len长度后传输后面的字节,当有3个线程或更多时,肯定是不行的。二、结合FileChannel的position()方法,去定位流中当前要传输的位置,然后通过read(buf,0,length)取得要传输的那段流,比如ssnec说的传输50k到100k的位置,就可以fileIS.position(50K);
    byte[] buf=new buf[50K];
    fileIS.read(buf,0,50K);
    来完成。但是当文件很大的时候呢,假如文件是2G,那么每个线程负责传500M。
    还是这样的,byte[] buf=new buf[50M];  GOD!!这么大的数组,JVM马上就out of memory了。
    ok,既然这样不行那就把buf设小一点,然后做一个判断,如下
     file.position(startPos);
     byte[] buf = new byte[2048];
     int len=2048;
     while (in.read(buf,0,len)!= -1 && startPos < endPos){
     ftp.put(buf, fileName,true);
     startPos=startPos+len;
     }
    似乎是可以了,但是这样频繁的put()操作也同样有问题,你会发现BindException的错误。
    原因是短时间内new socket操作很多,而socket.close( )操作并不能立即释放绑定的端口,导致系统资源耗尽。所以最后还是决定放弃在流里面分割的想法,其实用多个线程传多个文件,和将一个大文件用多个线程传,效果也是一样的嘛。
      

  3.   

    在上传文件时,遇到新问题,当网络连接断开后,会触发一个connect reset exception异常。同时刚刚上传未成功的文件,也没有保存下来。这样就不能断点续传了,请问要怎么解决?