首页 文章

Java通过套接字传输多个文件

提问于
浏览
21

好的,尝试通过套接字传输指定的文件目录,从arraylist中删除目录对象,因此只剩下文件,并在同一个套接字上逐个传输它们 . 这里的arraylist充满了ONLY文件,没有目录 . 继承人分别为客户端和服务器接收和发送代码 . 除了将所有数据写入第一个文件之外,代码运行正常且没有错误 . 后续文件在服务器文件夹中创建,但它们是0字节 . 任何投入将不胜感激 .

这是收到文件的服务器代码

public void receive(){


    try {
        DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
//read the number of files from the client
        int number = dis.readInt();
        ArrayList<File>files = new ArrayList<File>(number);
        System.out.println("Number of Files to be received: " +number);
        //read file names, add files to arraylist
        for(int i = 0; i< number;i++){
            File file = new File(dis.readUTF());
            files.add(file);
        }
        int n = 0;
        byte[]buf = new byte[4092];

        //outer loop, executes one for each file
        for(int i = 0; i < files.size();i++){

            System.out.println("Receiving file: " + files.get(i).getName());
            //create a new fileoutputstream for each new file
            FileOutputStream fos = new FileOutputStream("C:\\users\\tom5\\desktop\\salestools\\" +files.get(i).getName());
            //read file
            while((n = dis.read(buf)) != -1){
                fos.write(buf,0,n);
                fos.flush();
            }
            fos.close();
        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();

    }


}

这是发送文件的客户端代码

public void send(ArrayList<File>files){

    try {
        DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
        System.out.println(files.size());
//write the number of files to the server
        dos.writeInt(files.size());
        dos.flush();

        //write file names 
        for(int i = 0 ; i < files.size();i++){
            dos.writeUTF(files.get(i).getName());
            dos.flush();
        }

        //buffer for file writing, to declare inside or outside loop?
        int n = 0;
        byte[]buf = new byte[4092];
        //outer loop, executes one for each file
        for(int i =0; i < files.size(); i++){

            System.out.println(files.get(i).getName());
            //create new fileinputstream for each file
            FileInputStream fis = new FileInputStream(files.get(i));

            //write file to dos
            while((n =fis.read(buf)) != -1){
                dos.write(buf,0,n);
                dos.flush();

            }
            //should i close the dataoutputstream here and make a new one each time?
        }
        //or is this good?
        dos.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

2 回答

  • 23

    您正在读取套接字,直到 read() 返回-1 . 这是流结束条件(EOS) . 当对等方关闭连接时,会发生EOS . 不是在完成一个文件的写入时 .

    您需要在每个文件之前发送文件大小 . 你已经在使用文件计数做了类似的事情 . 然后确保您准确读取该文件的那么多字节:

    String filename = dis.readUTF();
    long fileSize = dis.readLong();
    FileOutputStream fos = new FileOutputStream(filename);
    while (fileSize > 0 && (n = dis.read(buf, 0, (int)Math.min(buf.length, fileSize))) != -1)
    {
      fos.write(buf,0,n);
      fileSize -= n;
    }
    fos.close();
    

    您可以将所有这些包含在一个循环中,该循环在 readUTF() 抛出 EOFException 时终止 . 当然,在发送数据之前,您必须在发件人处调用 writeUTF(filename)writeLong(filesize) .

  • 1

    我是这样做的,它工作得很好,你可以看看:

    send

    byte[] done = new byte[3];
    String str = "done";  //randomly anything
    done = str.getBytes();
    for(int i =0; i < files.size(); i++){
        System.out.println(files.get(i).getName());
        FileInputStream fis = new FileInputStream(files.get(i));
        while((n =fis.read(buf)) != -1){
            dos.write(buf,0,n);
            System.out.println(n);
            dos.flush();
        }
     //should i close the dataoutputstream here and make a new one each time?                 
        dos.write(done,0,3);
        dos.flush();
    }
            //or is this good?
            dos.close();
    

    recieve

    for(int i = 0; i < files.size();i++){
        System.out.println("Receiving file: " + files.get(i).getName());
     //create a new fileoutputstream for each new file
    fos = new FileOutputStream("C:\\users\\tom5\\desktop\\salestools\\" +files.get(i).getName());
    //read file
    while((n = dis.read(buf)) != -1 && n!=3 ){
            fos.write(buf,0,n);
            fos.flush();
            }
                fos.close();
            }
    

相关问题