如何通过 byte[] 流读取多个文件的 Socket InputStream?
How to read Socket InputStream for multiple files over byte[] streams?
我在下面发布的代码适用于通过套接字传输单个文件。但它不适用于通过套接字传输多个文件。当尝试通过套接字传输多个文件时,代码崩溃。
我通过在服务器上循环发送代码 x 次和 运行 接收代码 x 次来发送多个文件。尝试发送多个文件时,第一个文件发送成功,第二个文件名和大小读取成功,但我的代码中的错误发生在这之后。
在我的接收客户端中,我尝试使用此处发布的建议:Java multiple file transfer over socket 但没有成功。
错误在客户端。
我要问的问题是:为什么这段代码不能用于多个文件,我该如何解决?
服务器发送
try{
byte[] bytes = new byte[(int)file.length()];
FileInputStream fis = new FileInputStream(file);
OutputStream os = socket.getOutputStream();
out.println(file.getName()); // Send Filename
out.println(file.length()); // Send filesize
int count;
while ((count = fis.read(bytes)) > 0) {
os.write(bytes, 0, count);
}
os.flush();
fis.close();
}catch(IOException e){
e.printStackTrace();
}
}
客户收到
try{
String file = in.readLine(); // Read filename
int fileSize = Integer.parseInt(in.readLine()); // Read Filesize
//ERROR HAPPENING ON LINE ABOVE IN LOOPS AFTER THE FIRST
byte [] buf = new byte [fileSize];
FileOutputStream fos = new FileOutputStream(file);
InputStream is = socket.getInputStream();
int count = 0;
while (fileSize > 0 && (count = is.read(buf, 0, (int)Math.min(buf.length, fileSize))) != -1){
fos.write(buf, 0, count);
fileSize -= count;
}
fos.close();
}catch(IOException e){
e.printStackTrace();
}
错误是 NumberFormatException,当客户端正在接收文件的一部分以输入 fileSize 时,在第一个循环之后。
确保在 flush
PrintWriter
之前将原始字节直接写入 PrintWriter
所附加的 OutputStream
。否则,您可能会将任何缓冲区数据乱序写入底层套接字。
但更重要的是,如果您在接收端使用缓冲读取,请确保您使用接收文件名和文件大小的相同缓冲区读取文件字节。您还应该使用较小的固定块传输 File
,不要为整个文件大小分配单个 byte[]
数组,这对于大文件来说是一种内存浪费,并且很可能会失败。
服务器:
try{
byte[] bytes = new byte[1024];
FileInputStream fis = new FileInputStream(file);
OutputStream os = socket.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
PrinterWriter pw = new PrintWriter(bos);
pw.println(file.getName()); // Send Filename
pw.println(file.length()); // Send filesize
pw.flush();
int count;
while ((count = fis.read(bytes)) > 0) {
bos.write(bytes, 0, count);
}
bos.flush();
fis.close();
}catch(IOException e){
e.printStackTrace();
}
}
客户:
try{
byte [] buf = new byte [1024];
FileOutputStream fos = new FileOutputStream(file);
InputStream is = socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
InputStreamReader isr = new InputStreamReader(bis);
String file = isr.readLine(); // Read filename
long fileSize = Long.parseLong(isr.readLine()); // Read Filesize
int count = 0;
while ((fileSize > 0) && (count = bis.read(buf, 0, (int)Math.min(buf.length, fileSize))) > 0){
fos.write(buf, 0, count);
fileSize -= count;
}
fos.close();
}catch(IOException e){
e.printStackTrace();
}
也就是说,您也可以考虑使用 DataOutputStream.writeLong()
和 DataInputStream.readLong()
来 send/receive 原始二进制格式的文件大小而不是文本字符串:
服务器:
try{
byte[] bytes = new byte[1024];
FileInputStream fis = new FileInputStream(file);
OutputStream os = socket.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
PrinterWriter pw = new PrintWriter(bos);
pw.println(file.getName()); // Send Filename
pw.flush();
DataOutputStream dos = new DataOutputStream(bos);
dos.writeLong(file.length()); // Send filesize
dos.flush();
int count;
while ((count = fis.read(bytes)) > 0) {
bos.write(bytes, 0, count);
}
bos.flush();
fis.close();
}catch(IOException e){
e.printStackTrace();
}
}
客户:
try{
byte [] buf = new byte [1024];
FileOutputStream fos = new FileOutputStream(file);
InputStream is = socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
InputStreamReader isr = new InputStreamReader(bis);
String file = isr.readLine(); // Read filename
DataInputStream dis = new DataInputStream(bos);
long fileSize = dis.readLong(); // Read Filesize
int count = 0;
while ((fileSize > 0) && (count = bis.read(buf, 0, (int)Math.min(buf.length, fileSize))) > 0){
fos.write(buf, 0, count);
fileSize -= count;
}
fos.close();
}catch(IOException e){
e.printStackTrace();
}
我在下面发布的代码适用于通过套接字传输单个文件。但它不适用于通过套接字传输多个文件。当尝试通过套接字传输多个文件时,代码崩溃。
我通过在服务器上循环发送代码 x 次和 运行 接收代码 x 次来发送多个文件。尝试发送多个文件时,第一个文件发送成功,第二个文件名和大小读取成功,但我的代码中的错误发生在这之后。
在我的接收客户端中,我尝试使用此处发布的建议:Java multiple file transfer over socket 但没有成功。
错误在客户端。
我要问的问题是:为什么这段代码不能用于多个文件,我该如何解决?
服务器发送
try{
byte[] bytes = new byte[(int)file.length()];
FileInputStream fis = new FileInputStream(file);
OutputStream os = socket.getOutputStream();
out.println(file.getName()); // Send Filename
out.println(file.length()); // Send filesize
int count;
while ((count = fis.read(bytes)) > 0) {
os.write(bytes, 0, count);
}
os.flush();
fis.close();
}catch(IOException e){
e.printStackTrace();
}
}
客户收到
try{
String file = in.readLine(); // Read filename
int fileSize = Integer.parseInt(in.readLine()); // Read Filesize
//ERROR HAPPENING ON LINE ABOVE IN LOOPS AFTER THE FIRST
byte [] buf = new byte [fileSize];
FileOutputStream fos = new FileOutputStream(file);
InputStream is = socket.getInputStream();
int count = 0;
while (fileSize > 0 && (count = is.read(buf, 0, (int)Math.min(buf.length, fileSize))) != -1){
fos.write(buf, 0, count);
fileSize -= count;
}
fos.close();
}catch(IOException e){
e.printStackTrace();
}
错误是 NumberFormatException,当客户端正在接收文件的一部分以输入 fileSize 时,在第一个循环之后。
确保在 flush
PrintWriter
之前将原始字节直接写入 PrintWriter
所附加的 OutputStream
。否则,您可能会将任何缓冲区数据乱序写入底层套接字。
但更重要的是,如果您在接收端使用缓冲读取,请确保您使用接收文件名和文件大小的相同缓冲区读取文件字节。您还应该使用较小的固定块传输 File
,不要为整个文件大小分配单个 byte[]
数组,这对于大文件来说是一种内存浪费,并且很可能会失败。
服务器:
try{
byte[] bytes = new byte[1024];
FileInputStream fis = new FileInputStream(file);
OutputStream os = socket.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
PrinterWriter pw = new PrintWriter(bos);
pw.println(file.getName()); // Send Filename
pw.println(file.length()); // Send filesize
pw.flush();
int count;
while ((count = fis.read(bytes)) > 0) {
bos.write(bytes, 0, count);
}
bos.flush();
fis.close();
}catch(IOException e){
e.printStackTrace();
}
}
客户:
try{
byte [] buf = new byte [1024];
FileOutputStream fos = new FileOutputStream(file);
InputStream is = socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
InputStreamReader isr = new InputStreamReader(bis);
String file = isr.readLine(); // Read filename
long fileSize = Long.parseLong(isr.readLine()); // Read Filesize
int count = 0;
while ((fileSize > 0) && (count = bis.read(buf, 0, (int)Math.min(buf.length, fileSize))) > 0){
fos.write(buf, 0, count);
fileSize -= count;
}
fos.close();
}catch(IOException e){
e.printStackTrace();
}
也就是说,您也可以考虑使用 DataOutputStream.writeLong()
和 DataInputStream.readLong()
来 send/receive 原始二进制格式的文件大小而不是文本字符串:
服务器:
try{
byte[] bytes = new byte[1024];
FileInputStream fis = new FileInputStream(file);
OutputStream os = socket.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
PrinterWriter pw = new PrintWriter(bos);
pw.println(file.getName()); // Send Filename
pw.flush();
DataOutputStream dos = new DataOutputStream(bos);
dos.writeLong(file.length()); // Send filesize
dos.flush();
int count;
while ((count = fis.read(bytes)) > 0) {
bos.write(bytes, 0, count);
}
bos.flush();
fis.close();
}catch(IOException e){
e.printStackTrace();
}
}
客户:
try{
byte [] buf = new byte [1024];
FileOutputStream fos = new FileOutputStream(file);
InputStream is = socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
InputStreamReader isr = new InputStreamReader(bis);
String file = isr.readLine(); // Read filename
DataInputStream dis = new DataInputStream(bos);
long fileSize = dis.readLong(); // Read Filesize
int count = 0;
while ((fileSize > 0) && (count = bis.read(buf, 0, (int)Math.min(buf.length, fileSize))) > 0){
fos.write(buf, 0, count);
fileSize -= count;
}
fos.close();
}catch(IOException e){
e.printStackTrace();
}