2012-10-22 61 views
2

我遇到了連接回使用二進制I/O分割某些文件所產生的.dat文件的問題。使用Java中的二進制I/O分割和連接文件的機制

問題就出現了與某些類型的文件,例如,用.avi文件(不超過2GB)。當連接後面的輸出文件似乎是完全一樣被分裂的文件,但.avi文件「不能渲染文件」錯誤occures。 (如果使用Binary I/O製作文件的副本,則會發生同樣的情況)。 然而,例如,.mp4文件是否正確連接回來。

我的問題是,爲什麼出現這種情況?因爲我被教導 - 任何文件只是一個0序列和1所以,如果你只是重寫文件的二進制序列,並設置相同的文件格式 - 一切都應該正常工作。

以防萬一,這裏是我的分裂和連接播放的文件代碼(正常工作):

---分配器---

public static void main(String[] args) throws IOException { 

    String sourceFile = "Movie2.mp4"; 
    int parts = 5; 

    BufferedInputStream in = new BufferedInputStream(new FileInputStream(sourceFile)); 
    BufferedOutputStream out; 

    int partSize = in.available()/parts; 
    byte[] b;  

    for (int i = 0; i < parts; i++) { 
     if (i == parts - 1) {     
      b = new byte[in.available()]; 
      in.read(b); 
      out = new BufferedOutputStream(new FileOutputStream(sourceFile + "_" + i + ".dat")); 
      out.write(b); 
      out.close(); 
     } else { 
      b = new byte[partSize]; 
      in.read(b); 
      out = new BufferedOutputStream(new FileOutputStream(sourceFile + "_" + i + ".dat")); 
      out.write(b); 
      out.close(); 
     } 
    } 

    in.close(); 
} 

--- ---連接器

public static void main(String[] args) throws IOException { 

    String sourceFile; 
    BufferedInputStream in; 
    byte[] b; 
    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("Movie2RESTORED.mp4", true)); 

    for (int i = 0; i < 5; i++) { 
     sourceFile = "Movie2.mp4_" + i + ".dat"; 
     in = new BufferedInputStream(new FileInputStream(sourceFile)); 
     b = new byte[in.available()]; 
     in.read(b); 
     out.write(b); 
     in.close(); 
    } 

    out.close(); 
} 

在此先感謝!

+0

連接文件的大小是否與原始大小相同或是某些字節是否丟失或添加? –

+0

這是完全一樣的,字節數量完全相同 – Makks129

+0

你在哪裏out.close();'你所有的文件? –

回答

3

你需要周圍in.read(b)一個循環。

即使available應該返回可以無阻塞地讀取的字節數,您可能需要多次調用read以獲取所有這些字節。這將使用緩衝器具有固定的大小會更容易,但如果你堅持閱讀由適用於指定的字節數:

int toBeRead = in.available(); 
byte[] b = new byte[toBeRead]; 
int totalRead = 0; 
int read; 
while ((read = in.read(b, totalRead, toBeRead-totalRead)) != -1) { 
    totalRead += read; 
} 

此外,像由aetheria提到的,你應該叫close關閉各種輸出流。否則,保留在JVM和OS緩衝區中的數據可能不會進入文件中,儘管它看起來像目前它們一樣。