我已经给出了大数(5-7)的大型UTF8文本文件(7 MB)。在unicode中,每个大小约为15MB。
我需要加载给定文件的给定部分。这些文件是已知的,不会更改。我想尽可能快地访问和加载行。我加载这些行添加HTML标记并在JEditorPane中显示它们。我知道瓶颈将是JEditorPane对HTML生成的渲染,但是现在我想专注于文件访问性能。
此外,用户可以搜索所有文件中的给定单词。
现在我使用的代码是:
private static void loadFile(String filename, int startLine, int stopLine) {
try {
FileInputStream fis = new FileInputStream(filename);
InputStreamReader isr = new InputStreamReader(fis, "UTF8");
BufferedReader reader = new BufferedReader(isr);
for (int j = startLine; j <= stopLine; j++) {
//here I add HTML tags
//or do string comparison in case of search by the user
sb.append(reader.readLine());
}
reader.close();
} catch (FileNotFoundException e) {
System.out.println(e);
} catch (IOException e) {
System.out.println(e);
}
}
现在我的问题:
由于已知每个文件的部分数量,在我的情况下为67(对于每个文件),我可以创建67个较小的文件。加载给定部分会“更快”但是当我进行搜索时会更慢,因为我必须打开每个67文件。
我还没有做过替补标记,但我的感觉是,在搜索的情况下打开67个文件比在加载文件的一部分时执行空的reader.readlines的时间要长得多。
所以在我的情况下,最好有一个更大的文件。你同意吗?
如果我把每个大文件都放在资源中,我的意思是在Jar文件中,性能会更差,如果是的话会更糟吗?
相关的问题是,如果我将每个文件压缩为备用大小。据我所知,Jar文件只是一个zip文件。
我想我不知道拉链是如何起作用的。如果我压缩文件,文件将在内存中解压缩,或者我的程序是否能够直接访问磁盘上我需要的给定行。 对于Jar文件,它将在内存中解压缩。
如果解压缩不在内存中,有人可以编辑我的代码以使用zip文件。
最后的问题,对我来说最重要。如果所有内容都在内存中执行,我可以提高所有性能,但由于unicode和相当大的文件,这很容易导致超过100MB的内存堆。是否有可能将zip文件加载到内存中并对其进行处理。这会很快,只使用很少的内存。
问题摘要
在我的情况下,1个大文件最好是很多小文件。
如果压缩文件,则在内存中执行解压缩过程(GZipInputStream)。是否所有文件都在内存中解压缩然后访问,或者是否可以直接在磁盘上访问它。
如果对问题2的回答为是,是否有人可以编辑我的代码以便能够执行此操作?
最重要的是:可以将zip文件加载到内存中吗?
我希望我的问题足够明确。 ; - )
更新:感谢Mike提供的getResourceAsStream提示,让它运转起来
请注意,基准测试为Gzip文件的加载提供了高效率,但实际上速度太慢。
gzip文件~200 ms 标准文件大约125毫秒,因此快1.6倍。
假设资源文件夹名为resources
private static void loadFile(String filename, int startLine, int stopLine) {
try {
GZIPInputStream zip = new GZIPInputStream(this.class.getResourceAsStream("resources/"+filename));
InputStreamReader isr = new InputStreamReader(zip, "UTF8");
BufferedReader reader = new BufferedReader(isr);
for (int j = startLine; j <= stopLine; j++) {
//here I add HTML tags
//or do string comparison in case of search by the user
sb.append(reader.readLine());
}
reader.close();
} catch (FileNotFoundException e) {
System.out.println(e);
} catch (IOException e) {
System.out.println(e);
}
}
答案 0 :(得分:1)
我认为将文件加载到内存中会更快。然后,您可以压缩到所需文件的任何部分。
为此,请查看RandomAccessFile
。
GZipInputStream将文件作为缓冲流读入内存。
完全是另一个问题:)
同样,zip文件将在内存中解压缩,具体取决于您用来打开它的类。