我正在阅读XML文件并将其内容推送到ByteArrayOutputStream
,如下所示:
static final MY_XML_FILE = new File("...");
byte[] buffer = new byte[(int) MY_XML_FILE.length()];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
while ((bytesRead = fileInputStream.read(buffer)) != -1)
output.write(buffer, 0, bytesRead);
工作正常。
我不希望在bytesRead
循环之外显示while
的范围,因此我将其更改为for
循环:
for (int bytesRead = fileInputStream.read(buffer); bytesRead != -1; )
output.write(buffer, 0, bytesRead);
但是这会引发以下错误:
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at java.util.Arrays.copyOf(Arrays.java:3236)
at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:113)
at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:140)
我的问题是:两种循环方式不一样吗?如果没有,那么我想知道for
和while
循环在Java中的内存使用情况有何不同。
答案 0 :(得分:7)
在for循环中,您只需设置一次bytesRead
,而不是像while
中那样设置每次迭代。 for
- 相当于你的while循环:
for( int bytesRead; (bytesRead = fileInputStream.read(buffer)) != -1; )
或者以不同的方式:
for( int bytesRead = fileInputStream.read(buffer); bytesRead != -1; bytesRead = fileInputStream.read(buffer) )
答案 1 :(得分:2)
因为您永远不会在bytesRead
循环中更新成为无限内存请求的for
;
for (int bytesRead = fileInputStream.read(buffer); bytesRead != 1; )
output.write(buffer, 0, bytesRead);
应该是(并检查bytesRead
不是-1)
for (int bytesRead = fileInputStream.read(buffer); bytesRead != -1; ) {
output.write(buffer, 0, bytesRead);
bytesRead = fileInputStream.read(buffer);
}
我真的建议您尝试write dumb code。
答案 2 :(得分:0)
在for
循环中,您正在检查是否bytesRead != 1
;在while
循环中,您正在检查是否bytesRead != -1
。
答案 3 :(得分:0)
当你在for中将第一个读取分配给bytesRead时,你将为bytesRead放置一个起始值。永远不会再被召唤。 Ence,你一遍又一遍地写,直到你的内存不足,因为bytesRead永远不会是-1。
更准确地说,想象一下典型的:for(int i =0;i<x;i++)
。正如您从典型的int中看到的那样i = 0只被调用一次。将for读取内容并将bytesRead作为0。