如果使用Java开发多线程传输文件,你如何实现

面试题:如果使用Java开发多线程传输文件,你如何实现。(只需要说明技术和思路)

BS结构

H5,文件组件标签,有多个属性,文件切割相关属性。把一个文件切割,从文件的第几个字节开始读取,读取多少字节。

服务端本身就是一个多线程,
Commons-Fileupload

一个进程有多个线程,一个线程有多个协程

CS结构

使用多线程技术和RandomAccessFile技术实现。
多线程,提高效率使用ExecutorService线程池,优化代码。
RandomAccessFile是随机文件读写流,打开文件,做随机读写。通过分隔文件,跳过不需要读写的字节数,进行读写操作。

socket+IO
java.io.RandomAccessFile 文件随机读写流

上传:
client:

 class ClientMain{
	  public static void main(String[] args){
	    Socket s = new Socket(ip, port);
	    File file = new File(path);
	    FileInputStream fis = new FileInputStream(file);
	    // 文件的总体长度
	    long length = fis.available();
            // 设置10线程上传。
	    long point = length/10;
	    // 让服务器创建文件
            OutputStream output = s.getOutputStream();
	    output.write("{\"filename\"=\"xxx\"}".byteArray());
	    // 阻塞等待,等待多线程上传结束。
	    // 创建一个线程池,固定容量,只有10个线程。
            ExecutorService es = ExecutorServices.newFixedThreadPool(10);
	    ArrayList fArray = new ArrayList();
	    for(int i = 0; i < 10; i++){
	      Socket upload = new Socket(ip, port);
	      int index = (i * point);
	      int endIndex = 0;
	      if(i != 9){
	        endIndex = (i + 1) * point;
	      }else{
	        endIndex = length;
	      }
	      Future<Object> f = 
	        es.submit(new UpdateClient(file, index, endIndex, upload));
	      fArray.add(f);
	    }
	    int flag = 10;
	    while(flag > 0){
	      for(Future f : fArray){
	        try{
		  f.get(10, TimeUnit.MILLSSECOND);
		  flag--;
		  fArray.remove(f);
		}catch(Exception e){}
	      }
	    }
	    // 所有的线程都执行结束了。文件上传结束。
	    s.close();
	  }
	}
	class UploadClient implements Callable{
	  private File file; // 要上传的文件
	  private int index; // 要读取的文件的起始下标
	  private int endIndex; // 要读取的文件的结束下标
	  private Socket socket; // 客户端对象
	  public UploadClient(File file, int index, int endIndex, Socket socket){
	    // 赋值
	  }
	  public Object call(){
	    RandomAccessFile raf = new RandomAccessFile(file);
	    raf.skipBytes(index);
	    byte[] temp = new byte[endIndex - index];
	    raf.read(temp, index, endIndex - index);
	    OutputStream output = socket.getOutputStream();
	    // 通知服务器,本次连接上传的是那一个文件,是这个文件的那一个部分。
	    output.write("{\"filename\"=\"\",\"index\"=?,\"endIndex\"=?}".getBytes());
	    // 通知服务器,描述信息结束,后续的都是文件内容。
	    output.write("\n".getBytes());
	    output.flush();
	    output.write(temp);
	    output.flush();
	    raf.close();
	    socket.close();

	    return "ok";
	  }
	}

server:

  class ServerMain{
	  public static void main(String [] args){
	    ServerSocket ss = new ServerSocket(port);
	    while(true){
	      Socket s = ss.accept();
	      new Thread(new ServerHandler(s)).start();
	    }
	  }
	}
	class ServerHandler implements Runnable{
	  private Socket s;
          public ServerHandler(Socket s){}
	  public void run(){
	    InputStream input = s.getInputStream();
	    BufferedReader reader = new BufferedReader(input);
	    String line = reader.readLine();
	    // 处理字符串line,如果是{filename:xxx}, 创建文件
	    ObjectMapper om = new ObjectMapper();
	    Map map = om.readObject(line, Map.class);
	    if(map.size() == 1){// 创建文件}
	    else{// 多线程写入操作
	      // 读取文件内容,做写入操作
              String filename = map.get("filename");
	      long index = map.get("index");
	      long endIndex = map.get("endIndex");
	      RandomAccessFile raf = new RandomAccessFile(filename, "append");
	      raf.skipBytes(index);
	      input.read();
	      raf.write();
	    }
	  }
	}

迅雷

java编写简单的Socket通信应用 实现服务端同时处理多个客户端

java socket 多线程网络传输多个文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值