我正在尝试将WAV资源文件加载到我的jar文件中。通过IDE运行时,它可以很好地工作。但是,当通过java -jar
运行时,它给了我约75%的垃圾和25%的正确数据。我想知道为什么。这是我尝试的几种方法:
-
(我的首选方法(:用JAR的GetResourCeasStream读取具有原始部分的损坏数据:
short[] waveform = AudioFileAPI.readWavFile( Blah.class.getResourceAsStream("/blah.wav"));
-
从常规文件中读取:ok
waveform = AudioFileAPI.readWavFile(new File("C:\blah\blah.wav"));
-
从创建的jar提取wav并将其读为常规文件:ok
waveform = AudioFileAPI.readWavFile(new File("C:\blah\fromjar.wav"));
-
在appletaudioclip上使用getResource和call play((读取75%的损坏数据。
Object o = Blah.class.getResource("/blah.wav").getContent(); AppletAudioClip appletAudioClip = (AppletAudioClip) o; appletAudioClip.play();
-
通过getResource((。openstream((:75%的损坏数据如上所述。
InputStream is = Blah.class.getResource("/blah.wav").openStream(); waveform = AudioFileAPI.readWavFile(is);
-
解压缩并重新拉链罐并重新运行该程序也无济于事。
回顾一下,从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();
}