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
或whatever.trash
!
我没有想法,也许我犯了或犯了大错,所以如果可以,请帮助我。
答案 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);
}
}
}