Java 在使用套接字通过本地网络传输文件时,如何防止文件损坏?

Java 在使用套接字通过本地网络传输文件时,如何防止文件损坏?,java,file,sockets,tcp,file-handling,Java,File,Sockets,Tcp,File Handling,我正在做一个学校项目,我想做一个个人存储服务器。目前,我试图实现的是能够将文件从客户机传输到服务器。但是,当使用图像测试时,文件会在损坏之前部分发送。 请记住,我是一个相当新的程序员,我的技术知识可能是有限的 我通过DataOutputStream使用字节数组来传输文件。我想使用这个方法,因为它应该适用于任何文件类型。我曾尝试将缓冲区大小设置为文件的确切大小或更大,但两者都不起作用 服务器: public void run() { try {

我正在做一个学校项目,我想做一个个人存储服务器。目前,我试图实现的是能够将文件从客户机传输到服务器。但是,当使用图像测试时,文件会在损坏之前部分发送。 请记住,我是一个相当新的程序员,我的技术知识可能是有限的

我通过DataOutputStream使用字节数组来传输文件。我想使用这个方法,因为它应该适用于任何文件类型。我曾尝试将缓冲区大小设置为文件的确切大小或更大,但两者都不起作用

服务器:

public void run() {
            try {
                System.out.println("ip: " + clientSocket.getInetAddress().getHostAddress());

                out = new DataOutputStream(clientSocket.getOutputStream());
                in = new DataInputStream(clientSocket.getInputStream());

                in.read(buffer, 0, buffer.length);

                fileOut = new FileOutputStream("X:\\My Documents\\My 
                Pictures\\gradient.jpg");

                fileOut.write(buffer, 0, buffer.length);
                in.close();
                out.close();
                clientSocket.close();

         } catch (IOException ex) {
                System.out.println(ex.getMessage());
            }
        }
客户:

 public void startConnection(String ip, int port) {
        try {
            clientSocket = new Socket(ip, port);
            out = new DataOutputStream(clientSocket.getOutputStream());
            in = new DataInputStream(clientSocket.getInputStream());

            x = false;
            Path filePath = Paths.get("C:\\Users\\georg\\Documents\\gradient.jpg");
            buffer = Files.readAllBytes(filePath);
            Thread.sleep(3000);
            //Files.write(filePath, buffer);
            //out.write(buffer,0,buffer.length);
            x = true;
            sendMessage(buffer);


        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        } catch (InterruptedException ex) {
            Logger.getLogger(PCS_Client.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public byte[] sendMessage(byte[] buffer) {
        if (x==true){
        try {
            out.write(buffer,0,buffer.length);

        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }

    }
        return null;
    }
以下是我尝试发送的文件与收到的文件的比较:


奇怪的是,发送单色图像会在服务器上生成单色图像。我相信这里的问题可能是代码执行的时间,但是我不确定,也不知道如何解决它。

问题在于您的服务器代码,在这一行:

in.read(buffer, 0, buffer.length);
您希望一次读取所有数据,但如果您读取文档,您会发现:

公共最终整型读取(字节[]b, int off, 内特兰) 抛出IOException

从包含的输入流读取多达len字节的数据到 字节数组。尝试读取多达len字节,但 可以读取较小的数字,可能为零。字节数 实际读取以整数形式返回

重要的部分是读取多达len字节的数据


必须使用read的返回值并反复调用它read,直到不再需要读取为止。

使用正确的复制代码:
while((count=in.read(buffer))>0){out.write(buffer,0,count);}
。目前,您假设
read()
填充了缓冲区,而缓冲区不在合同中,并且忽略返回的实际计数,错误地、不必要地假设您可以在一次读写中完成所有操作。不要把睡眠放在网络代码中:它们实际上只是浪费时间。