2017-06-02 54 views
0

我試圖在我的JAR文件中加載WAV資源文件。通過IDE運行時,它完美地工作。但是當通過java -jar運行時,它給我提供了大約75%的垃圾和25%的正確數據。我想知道爲什麼。這裏有一些方法我試過:在JAR內部訪問Java資源會返回大約75%的垃圾

  1. (我的首選方法):閱讀與的getResourceAsStream從JAR給出了具有原始的某些部分損壞的數據:

    short[] waveform = AudioFileAPI.readWavFile(
        Blah.class.getResourceAsStream("/blah.wav")); 
    
  2. 從常規文件讀取:從創建的JAR OK

    waveform = AudioFileAPI.readWavFile(new File("C:\\blah\\blah.wav")); 
    
  3. 提取WAV和閱讀它作爲一個普通的文件:OK

    waveform = AudioFileAPI.readWavFile(new File("C:\\blah\\fromjar.wav")); 
    
  4. 使用getResource讀取並調用AppletAudioClip上的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. 解壓縮並重新壓縮JAR並重新運行該程序也沒有幫助。

回顧一下,上述所有方法在從IDE運行時都能很好地工作,但是在作爲資源加載時指示的方法失敗。 JAR由IntelliJ IDEA打包。我使用JDK版本1.8.0_131。 AudioFileAPI是我自己的課程。

+0

可能是因爲從'getResource(..)'返回的流不可定位。爲什麼不使用來自Java聲音API的'Clip'呢? –

+0

我實際上並不打算播放音頻,但我需要對音頻樣本進行一些信號處理。我需要資源中的二進制數據,而不是僅支持播放功能的對象。 – 3VYZkz7t

回答

0

這實際上是由於正在讀取資源的InputStream的代碼中的一個錯誤。如果InputStream的read()方法由於某種原因沒有一次讀取所有字節,後續的read()嘗試將錯誤地寫入總是從位置0開始的相同緩衝區,而不是從當前讀取的總字節數確定的位置開始。

因此,最後,緩衝區看起來像是在開始時有正確數據的碎片,最後是垃圾。