English 中文(简体)
从Jar中更有效地提取文件
原标题:
  • 时间:2009-02-12 16:24:28
  •  标签:

我正在扩展一个实用类,它打包了一组图片和 .xml 描述文件。目前我将所有文件放在一个目录中,并从那里加载它们。该目录看起来像这样:

8.png
8.xml
9.png
9.xml
10.png
10.xml
...
...
50.png
50.xml
...

Translate what into Chinese? Please provide the text you want me to translate.Translate what into Chinese? Please provide the text you want me to translate. Here s my current constructor. It is lightning fast and does what I need it to do. (I ve stripped out some of the error checking to make it easier to read): Translate what into Chinese? Please provide the text you want me to translate.Translate what into Chinese? Please provide the text you want me to translate.

public DivineFont(String directory ) {

    File dir = new File(directory);

    //children is an array that looks like this:  10.fnt ,  11.fnt , etc.
    String[] children = dir.list(fntFileFilter);

    fonts = new Hashtable<Integer, AngelCodeFont>(100);

    AngelCodeFont buffer;
    int number;
            String fntFile;
            String imgFile;

    for(int k = 0; k < children.length; k++ ) {
        number = Integer.parseInt( children[k].split("\.")[0] );
        fntFile = directory + File.separator + number + ".xml";
        imgFile = directory + File.separator + number + ".png";
        buffer = new AngelCodeFont(fntFile, imgFile);

        fonts.put(number, buffer);
    }
}

为了网站的开始和整洁,我一直在尝试从Jar中加载这些资源。我已经让它运行起来了,但加载时间从即时变成了几秒钟,这是不可接受的。这是我尝试过的代码(再次说明,已去除错误检查):

这不是我想要做的最好的方法,而是一个模拟来看看这个想法是否可行。它没有成功。这两个for循环绝不是问题的根源;而是创建所有这些InputStream的过程使其变慢。

public DivineFont(String jarFileName ) {

    JarFile jarfile = new JarFile(jarFileName);
    Enumeration<JarEntry> em = jarfile.entries();
    ArrayList<Integer> fontHeights = new ArrayList<Integer>(100);
    for (Enumeration em1 = jarfile.entries(); em1.hasMoreElements(); ) {
        String fileName = em1.nextElement().toString();
        if( fileName.endsWith(".fnt") ) {
            fontHeights.add( Integer.parseInt(fileName.split("\.")[0] ) );
        }
    }

    fonts = new Hashtable<Integer, AngelCodeFont>(100);

    AngelCodeFont buffer;
    int number;

    for(int k = 0; k < fontHeights.size(); k++ ) {
        number = fontHeights.get(k);
        InputStream fntFileStream = jarfile.getInputStream(jarfile.getEntry(number + ".xml"));
        InputStream pngFileStream = jarfile.getInputStream(jarfile.getEntry(number + ".png"));
        buffer = new AngelCodeFont(String.valueOf(number), fntFileStream, pngFileStream );

        fonts.put(number, buffer);


    }
}

Translate what into Chinese? Please provide the text you want me to translate.

有人知道除了我在这里尝试的方式还有更好的处理.jar文件的方法吗?这是AngelCodeFont API。如果绝对必要,我可以提交一个补丁,但我不想这样做。我觉得可能有一种方法可以做我想做的事情,只是我不太熟悉。

我并不十分反对将jar文件快速转储到临时目录,然后从那里读取文件,但如果有一种方法可以直接从jar文件快速读取,我更愿意这样做。

此外:压缩根本不是问题。我使用罐子的唯一原因是为了包装问题。

最佳回答

好的,我找到答案了。我的原始问题的答案是“问题错误”。Jar文件不是问题,在使用的库中加载图像才是问题。

当我从文件系统加载时,该图像被命名为"38.png"等。当我从Jar加载时,我只是命名它为"38"。

图像加载器类库内部使用文件名的文件扩展名来识别使用哪个图像加载器。如果没有文件扩展名,则使用较慢的基本图像加载器。当我更改了这一行:

buffer = new AngelCodeFont(String.valueOf(number), fntFileStream, pngFileStream );

Sorry, could you please provide the whole sentence or context for me to give an accurate translation?

buffer = new AngelCodeFont( number + ".png", fntFileStream, pngFileStream );

我们有了胜利者。

无论如何,谢谢大家的帮助。我花了几个小时才弄明白这个问题,但如果没有你们的帖子,我可能会继续认为是Java的问题,而不是我正在使用的库的问题。

问题回答

打开一个JAR文件是一个非常昂贵的操作。因此,您可能希望仅打开一次JAR文件,并将JarFile实例保存在某个静态字段中。在您的情况下,您还希望读取所有条目并将它们保存在哈希映射中,以便立即访问所需的资源。

另一个解决方案是将JAR放在类路径上并使用。

DivineFont.class.getContextClassLoader().getResource*("/8.png");

注意 "/"! 如果您省略它,Java将在找到DivineFont.class文件的相同目录(包)中进行搜索。

在Java中,从类路径获取东西已经被优化到极致了。

JAR文件操纵可能非常昂贵,而java类库已经实现了这种资源加载(可能尽可能高效)的类型。

此外,一旦您进入WebStart,您的jar文件名称将被混淆,因此您可能最终不得不浏览类路径上的每个jar文件以加载资源(我已经做到了!丑陋!)

相反,使用Class.getResourceAsStream(String resourceName)。我没有对其进行分析,但我没有注意到它比直接文件访问慢。

这个库可能不能压缩你需要的那么多,但它会更快...





相关问题
热门标签