Ric*_*ase 3 java sockets file-io
我有一个文件发送者和接收者。在互联网上找到的10多个帖子中,这是通过Java中的套接字发送文件的正确方法。看看下面的代码片段。
发件人:
OutputStream bos = clientSocket.getOutputStream();
FileInputStream fis = new FileInputStream(sendingFile);
BufferedInputStream bis = new BufferedInputStream(fis);
int n;
int total = 0;
byte[] buffer = new byte[8192];
while ((n = bis.read(buffer)) > 0) {
bos.write(buffer, 0, n);
System.out.println("Sending File... ");
total += n;
System.out.println(total);
}
Run Code Online (Sandbox Code Playgroud)
接收方:
InputStream bis = clientSocket.getInputStream();
FileOutputStream fos = new FileOutputStream(fileOut);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int n;
int total = 0;
byte[] buffer = new byte[8192];
while ((n = bis.read(buffer)) > -1) {
bos.write(buffer, 0, buffer.length);
System.out.println("Writing File... ");
total += n;
System.out.println(total);
if (total == fileSize) {
break;
}
}
System.out.println("File Received");
Run Code Online (Sandbox Code Playgroud)
这是发件人的输出
正在发送文件:D:\ Users \ Administrator \ Documents \ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.avi
文件大小:54236160
正在发送文件...
8192
正在发送文件...
16384
................... 。一些时间后,
发送文件...
54231040
发送文件...
54236160
文件发送
最后一个数字54236160是发送文件的确切大小。现在,这是接收器端的最后一行。
正在写入档案...
54234710
因此,对于此特定文件,它始终以该大小停止,因此,由于未发送整个文件,因此接收方永远不会停止等待数据。我不了解发送方如何发送正确数量的数据,但是接收方却无法获得全部信息。我从没有在接收方看到“文件已接收”,并且接收方读取的数据量从不等于发送的量。
我发送的任何文件都会出现此问题,如果我发送的文件非常小,例如字节而不是kb的文件,则接收方完全看不到任何“ Writing File ...”,几乎就像它只是忽略了流。
但是互联网上的每个帖子都说这是发送文件的正确方法。哦,如果我关闭了发送套接字和/或流,由于客户端和服务器还有其他需要做的事情,我不想这样做,那么无论如何它还是不能解决问题。
我注意到的另一件事是,尽管发件人总是似乎指示其将全部金额写入缓冲区(始终为8192的倍数作为“总数”),但接收方却没有。
以下是获取文件大小和文件名的代码。也许这就是错误所在?在开始发送和接收文件之前,我不知道如何完成所有操作。
System.out.println("Receiving File");
try {
clientScanner.nextLine();
String fileName = clientScanner.nextLine();
int fileSize = clientScanner.nextInt();
System.out.println("File: " + fileName + " Size: " + fileSize);
File fileOut = new File("C:\\Users\\owner\\AppData\\Local\\temp\\" + fileName);
InputStream bis = clientSocket.getInputStream();
FileOutputStream fos = new FileOutputStream(fileOut);
BufferedOutputStream bos = new BufferedOutputStream(fos);
Run Code Online (Sandbox Code Playgroud)
您不应尝试读取比预期更多的数据。您的循环应为:
int n;
int bytesLeft = fileSize;
byte[] buffer = new byte[8192];
while (bytesLeft > 0) {
int n = bis.read(buffer, 0, Math.min(buffer.length, bytesLeft));
if (n < 0) {
throw new EOFException("Expected " + bytesLeft + " more bytes to read");
}
bos.write(buffer, 0, n);
System.out.println("Writing File... ");
bytesLeft -= n;
System.out.println(total " bytes left to read");
}
Run Code Online (Sandbox Code Playgroud)
(您可以调整输出以显示已读取的字节数,而不是需要读取的字节数,但我认为这种方法更简单。)
如果仍然不能获取全部数据,则应该在编写代码中刷新输出流-我不希望您必须这样做,但是如果您不关闭套接字,我想它可能正在缓冲它永远。
如果循环终止但文件似乎不完整,请确保bos在所有这些操作之后要关闭。
如果没有那个帮助,那么就可能是别的东西已经阅读您的数据的开始,你进入这个循环之前。您应该将输出文件中的数据与原始文件进行比较。查看输出文件中的前16个字节(例如),并检查它们是否在输入文件的开头。如果不是,则表明问题出在您向我们展示代码之前,您正在处理连接问题。(例如,用于发送和接收预期文件大小的代码。)
现在我们可以看到您如何发送/接收文件大小,这绝对是问题所在。扫描程序正在读取某些文件数据。要解决此问题,只需DataOutputStream在发送方和DataInputStream接收方使用:
DataOutputStream output = new DataOutputStream(clientSocket.getOutputStream());
output.writeUTF(fileName);
output.writeInt(fileSize);
// Write the data as before, to output
Run Code Online (Sandbox Code Playgroud)
在接收方:
DataInputStream input = new DataOutputStream(clientSocket.getInputStream());
String fileName = input.readUTF(name);
int fileSize = input.readInt();
// Read the data before, as above, from input
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1386 次 |
| 最近记录: |