是否有更清洁,更快捷的方法:
BufferedReader inputReader = new BufferedReader(new InputStreamReader(context.openFileInput("data.txt")));
String inputString;
StringBuilder stringBuffer = new StringBuilder();
while ((inputString = inputReader.readLine()) != null) {
stringBuffer.append(inputString + "\n");
}
text = stringBuffer.toString();
byte[] data = text.getBytes();
基本上我正在尝试将文件转换为byte[]
,除非文件足够大,否则会遇到outofmemory错误。我一直在寻找SO的解决方案,我试图在这里做到这一点,但它没有用。任何帮助将不胜感激。
答案 0 :(得分:6)
很少有建议:
答案 1 :(得分:3)
我们知道这个文件的大小,通过直接分配给定大小的字节数组而不是扩展它,可以节省一半的内存:
byte [] data = new byte[ (int) file.length() ];
FileInputStream fin = new FileInputStream(file);
int n = 0;
while ( (n = fin.read(data, n, data.length() - n) ) > 0);
这将避免分配不必要的额外结构。字节数组只分配一次,从头开始具有正确的大小。 while循环确保加载所有数据(read(byte[], offset, length)
可能只读取文件的一部分但返回读取的字节数。)
澄清:当StringBuilder用完时,它会分配一个比初始缓冲区大两倍的新缓冲区。此时,我们使用的内存量大约是最低要求的两倍。在最简并的情况下(最后一个字节不适合某些已经很大的缓冲区),可能需要接近最小RAM量的三倍。
答案 2 :(得分:2)
如果没有足够的内存来存储整个文件,您可以尝试重新考虑算法,以便在读取时处理文件数据,而无需构建大型byte[]
数组数据。
如果您已经尝试通过使用java
参数来增加-Xmx
内存,则没有任何解决方案,这将允许您将数据存储在内存中,因为无法将数据存储在那里它的大小。
答案 3 :(得分:0)
您正在将字节复制到char(使用两倍的空间)并再次返回字节。
InputStream in = context.openFileInput("data.txt");
ByteArrayOutputStream bais = new ByteArrayOutputStream();
byte[] bytes = new byte[8192];
for(int len; (lne = in.read(bytes) > 0;)
bais.write(bytes, 0, len);
in.close();
return bais.toByteArray();
这将是你的内存需求的一半,但它仍然意味着你的内存不足。在这种情况下,您必须
答案 4 :(得分:0)
您当前正在读取字节数,将它们转换为字符,然后尝试将它们转换回字节。来自Java API中的InputStreamReader类:
InputStreamReader是从字节流到字符流的桥接器:它读取字节并将它们解码为字符..
以字节为单位读取会更有效率。
一种方法是直接在ByteArrayInputStream
或Jakarta Commons context.openFileInput()
上使用IOUtils.toByteArray(InputStream)
,或者如果您使用的是JDK7,则可以使用Files.readAllBytes(Path)
。< / p>
答案 5 :(得分:0)
“更清洁,更快捷的方式”根本不是这样做的。它不会扩展。一次处理一个文件。
答案 6 :(得分:-1)
此解决方案将在加载前测试可用内存...
File test = new File("c:/tmp/example.txt");
long freeMemory = Runtime.getRuntime().freeMemory();
if(test.length()<freeMemory) {
byte[] bytes = new byte[(int) test.length()];
FileChannel fc = new FileInputStream(test).getChannel();
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, (int) fc.size());
while(mbb.hasRemaining()) {
mbb.get(bytes);
}
fc.close();
}