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

Java 导出桌面应用程序中内部文件的LibGDX列表,java,libgdx,file-handling,Java,Libgdx,File Handling,我对LibGDX的文件系统有一个很大的问题。我需要jar文件中文件夹中所有文件的列表。我尝试了不同的方法,但最好的代码是: FileHandle dirHandle; if (Gdx.app.getType() == ApplicationType.Android) { dirHandle = Gdx.files.internal("levels"); } else { // ApplicationType.Desktop .. dirHan

我对
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.xml
,或者
随便什么.trash


我不知道,可能是我犯了或犯了一个大错误,所以如果可以的话,请帮助我。

当目录由类路径上的JAR文件支持时,Java没有提供一种方便的方法来列出“目录”中的“文件”(请参阅一些解决方法)。我认为这是因为在多个.jar文件和类路径目录中存在一个“目录”的一般情况非常复杂(系统必须在多个源中呈现条目的联合,并处理重叠)

因为Java/Android不支持clean,Libgdx也不支持clean(搜索类路径是“内部”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文件时设置一些东西来构建这个文本文件。(这是一个单独的问题,所以我不知道答案…)


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

当该目录由类路径上的JAR文件支持时,Java没有提供一种方便的方法来列出“目录”中的“文件”(有关一些解决方法,请参阅)。我认为这是因为在多个.jar文件和类路径目录中存在一个“目录”的一般情况非常复杂(系统必须在多个源中呈现条目的联合,并处理重叠)

因为Java/Android不支持clean,Libgdx也不支持clean(搜索类路径是“内部”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文件时设置一些东西来构建这个文本文件。(这是一个单独的问题,所以我不知道答案…)


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

如果您仍在寻找实际答案,这里是(这有点黑客,但它的工作)

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

FileHandle[] fileList = JarUtils.listFromJarIfNecessary("Path/to/your/folder");
FileHandle[] fileList = JarUtils.listFromJarIfNecessary(yourJarFileFilter);
JarFileFilter是一个简单的类,它重载Java默认文件过滤器以满足jar过滤器的需要

这既可以在IDE中运行,也可以在jar文件中运行。它还检查游戏是否在桌面上运行,否则它将使用默认的libGDX方式加载资源,以便安全地用于跨平台项目(Android、Ios等)。
如果需要,可以随时更新代码以满足您的需要。代码有文档记录,大约有150行,希望您能理解它


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

如果您仍在查找实际答案,这里是(这有点像黑客,但它的工作)

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

FileHandle[] fileList = JarUtils.listFromJarIfNecessary("Path/to/your/folder");
FileHandle[] fileList = JarUtils.listFromJarIfNecessary(yourJarFileFilter);
JarFileFilter是一个简单的类,它重载Java默认文件过滤器以满足jar过滤器的需要

这既可以在IDE中运行,也可以在jar文件中运行。它还检查游戏是否在桌面上运行,否则它将使用默认的libGDX方式加载资源,以便安全地用于跨平台项目(Android、Ios等)。
如果需要,可以随时更新代码以满足您的需要。代码有文档记录,大约有150行,希望您能理解它


警告:注意这可能不是很有效,因为它必须查找jar中的所有条目,所以您不想太频繁地调用它。

我有时会使用前缀文件名和数字后缀循环“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);
            }
        }
    }

我有时会使用前缀文件名和数字后缀循环“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);
            }
        }
    }

您是否将包含文件的文件夹添加到eclipse中的“order an export”列表中?是的,我添加了。问题不是缺少文件,而是文件的“missing”路径。您是否将包含文件的文件夹添加到eclipse中的“order an export”列表中?是的,我添加了。问题不是缺少文件,而是缺少文件文件路径。谢谢你的帮助。我想我将使用另一个系统来加载我的关卡。问题是,如果我将它们写入一个静态文件,那么在不将它们添加到levelfile(“level.txt”)的情况下,您无法添加或发布文件。我认为,将它们存储在Userdata路径中自己的文件夹中更容易。不过,谢谢你的想法。@DykeStorm,如果你想将你的关卡存储在