访问Jar内部的Java资源返回约75%的垃圾



我正在尝试将WAV资源文件加载到我的jar文件中。通过IDE运行时,它可以很好地工作。但是,当通过java -jar运行时,它给了我约75%的垃圾和25%的正确数据。我想知道为什么。这是我尝试的几种方法:

  1. (我的首选方法(:用JAR的GetResourCeasStream读取具有原始部分的损坏数据:

    short[] waveform = AudioFileAPI.readWavFile(
        Blah.class.getResourceAsStream("/blah.wav"));
    
  2. 从常规文件中读取:ok

    waveform = AudioFileAPI.readWavFile(new File("C:\blah\blah.wav"));
    
  3. 从创建的jar提取wav并将其读为常规文件:ok

    waveform = AudioFileAPI.readWavFile(new File("C:\blah\fromjar.wav"));
    
  4. 在appletaudioclip上使用getResource和call play((读取75%的损坏数据。

    Object o = Blah.class.getResource("/blah.wav").getContent();
    AppletAudioClip appletAudioClip = (AppletAudioClip) o;
    appletAudioClip.play();
    
  5. 通过getResource((。openstream((:75%的损坏数据如上所述。

    InputStream is = Blah.class.getResource("/blah.wav").openStream();
    waveform = AudioFileAPI.readWavFile(is);
    
  6. 解压缩并重新拉链罐并重新运行该程序也无济于事。

回顾一下,从IDE运行时,所有上述方法都可以很好地工作,但是指示的方法在加载作为资源时失败。罐子是由Intellij Idea包装的。我使用JDK版本1.8.0_131。Audiofileapi是我自己的班级。

这实际上是由于代码中读取资源输入流中的错误。如果出于任何原因,InputStream的read()方法并未一次读取所有字节,那么随后的read()尝试将错误地写入相同的缓冲区始终从位置0开始,而不是以由总数BYTE读取到迄今为止的位置开始。。

因此,最终,缓冲区看起来像是在开始时具有正确数据的片段,最后垃圾。

read()不能保证一口气读取文件。如果您阅读了InputReader的文档。它说

读取来自输入流的某些字节,并将它们存储到缓冲区阵列中b。

即使read(byte[] b, int off, int len)功能签名也不能保证它会读取您提供的所有Len字节。

从输入流到一个字节数组的数据读取数据。试图读取与Len字节一样多的读数,但是可以读取较小的数字。实际读取的字节数作为整数返回。

因此,您必须循环直到available()为零。

这是一个示例代码,其中还包括如何在JAR文件中指定文件。

更改jarpath以指向jarfile的位置。然后更改FILEPATH,以指向罐子内的文件。如果您的文件在

somejar.jar img test.gif

将filepath设置为" img test.gif"

File executable = new File(jarPath);
JarFile jar = new JarFile(executable);
InputStream fileInputStreamReader = jar.getInputStream(jar.getJarEntry(filePath));
byte[] bytes = new byte[fileInputStreamReader.available()];
int sizeOrig = fileInputStreamReader.available();
int size = fileInputStreamReader.available();
int offset = 0;
while (size != 0){
    fileInputStreamReader.read(bytes, offset, size);
    offset = sizeOrig - fileInputStreamReader.available();
    size = fileInputStreamReader.available();
}

最新更新