如何从.jar文件中包含的ZIP文件加载图像?

时间:2015-07-15 16:00:53

标签: java image intellij-idea jar zipfile

我们正在编写一个游戏,它可以从.jar文件中启动。首先,我们在IntelliJ中创建了一个项目,并使用以下代码从ZIP加载图像:

ZipFile zf = null;
try {
    zf = new ZipFile(zipPath);
    Image Image = ImageIO.read(zf.getInputStream(zf.getEntry("Block/Air.png")));
} catch (IOException ignored) {}

现在没有ZIP(仅来自.jar)的尝试是:

Image image=ImageIO.read(getClass().getResourceAsStream(path+ "Block/Air.png"));

它不会加载任何纹理。你有更好的方法来组合这个吗?

编辑:似乎不是问题。

3 个答案:

答案 0 :(得分:0)

由于jar是zip文件,你可以将它们放在jar文件中并将它们放在类路径中。

Sub CopyCharts(Source As Worksheet, Target As Worksheet)
    Dim SChart         As ChartObject
    Dim NChart         As ChartObject
    Dim NewSheetNChart As ChartObjects
    Dim ChartTop       As Single
    Dim ChartLeft      As Single
    Dim ChartIndex     As Integer
    Dim ChartSeries    As Series
    Dim XAxis          As Axis

    For Each SChart In Source.ChartObjects
        'Save chart's current position
        ChartTop = SChart.Top
        ChartLeft = SChart.Left

        'Copy and paste the chart
        SChart.Copy
        Target.Paste

        'Find the chart in a new spreadsheet
        ChartIndex = ChartIndex + 1
        Set NewSheetNChart = Target.ChartObjects
        Set NChart = NewSheetNChart(ChartIndex)

        'Align the charts
        NChart.Top = ChartTop
        NChart.Left = ChartLeft

        'Delink sereis from source
        For Each ChartSeries In NChart.Chart.SeriesCollection
            ChartSeries.XValues = ChartSeries.XValues
            ChartSeries.Values = ChartSeries.Values
            ChartSeries.Name = ChartSeries.Name
        Next ChartSeries

        'Set the X axis to correct values
        Set XAxis = NChart.Chart.Axes(xlCategory, xlPrimary)
        With XAxis
            .CategoryType = xlTimeScale
            .BaseUnit = xlMonths
            .MajorUnit = 1
        End With
    Next SChart
End Sub

路径必须是源路径根目录的相对路径。例如。我有一个文件在" src / main / resource / my / cool / game /"路径是" / my / cool / game"。

如果您想使用zip文件,它必须在您的jar文件之外。要加载zip,您可以使用相对文件路径,如果您从Intellij和dekstop启动游戏,则相同。

更改intellij look here中的工作目录。

最好的方法是将zip文件放在jar旁边,这样就可以使用"。"作为加载zip文件的工作目录。

或者您可以使用固定目录,但是您的游戏需要某种安装,因此它知道在哪里找到zip文件。

如果您使用"。",则zip文件需要位于项目目录的根目录中。

答案 1 :(得分:0)

Class.getResource和Class.getResourceAsStream方法采用相对于每个类路径条目的根的URL(不是文件路径!)。对于.jar文件的类路径条目,这个表示打包在相应.jar文件中的文件的路径。

如果您的整个程序位于一个.jar文件中,则类路径只包含一个项目:.jar文件。因此,只有一个类路径根,并且传递给getResourceAsStream的String是.jar文件中条目的URL。不要在该String中包含.jar文件的路径。

如果您不确定应该传递什么,请检查.jar文件的内容。每个IDE(我所知道的)都提供了一种方法。您还可以使用任何解压缩实用程序来检查.jar文件,因为每个.jar文件实际上都是.zip文件。 (如果您只有Windows,没有安装zip工具,请复制.jar文件并将副本的扩展名更改为“.zip”,然后将其打开。)

.jar文件内部当然是zip条目。要加载的条目的完整路径(没有.jar文件的路径)是必须传递给getResourceAsStream的路径。 getResourceAsStream接受一个URL,并且URL总是在所有平台上使用正斜杠(/),因此不要使用任何反斜杠。此外,字符串的第一个字符必须是/

实际上可以指定较短的路径,具体取决于图像在.jar中的打包方式,但这是一个单独的主题。有关详细信息,请参阅the documentation

旁注:永远不要写一个空的挡块。永远。对于您或其他任何人来说,获取异常的最简单方法是知道您的程序何时以及为何无法正常工作。至少,将exc.printStackTrace();放入catch区块。更常见的是,正确的行动方案是使用throw new RuntimeException(exc);之类的内容中止程序。毕竟,如果无法加载该图像,您的程序将无法继续正常运行,对吧?

答案 2 :(得分:-1)

为什么需要将图像存储在zip文件中?如果你这样做是为了减小文件大小,那么你首先要抓住它就完全没有任何好处。无论如何JAR文件都是压缩文件(如果您不相信我,请将.jar文件重命名为.zip,并尝试打开它)。你基本上做的是尝试压缩已经压缩的文件,这个文件实际上并没有做任何事情。

我建议你解压缩你的图像并将它们存储在像<资源> / images

如果你坚持让它们拉链,你需要把它改成这样的东西。否则,它正在工作目录(执行jar的目录)中查找zip文件

ZipFile zf = new ZipFile(getClass().getResourcesAsStream("path/to/zip"));

免责声明:我不熟悉ZipFile类,所以我不知道该构造函数是否存在。