2012-10-19 148 views
2

我必須在文件中寫入字節數組。我不能一次做到這一點,所以我不能把我的數組放在容器中。我的數組的大小也是可變的。其次,文件非常大,所以我必須將其分開,以便按陣列讀取數組。使用Java在文件中寫入和讀取多個字節[]

我該怎麼做?我試圖一行一行地寫我的字節數組,但我一直未能。我怎樣才能把我的數組之間的分隔符,並將其分割在此分隔符之後?

編輯:

我嘗試這樣做:

ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
ObjectOutput out = new ObjectOutputStream(bos); 
out.writeObject(byteArray); 

但是,我執行這個代碼幾次,所以用ObjectOutputStream每次增加一個新的報頭損壞的文件。

我也嘗試:

out.write(byteArray); 

但我不能分開我的陣列。所以我試圖追加一個'\ n',這不起作用。在我尋找像FileUtils這樣的庫之後,爲了逐行寫入byte [],但是我沒有找到。

+1

顯示一些代碼,並告訴我們你的嘗試。否則,我預測會有一個downvote瘋狂來臨。 –

+0

好的謝謝你的建議。給我一些時間 – Pith

+0

http://stackoverflow.com/questions/11110153/java-reading-file-chunk-by-chunk重複 – smk

回答

6

您可以使用現有的集合例如列表保持字節[]的列表並將其傳輸

List<byte[]> list = new ArrayList<byte[]>(); 
    list.add("HI".getBytes()); 
    list.add("BYE".getBytes()); 

    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
      "test.txt")); 
    out.writeObject(list); 

    ObjectInputStream in = new ObjectInputStream(new FileInputStream(
      "test.txt")); 
    List<byte[]> byteList = (List<byte[]>) in.readObject(); 

    //if you want to add to list you will need to add to byteList and write it again 
    for (byte[] bytes : byteList) { 
     System.out.println(new String(bytes)); 
    } 

輸出:

HI 
    BYE 

另一種選擇是使用RandomAccessFile這不會強制您讀取完整文件,並且可以跳過不想讀取的數據。

 DataOutputStream dataOutStream = new DataOutputStream(
      new FileOutputStream("test1")); 
    int numberOfChunks = 2; 
    dataOutStream.writeInt(numberOfChunks);// Write number of chunks first 
    byte[] firstChunk = "HI".getBytes(); 
    dataOutStream.writeInt(firstChunk.length);//Write length of array a small custom protocol 
    dataOutStream.write(firstChunk);//Write byte array 

    byte[] secondChunk = "BYE".getBytes(); 
    dataOutStream.writeInt(secondChunk.length);//Write length of array 
    dataOutStream.write(secondChunk);//Write byte array 

    RandomAccessFile randomAccessFile = new RandomAccessFile("test1", "r"); 
    int chunksRead = randomAccessFile.readInt(); 
    for (int i = 0; i < chunksRead; i++) { 
     int size = randomAccessFile.readInt(); 
     if (i == 1)// means we only want to read last chunk 
     { 
      byte[] bytes = new byte[size]; 
      randomAccessFile.read(bytes, 0, bytes.length); 
      System.out.println(new String(bytes)); 
     } 
     randomAccessFile.seek(4+(i+1)*size+4*(i+1));//From start so 4 int + i* size+ 4* i ie. size of i 
    } 

輸出:

BYE 
1

你必須在你的編碼中描述你的數據。即添加一些元數據。例如,數組的長度,然後是數組的數據。

這被稱爲序列化。

Array of int: length(4 bytes), data[0] (4 bytes), data[1] (4 bytes), data[2] (4 bytes) 
+0

真的嗎?這是*序列化*爲你? – Sujay

+0

這是一種序列化,不是唯一的一種... – Aubin

+0

這是一種序列化形式,儘管您通常只需添加儘可能多的元數據以解序列化和重新創建對象(或數組)。 –

0

有這樣做的幾種方法。基本上首先要指出的是,文件只是一個非結構化的字節序列。任何字節。基本上你想要存儲幾個可變長度的字節數組。這意味着你必須以某種方式添加結構,然後在閱讀時解析它。

最簡單的方法可能是使用一些字節序列作爲分隔符(具體而言,它的數據很少顯示在您的數據中)。

然後在寫作,第一次輕鬆的寫字節,則分離

out.write(myarray); 
out.write(separator); 
out.write(anotherarray); 

閱讀,您需要使用某種類型的滑動窗口,你可以檢查,這樣就可以計算出,如果您已經閱讀分離器。基本上只是逐個迭代字節,並保留最後幾個讀入的緩衝區。當你在你的緩衝區中看到分隔符時,你剛剛發現你的數組的末尾。

另一種方法是用一些描述長度的頭部來寫入固定長度的塊,也可能用一點來表示當前數組是否有另一個數據包。然後你只需讀取和寫入整個塊。

+0

如何處理問題:我有分隔符INTO數組? – Aubin