Java 在使用套接字通过本地网络传输文件时,如何防止文件损坏?
我正在做一个学校项目,我想做一个个人存储服务器。目前,我试图实现的是能够将文件从客户机传输到服务器。但是,当使用图像测试时,文件会在损坏之前部分发送。 请记住,我是一个相当新的程序员,我的技术知识可能是有限的 我通过DataOutputStream使用字节数组来传输文件。我想使用这个方法,因为它应该适用于任何文件类型。我曾尝试将缓冲区大小设置为文件的确切大小或更大,但两者都不起作用 服务器:Java 在使用套接字通过本地网络传输文件时,如何防止文件损坏?,java,file,sockets,tcp,file-handling,Java,File,Sockets,Tcp,File Handling,我正在做一个学校项目,我想做一个个人存储服务器。目前,我试图实现的是能够将文件从客户机传输到服务器。但是,当使用图像测试时,文件会在损坏之前部分发送。 请记住,我是一个相当新的程序员,我的技术知识可能是有限的 我通过DataOutputStream使用字节数组来传输文件。我想使用这个方法,因为它应该适用于任何文件类型。我曾尝试将缓冲区大小设置为文件的确切大小或更大,但两者都不起作用 服务器: public void run() { try {
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()
填充了缓冲区,而缓冲区不在合同中,并且忽略返回的实际计数,错误地、不必要地假设您可以在一次读写中完成所有操作。不要把睡眠放在网络代码中:它们实际上只是浪费时间。