LibGDX导出的桌面应用程序中的内部文件列表

时间:2014-02-16 20:30:35

标签: java libgdx file-handling

LibGDX的文件系统存在很大问题。我需要一个jar文件中文件夹中所有文件的列表。我尝试了不同的东西,但最好的工作代码是:

FileHandle dirHandle;
    if (Gdx.app.getType() == ApplicationType.Android) {
       dirHandle = Gdx.files.internal("levels");
    } else {
      // ApplicationType.Desktop ..
      dirHandle = Gdx.files.internal("./bin/levels");
    }
    for (FileHandle entry: dirHandle.list()) {
        Gdx.app.log("FILE", entry.name() + "  " + entry.path());
        //DO some other stuff...
    }

问题是,如果我导出它,这段代码根本不起作用。

通常我可以获取内部文件路径,但导出的jar只会崩溃。

它会抛出NullPointerException,因为其中没有文件。

我检查了路径,它是C:/Users/user/./bin/levels

逻辑,但对我不好。

如何从导出的jar中获取内部文件列表?

我只需要文件的名称,例如在我的情况下mission1.xmlwhatever.trash

我没有想法,也许我犯了或犯了大错,所以如果可以,请帮助我。

3 个答案:

答案 0 :(得分:2)

当该目录由类路径上的JAR文件支持时,Java不提供列出“目录”中“文件”的便捷方法(有关解决方法,请参阅How do I list the files inside a JAR file?)。我相信这是因为多个.jar文件和类路径目录中存在“目录”的一般情况非常复杂(系统必须在多个源中提供条目联合并处理重叠)。

因为Java / Android没有干净的支持,所以Libgdx(搜索类路径都是“内部”Libgdx文件映射到的)。

我认为最简单的解决方法是在文本文件中构建一个级别列表,然后将其打开并将其用作文件名列表。所以,像:

// XXX More pseudo code in Java than actual code ... (this is untested)
fileList = Gdx.files.internal("levels.txt");
String files[] = fileList.readString().split("\\n");
for (String filename: files) {
   FileHandle fh = Gdx.files.internal("levels/" + filename);
   ...
}

理想情况下,您可以在构建JAR文件时设置构建此文本文件的内容。 (这是一个单独的SO问题,我不知道答案......)

顺便说一下,使用ApplicationType.Desktop的解决方法是利用除了.jar文件之外,类路径上还有一个可以打开的真实目录。 Android设备上不存在该目录(在构建环境下运行时,它实际上只存在于桌面上)。

答案 1 :(得分:0)

如果您仍在寻找实际的答案,这里是mine(虽然有点古怪,但确实可行)。

要使用它,您只需调用以下2个选项之一:

FileHandle[] fileList = JarUtils.listFromJarIfNecessary("Path/to/your/folder");
FileHandle[] fileList = JarUtils.listFromJarIfNecessary(yourJarFileFilter);

JarFileFilter是一个简单的类,可重载Java默认FileFilter以适合jar过滤器的需求。

这将同时起作用:从IDE和jar文件中运行时。它还会检查游戏是否在桌面上运行,否则它将使用默认的libGDX方式加载资源,因此可以安全地用于跨平台项目(Android,Ios等)。
如果需要,可以随时更新代码。该代码已记录在案,大约150行,因此希望您能理解。

警告:请注意,这可能不是很有效,因为它必须查找jar中的所有条目,因此您不想经常调用它。

答案 2 :(得分:0)

我有时要做的是用前缀的文件名和带有编号的sufix循环“ sounds”文件夹,如下所示:

for(String snd_name : new String[]{"flesh_", "sword_", "shield_", "death_", "skating_", "fall_", "block_"}) {
        int idx = 0;
        FileHandle fh;

        while((fh = Gdx.files.internal("snd/" + (snd_name + idx++) + ".ogg")).exists()) {
            String name = fh.nameWithoutExtension();
            Sound s = Gdx.audio.newSound(fh);

            if(name.startsWith("flesh")) {
                sounds_flesh.addLast(s);
            }
            else if(name.startsWith("sword")) {
                sounds_sword.addLast(s);
            }
            else if(name.startsWith("shield")) {
                sounds_shield.addLast(s);
            }
            else if(name.startsWith("death")) {
                sounds_death.addLast(s);
            }
            else if(name.startsWith("skating")) {
                sounds_skating.addLast(s);
            }
            else if(name.startsWith("fall")) {
                sounds_fall.addLast(s);
            }
            else if(name.startsWith("block")) {
                sounds_block.addLast(s);
            }
        }
    }