代码之家  ›  专栏  ›  技术社区  ›  Martin

用内容分发Java程序

  •  2
  • Martin  · 技术社区  · 15 年前

    在过去的几个月里,我一直在为一个大学项目做java游戏。它即将结束的项目,我想编译成一个单一的文件,这是易于分发的项目。游戏目前在IDE内部运行,并依赖于工作目录被设置在特定的地方(即带有声音/纹理等的内容目录)。为了便于携带,最好的方法是什么?我希望有办法把内容编译成jar文件。。。

    注意。我使用的是NetBeans,所以任何在NetBeans中简单的解决方案都会得到额外的赞扬;)

    附录:

    为了将来的参考,我找到了一种通过目录访问东西的方法,这可能不是最好的方法,但它是有效的:

    File directory = new File(ClassLoader.getSystemResource("fullprototypeone/Content/Levels/").toURI());
    

    5 回复  |  直到 15 年前
        1
  •  7
  •   pajton    15 年前

    您可以在jar文件中嵌入资源—这毕竟只是一个zip文件。标准方法是将资源文件放在源层次结构的某个目录中。然后通过Object.getClass().getResourceAsStream()引用它们。因此,您需要更改在代码中检索它们的方式。

    您可以在此处阅读更多内容: Object.getClass().getResourceAsStream()

    当您将这些资源文件放在src层次结构中时,我相信Netbeans应该用项目的标准构建为您提供jar。

        2
  •  1
  •   Roman    15 年前

    JNLP and Java Web Start . 这些技术只是为您描述的任务而存在的。

        3
  •  1
  •   TofuBeer    15 年前

    我建议做一个简单的程序,播放声音,并尝试它之前,你试图转换整个项目。

    如果你尝试,但它不工作,让我知道,我会看看我是否可以深入一点(张贴的简单项目的代码将是很好的,如果它来了)。

        4
  •  1
  •   Community CDub    8 年前

    它会在磁盘或JAR文件中找到该文件。如果它在JAR文件中,它会将它提取到一个临时目录中。然后,您可以使用“new File(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();
                }
            }
        }
    }
    

    编辑:

    抱歉,我现在没有时间处理这个问题(如果我得到一些,我会把代码贴在这里)。但我会这么做:

    1. ZipFile 分类并使用 entries()
    2. 这个 ZipEntry
    3. this answer 将为您提供一种方法来选择一个临时目录以将内容提取到其中。
    4. 我想我贴的密码 this answer 可能有助于将ZipEntry内容复制到文件系统。
    5. 一旦这些项在文件系统上,您已经拥有的用于在目录上迭代的代码仍然可以工作。您可以在上面的代码中向FileUtils类添加一个新方法,并且可以像现在这样查找所有文件。

    也许有更好的办法,但我想这会管用的。

        5
  •  0
  •   sp3tsnaz    15 年前

    对将编译好的.class文件和包含文件夹的资源放在jar文件中。。你还必须建立一个清单文件。。您可以找到关于在上创建.jar文件的教程 谷歌。您很可能会被推荐到java.sun.com。