这与我之前的问题有关 - DataInputStream giving java.io.EOFException
在该客户端-服务器应用程序中,有一种方法可以检索从服务器发送的文件并将其保存到文件中。
Client.java -
public void receiveFile(InputStream is, String fileName) throws Exception {
int filesize = 6022386;
int bytesRead;
int current = 0;
byte[] mybytearray = new byte[filesize];
System.out.println("Receving File!");
FileOutputStream fos = new FileOutputStream("RECEIVED_"+fileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray, 0, mybytearray.length);
current = bytesRead;
System.out.println(bytesRead);
do {
bytesRead = is.read(mybytearray, current,
(mybytearray.length - current));
System.out.println(bytesRead);
if (bytesRead >= 0)
current += bytesRead;
} while (bytesRead > -1);
System.out.println("Loop done");
bos.write(mybytearray, 0, current);
bos.flush();
bos.close();
}
}
服务器.Java
public void sendFile(OutputStream os, String fileName) throws Exception {
File myFile = new File(fileName);
byte[] mybytearray = new byte[(int) myFile.length() + 1];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray, 0, mybytearray.length);
System.out.println("Sending File!");
os.write(mybytearray, 0, mybytearray.length);
os.flush();
bis.close();
}
正如您所看到的,客户端的 receiveFile
方法中有几个搁浅的地方。这是我收到的输出。
问题是该方法没有完成其任务并且从未到达System.out.println("Loop done");
有什么问题吗?
最佳答案
稍后我会讨论循环错误。
源代码中多了一个字节:
public void sendFile(OutputStream os, String fileName) throws Exception {
File myFile = new File(fileName);
if (myFile.length() > Integer.MAX_VALUE) {
throw new IllegalStateException();
}
要么
byte[] mybytearray = Files.readAllBytes(myFile.toPath());
或者
byte[] mybytearray = new byte[(int) myFile.length()]; // No +1.
// BufferedInputStream here not needed.
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(myFile))) {
bis.read(mybytearray);
} // Always closed.
然后
System.out.println("Sending File!");
os.write(mybytearray);
os.flush();
}
或者,我添加了 java 7 Files.readAllBytes
。使用 Files.copy
甚至可以更简单。
我刚刚看到主要错误已经提到了。基本上有一个误解:您可以读取整个字节数组。它将阻塞直到读到末尾。如果要读取的内容较少(到达“文件结尾”),则返回字节数。因此,无论出于什么目的,您都可以完整地阅读它。
人们经常看到类似的代码重复读取固定大小(2 的幂) block (例如 4096)并将其写入输出流。
再次java 7 Files简化一切:
Files.copy(is, Paths.get("RECEIVED_" + fileName));
<小时/>
简而言之:
public void receiveFile(InputStream is, String fileName) throws Exception {
Files.copy(is, Paths.get("RECEIVED_" + fileName),
StandardCopyOption.REPLACE_EXISTING);
}
public void sendFile(OutputStream os, String fileName) throws Exception {
Files.copy(Paths.get(fileName), os);
}
关于java - 读取输入流并写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23184166/