我在写一个客户端服务器程序。客户端在同一WLAN上的另一台计算机上。我面临的问题是客户端的这个例外:java.lang.OutOfMemoryError: Java heap space。
问题是,如果我也使用服务器计算机作为客户端(服务器-客户端在同一台计算机上),它不会抛出此异常。但是,每次我从另一台计算机运行客户机来下载文档时,它都会抛出异常。
请用一个简单的方法来解决这个问题。我用Eclipse。
下面是我的客户类:
public void run() {
try {
servsock = new ServerSocket(13330);
while (true) {
System.out.println("Waiting on question server...");
try {
sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
// receive file
byte [] mybytearray = new byte [FILE_SIZE];
InputStream is = sock.getInputStream();
String LocalLocation = "C:\\NewEvalve\\LocalUploadedFiles\\"+clasx+"\\"+subject+"\\"+filename;
File LocalFile = new File(LocalLocation);
File file = new File("C:\\NewEvalve\\LocalUploadedFiles\\"+clasx+"\\"+subject);
if (!file.exists()) {
new File("C:\\NewEvalve\\LocalUploadedFiles\\"+clasx+"\\"+subject).mkdirs();
System.out.println(file+ " now exists.");
}
File outputfile = new File("C:\\NewEvalve\\LocalUploadedFiles\\"+clasx+"\\"+subject+"\\"+filename);
fos = new FileOutputStream(outputfile);
bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray, 0 , current);
bos.flush();
System.out.println("File " + FILE_TO_RECEIVED
+ " downloaded (" + current + " bytes read)");
}
finally {
if (fos != null) fos.close();
if (bos != null) bos.close();
if (sock != null) sock.close();
} }
} catch (IOException e) {
e.printStackTrace();
}.下面是上传文件的服务器类:
public void uploadIt(InetAddress retur2, String fileLocation2){
try{
File myFile = new File (fileLocation2);
sock = new Socket(retur2, 13330);
System.out.println("Connection on "+sock.getRemoteSocketAddress());
os = sock.getOutputStream();
byte [] mybytearray = new byte [(int)myFile.length()];
fis = new FileInputStream(myFile);
bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
os.write(mybytearray,0,mybytearray.length);
fis.close();
bis.close();
os.flush();
os.close();
System.out.println("Sent " + fileLocation2 + "(" + mybytearray.length + " bytes)");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
if (bis != null)bis.close();
if (os != null) os.close();
if (sock!=null) sock.close();
System.out.println("Completed Upload");
} catch (IOException e) {
e.printStackTrace();
}}
}发布于 2014-10-10 12:51:59
如果您正在读取文本文件,则应该使用BufferedReader & BufferedWriter,而不是一次读取整个文件,如下所示
File file = new File("your file");
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
BufferedReader br = new BufferedReader(new FileReader("your file"));
while ((currentLine = br.readLine()) != null) {
bw.write(currentLine);
}
bw.close();
br.close();如果您正在读取二进制文件,则建议使用BufferedInputStream & BufferedOutputStream。无法使用BufferedReader读取二进制数据,因为它将二进制数据转换为字符串格式&您的文件将损坏或损坏.。
可能您的文件中没有行终止符。在这种情况下,读取器继续读取文件,直到堆内存中有空间为止。这就是为什么您会得到OutOfMemory错误。
编辑:
要在音频文件上执行读/写操作,可以在Java标准版-声音中提供一个扩展。您可以在javax.sound.sampled.*包中使用类。
音频文件示例:
File fileIn = new File("your file");
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(fileIn);
// do something
File fileOut = new File("new file");
if (AudioSystem.isFileTypeSupported(AudioFileFormat.Type.WAVE, audioInputStream)) {
AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, fileOut);
}要获得有关声音包的详细信息,请参阅此Java声音API
要使用视频文件格式,可以如下所示:
在Java getResourceAsStream("your video file")中有一个返回InputStream对象的方法。这个流可以用来读取视频文件数据&将它写入另一个文件或您想做的任何事情。
InputStream getResourceAsStream(字符串名)- Java一些示例代码如下所示:-
try {
InputStream in = this.getClass().getResourceAsStream("your video file");
BufferedInputStream bis = new BufferedInputStream(in);
BufferedOutputStream bus = new BufferedOutputStream(new FileOutputStream(
new File("your new video file")));
byte[] data = new byte[in.available()];
int read = in.read(data);
bus.write(read);
} catch (IOException ex) {
}发布于 2014-10-10 12:13:07
实际上,您只需调整VM将要使用的最大内存量。只需使用-Xmx<size>参数来调整。例如,-Xmx512m将最多使用512 MB的内存。
我还注意到,您正在将一个文件作为一个大块读入内存。我会一片一片地做(就像1或2kb的片段),以防止巨大的即时内存需求。
发布于 2014-10-10 12:38:11
HotSpot根据机器上的总物理内存来调整堆的大小。更改主机时,可以隐式更改堆限制。似乎,在您的远程计算机上,您有较少的RAM,因此您达到了极限。
但是,真正的建议是不要将整个文件加载到内存中,而是以块的形式读取文件,并将它们直接写入网络套接字。那么无论文件大小如何,您都不会面临这个问题。同样的推理也适用于服务器端:不要将整个文件从套接字读取到RAM中,而是直接将其转储到文件中。
https://stackoverflow.com/questions/26299026
复制相似问题