TCP中的Java文件传输中的OutOfMemoryError

时间:2014-04-25 14:05:42

标签: java tcp out-of-memory file-transfer lan

我在java中设计了一个文件发送程序和一个文件接收程序,以了解通过LAN传输的TCP文件。 我的文件发送代码如下所示......

import java.io.*;
import java.net.*;
class filesender {
public static void main(String args[]) throws Exception
{
InputStreamReader istream = new InputStreamReader(System.in);
BufferedReader bufRead = new BufferedReader(istream);
try
{
System.out.println("Receiver's I.P:");
String serverName = bufRead.readLine();
System.out.println("File Name:");
String filename = bufRead.readLine();
Socket Socket1 = new Socket(serverName, 6789);
DataOutputStream outToServer=new DataOutputStream(Socket1.getOutputStream());
BufferedReader go=new BufferedReader(new InputStreamReader(Socket1.getInputStream()));
File file = new File(filename);
FileInputStream fin = new FileInputStream(file);
byte sendData[] = new byte[(int)file.length()];
fin.read(sendData);
outToServer.writeBytes(filename);
outToServer.writeInt(sendData.length);
outToServer.write(sendData, 0, sendData.length);
String deliveryreport = go.readLine();
System.out.println(deliveryreport);  /*Delivery report arrived from Receiver*/
Socket1.close();
}
catch (IOException err)
{ System.out.println("SENDER Error..!"); }}}

嗯......我的文件接收器编码如下......

import java.io.*;
import java.net.*;
class filereceiver {
public static void main(String args[]) throws Exception
{
try
{
String filename;
ServerSocket serverSocket = new ServerSocket(6789);
System.out.println("Waiting on Port 6789...");
Socket conSocket = serverSocket.accept();
DataInputStream dis = new DataInputStream(conSocket.getInputStream());
BufferedReader hi = new BufferedReader(new InputStreamReader(conSocket.getInputStream()));
DataOutputStream outToSender = new DataOutputStream(conSocket.getOutputStream());
int dataLength = dis.readInt();
byte[] receivedData = new byte[dataLength];
for(int i = 0; i < receivedData.length; i++)
receivedData[i] = dis.readByte();
filename = hi.readLine();
FileOutputStream fos = new FileOutputStream(filename);
fos.write(receivedData);
fos.close();
outToSender.writeBytes("File has been Sent..!");/*Delivery report to sender*/
System.out.println("File has been received..!"); /*Viewed on Receiver*/
serverSocket.close();
conSocket.close();
}
catch (IOException err)
{ System.out.println("RECEIVER Error..!"); }}}

O.K,这些文件编译正确执行,但是当我尝试传输文件时,两个程序都会出现如下错误。

发送者程序给出IOException错误/////////////“SENDER Error”////////////

接收方计划说 //////////“线程中的异常”main“java.lang.OutOfMemoryError:filereceiver.main上的Java堆空间(filereceiver.java:17)//////////// < / p>

为什么会出现这些错误..?任何人都可以解释..?在此先感谢..!

2 个答案:

答案 0 :(得分:2)

这一行是因为你试图将整个流分配到RAM中。

byte[] receivedData = new byte[dataLength];

当您的信息流很小时,就可以了。但对于大流,请分配一个小缓冲区(例如10K)并以块的形式读取它。

@nos还评论了服务器首先写入文件名,然后是文件长度。您必须按写入数据的顺序读取它。但即使你读了正确的数据,你最终也会遇到我描述的问题。你肯定需要以块的形式读取数据并随时处理它。

此外,由于您要将文件名发送给接收方,因此最好定义正确的结构/标头/协议,以便接收方可以轻松处理传入的数据。这是一个建议。

  1. 1个字节表示文件名长度
  2. 以下字节是实际文件名
  3. 8个字节表示文件内容的长度。
  4. 以下字节是文件的内容。
  5. 在接收端,您读取第一个字节以了解要为文件名读取的字节数。然后,您读取8个字节以了解要读取内容的字节数。

答案 1 :(得分:-3)

尝试使用下面的JVM参数增加接收方的堆内存,

-Xms512m -Xmx1g  -XX:PermSize=512m  -XX:MaxPermSize=1g