在过去的几个月里,我一直在为一个大学项目开发java游戏。它即将到达项目的最后阶段,我想将项目编译成一个易于分发的文件。游戏当前从IDE内部运行,并依赖于特定地设置的工作目录(即具有声音/纹理的内容目录等)。将所有这些放在一起以便携带的最佳方法是什么?我希望有一些方法可以将内容编译到jar文件中......
NB。我正在使用NetBeans,因此任何易于使用netbeans的解决方案都会获得额外的功劳;)
附录::
为了将来的参考,我找到了一种按目录访问东西的方法,这可能不是最好的方法,但它有效:
File directory = new File(ClassLoader.getSystemResource("fullprototypeone/Content/Levels/").toURI());
现在我可以正常使用该文件对象
答案 0 :(得分:7)
你可以在jar文件中嵌入资源 - 毕竟这只是一个拉链。这样做的标准方法是将资源文件放在源层中的某个目录中。然后由Object.getClass()。getResourceAsStream()引用它们。因此,您需要更改在代码中检索它们的方式。
您可以在此处阅读更多内容:Object.getClass().getResourceAsStream()。当然,您可以使用包中的某个类来代替对象。
当你把这些资源文件放在你的src层次结构中时,我相信Netbeans应该用标准版本的项目来为你设置它们。
答案 1 :(得分:1)
以下是JNLP and Java Web Start的手册。这些技术仅适用于您所描述的任务。
答案 2 :(得分:1)
一种方法是通过Class.getResourceAsStream(或Class.getResource)访问资源。然后确保文件位于JAR文件中。
脱离我的头脑(并且没有尝试)你应该能够将资源放入源文件中,这将使NetBeans将它们放入JAR文件中。然后将File stuff更改为getResource调用。
我建议制作一个播放声音的简单程序,并在尝试转换整个项目之前尝试一下。
如果你尝试但它不起作用,请告诉我,我会看看我是否可以再深入研究一下(如果涉及这个问题,发布简单项目的代码会很好。)
答案 3 :(得分:1)
这是我在另一条评论中承诺的代码......这不是我记得的,但它可能会让你开始。
基本上你调用:String fileName = FileUtils.getFileName(Main.class,“foo.txt”);
然后它会在磁盘或JAR文件中找到该文件。如果它在JAR文件中,则将其提取到临时目录。然后,您可以使用“新文件(fileName)”打开文件,无论以前在哪里,都将在磁盘上。
我要做的是查看getFile方法,看看你可以用JAR文件做什么来迭代它的内容并找到给定目录中的文件。
就像我说的那样,不完全是你想要的,但确实为你做了很多初步工作。
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
public class FileUtils
{
public static String getFileName(final Class<?> owner,
final String name)
throws URISyntaxException,
ZipException,
IOException
{
String fileName;
final URI uri;
try
{
final String external;
final String decoded;
final int pos;
uri = getResourceAsURI(owner.getPackage().getName().replaceAll("\\.", "/") + "/" + name, owner);
external = uri.toURL().toExternalForm();
decoded = external; // URLDecoder.decode(external, "UTF-8");
pos = decoded.indexOf(":/");
fileName = decoded.substring(pos + 1);
}
catch(final FileNotFoundException ex)
{
fileName = null;
}
if(fileName == null || !(new File(fileName).exists()))
{
fileName = getFileNameX(owner, name);
}
return (fileName);
}
private static String getFileNameX(final Class<?> clazz, final String name)
throws UnsupportedEncodingException
{
final URL url;
final String fileName;
url = clazz.getResource(name);
if(url == null)
{
fileName = name;
}
else
{
final String decoded;
final int pos;
decoded = URLDecoder.decode(url.toExternalForm(), "UTF-8");
pos = decoded.indexOf(":/");
fileName = decoded.substring(pos + 1);
}
return (fileName);
}
private static URI getResourceAsURI(final String resourceName,
final Class<?> clazz)
throws URISyntaxException,
ZipException,
IOException
{
final URI uri;
final URI resourceURI;
uri = getJarURI(clazz);
resourceURI = getFile(uri, resourceName);
return (resourceURI);
}
private static URI getJarURI(final Class<?> clazz)
throws URISyntaxException
{
final ProtectionDomain domain;
final CodeSource source;
final URL url;
final URI uri;
domain = clazz.getProtectionDomain();
source = domain.getCodeSource();
url = source.getLocation();
uri = url.toURI();
return (uri);
}
private static URI getFile(final URI where,
final String fileName)
throws ZipException,
IOException
{
final File location;
final URI fileURI;
location = new File(where);
// not in a JAR, just return the path on disk
if(location.isDirectory())
{
fileURI = URI.create(where.toString() + fileName);
}
else
{
final ZipFile zipFile;
zipFile = new ZipFile(location);
try
{
fileURI = extract(zipFile, fileName);
}
finally
{
zipFile.close();
}
}
return (fileURI);
}
private static URI extract(final ZipFile zipFile,
final String fileName)
throws IOException
{
final File tempFile;
final ZipEntry entry;
final InputStream zipStream;
OutputStream fileStream;
tempFile = File.createTempFile(fileName.replace("/", ""), Long.toString(System.currentTimeMillis()));
tempFile.deleteOnExit();
entry = zipFile.getEntry(fileName);
if(entry == null)
{
throw new FileNotFoundException("cannot find file: " + fileName + " in archive: " + zipFile.getName());
}
zipStream = zipFile.getInputStream(entry);
fileStream = null;
try
{
final byte[] buf;
int i;
fileStream = new FileOutputStream(tempFile);
buf = new byte[1024];
i = 0;
while((i = zipStream.read(buf)) != -1)
{
fileStream.write(buf, 0, i);
}
}
finally
{
close(zipStream);
close(fileStream);
}
return (tempFile.toURI());
}
private static void close(final Closeable stream)
{
if(stream != null)
{
try
{
stream.close();
}
catch(final IOException ex)
{
ex.printStackTrace();
}
}
}
}
编辑:
抱歉,我现在没有时间处理这个问题(如果我得到一些,我会这样做并在此处发布代码)。这就是我要做的事情:
可能有一种更好的方法可以做到这一点,但我认为这样可以解决问题。
答案 4 :(得分:0)