使用和不使用GZip和Jar文件(内存中的GZip?)访问给定行文本文件的最快方法

时间:2012-01-18 17:00:28

标签: java gzip text-files

我已经给出了大数(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. 在我的情况下,1个大文件最好是很多小文件。

  2. 如果压缩文件,则在内存中执行解压缩过程(GZipInputStream)。是否所有文件都在内存中解压缩然后访问,或者是否可以直接在磁盘上访问它。

  3. 如果对问题2的回答为是,是否有人可以编辑我的代码以便能够执行此操作?

  4. 最重要的是:可以将zip文件加载到内存中吗?

  5. 我希望我的问题足够明确。 ; - )

    更新:感谢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);
        }
    }
    

1 个答案:

答案 0 :(得分:1)

  1. 我认为将文件加载到内存中会更快。然后,您可以压缩到所需文件的任何部分。 为此,请查看RandomAccessFile

  2. GZipInputStream将文件作为缓冲流读入内存。

  3. 完全是另一个问题:)

  4. 同样,zip文件将在内存中解压缩,具体取决于您用来打开它的类。