Java 程序不会传输大于 64KB 的文件
Java program won't transfer files larger than 64KB
我正在制作一个从服务器向客户端发送文件的程序。该程序本身运行,适用于 64KB 及以下的任何文件,但是当我尝试发送大于它的文件时它只传输 64KB,例如,我尝试发送一个 232KB 的文件 test.txt,程序只输出一个 64KB 的文件 receivedTest.txt.
这是服务器代码
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class FileTransferServer {
public static void main(String[] args) throws IOException {
ServerSocket servsock = new ServerSocket(1234);
File myFile = new File("C:/Users/Owner/Downloads/test.txt");
while (true) {
Socket sock = servsock.accept();
byte[] mybytearray = new byte[(int) myFile.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
bis.read(mybytearray, 0, mybytearray.length);
OutputStream os = sock.getOutputStream();
os.write(mybytearray, 0, mybytearray.length);
os.flush();
sock.close();
}
}
}
这是客户
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.Socket;
public class FileTransferClient {
public static void main(String[] argv) throws Exception {
Socket sock = new Socket("127.0.0.1", 1234);
byte[] mybytearray = new byte[409600];
InputStream is = sock.getInputStream();
FileOutputStream fos=newFileOutputStream("C:/Users/Owner/Downloads/receivedTest.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray, 0, mybytearray.length);
bos.write(mybytearray, 0, bytesRead);
bos.close();
sock.close();
}
}
任何帮助将不胜感激,无法找出发生了什么。
编辑:谢谢大家,现在可以使用了,我将客户端代码更改为:
import java.io.*;
import java.net.*;
public class FileTransferClient {
public static void main(String[] argv) throws Exception {
Socket sock = new Socket("127.0.0.1", 1234);
byte[] mybytearray = new byte[1024];
int count;
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream("C:/Users/Owner/Downloads/receivedTest.jpg");
BufferedOutputStream bos = new BufferedOutputStream(fos);
while ((count = is.read(mybytearray)) > 0)
{
bos.write(mybytearray, 0, count);
}
bos.close();
sock.close();
}
}
常见问题。
- 您假设文件适合内存。
- 您假设文件大小适合 int。
- 您假设
read()
填满了缓冲区。
在java中复制流的规范方式如下:
byte[] buffer = new byte[8192]; // any size greater than 0 will work
int count;
while ((count = in,read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
我很惊讶您从代码中获得了 64k 之多。如果没有循环,您只会得到一个套接字接收缓冲区已满,在 Windows.
上可能低至 8k
你尝试的方式会给你 OutOfMemoryError 因为你试图将整个文件读入内存直到它被发送,这是完全没有必要的。
最好的方法是读取和写入块,就像您在接收代码中所做的那样。
您不应该一次写入整个内容,尤其是不要写入套接字。您想按照
的方式做一些事情
byte[] buf = new byte[4096];
int bytesRead = 0;
while((bytesRead = is.read(buf)) > 0){
os.write(buf, 0, bytesRead);
}
这样你就可以 read/write 任何大小而不会 运行 出错,也不用担心 运行 内存不足或因尝试发送太大的错误而出错向服务器请求。
我正在制作一个从服务器向客户端发送文件的程序。该程序本身运行,适用于 64KB 及以下的任何文件,但是当我尝试发送大于它的文件时它只传输 64KB,例如,我尝试发送一个 232KB 的文件 test.txt,程序只输出一个 64KB 的文件 receivedTest.txt.
这是服务器代码
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class FileTransferServer {
public static void main(String[] args) throws IOException {
ServerSocket servsock = new ServerSocket(1234);
File myFile = new File("C:/Users/Owner/Downloads/test.txt");
while (true) {
Socket sock = servsock.accept();
byte[] mybytearray = new byte[(int) myFile.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
bis.read(mybytearray, 0, mybytearray.length);
OutputStream os = sock.getOutputStream();
os.write(mybytearray, 0, mybytearray.length);
os.flush();
sock.close();
}
}
}
这是客户
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.Socket;
public class FileTransferClient {
public static void main(String[] argv) throws Exception {
Socket sock = new Socket("127.0.0.1", 1234);
byte[] mybytearray = new byte[409600];
InputStream is = sock.getInputStream();
FileOutputStream fos=newFileOutputStream("C:/Users/Owner/Downloads/receivedTest.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray, 0, mybytearray.length);
bos.write(mybytearray, 0, bytesRead);
bos.close();
sock.close();
}
}
任何帮助将不胜感激,无法找出发生了什么。
编辑:谢谢大家,现在可以使用了,我将客户端代码更改为:
import java.io.*;
import java.net.*;
public class FileTransferClient {
public static void main(String[] argv) throws Exception {
Socket sock = new Socket("127.0.0.1", 1234);
byte[] mybytearray = new byte[1024];
int count;
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream("C:/Users/Owner/Downloads/receivedTest.jpg");
BufferedOutputStream bos = new BufferedOutputStream(fos);
while ((count = is.read(mybytearray)) > 0)
{
bos.write(mybytearray, 0, count);
}
bos.close();
sock.close();
}
}
常见问题。
- 您假设文件适合内存。
- 您假设文件大小适合 int。
- 您假设
read()
填满了缓冲区。
在java中复制流的规范方式如下:
byte[] buffer = new byte[8192]; // any size greater than 0 will work
int count;
while ((count = in,read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
我很惊讶您从代码中获得了 64k 之多。如果没有循环,您只会得到一个套接字接收缓冲区已满,在 Windows.
上可能低至 8k你尝试的方式会给你 OutOfMemoryError 因为你试图将整个文件读入内存直到它被发送,这是完全没有必要的。
最好的方法是读取和写入块,就像您在接收代码中所做的那样。
您不应该一次写入整个内容,尤其是不要写入套接字。您想按照
的方式做一些事情byte[] buf = new byte[4096];
int bytesRead = 0;
while((bytesRead = is.read(buf)) > 0){
os.write(buf, 0, bytesRead);
}
这样你就可以 read/write 任何大小而不会 运行 出错,也不用担心 运行 内存不足或因尝试发送太大的错误而出错向服务器请求。