5

バイト配列をファイルに書き込む必要があります。一度に実行できないため、配列をコンテナーに入れることができません。また、私の配列のサイズは可変です。第二に、ファイルは非常に大きいので、配列ごとに読み取るために、ファイルを分割する必要があります。

どうやってやるの ?バイト配列を1行ずつ書き込もうとしましたが、できませんでした。配列の間にセパレータを配置し、このセパレータに分割した後、どうすればよいですか?

編集 :

私はこれを試しました:

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

ただし、このコードを数回実行するため、ObjectOutputStreamは、ファイルを破損する新しいヘッダーを毎回追加します。

私も試してみます:

out.write(byteArray);

しかし、アレイを分離することはできませんでした。そこで、「\ n」を追加しようとしましたが、機能しませんでした。byte []を1行ずつ書き込むために、FileUtilsのようなライブラリを探していましたが、見つかりませんでした。

4

3 に答える 3

8

Listなどの既存のコレクションを使用して、byte []のリストを維持し、転送することができます

    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
于 2012-10-19T15:23:25.410 に答える
1

データをエンコーディングで記​​述する必要があります。つまり、メタデータを追加します。

たとえば、配列の長さ、次に配列のデータ。

これはシリアル化と呼ばれます。

Array of int: length(4 bytes), data[0] (4 bytes), data[1] (4 bytes), data[2] (4 bytes)
于 2012-10-19T15:19:05.343 に答える
0

これを行うにはいくつかの方法があります。基本的に最初に指摘するのは、ファイルは構造化されていないバイトのシーケンスにすぎないということです。任意のバイト。基本的には、可変長の複数のバイト配列を格納する必要があります。つまり、何らかの方法で構造を追加する必要があり、それを読み取るときに解析します。

最も簡単なのは、区切り文字として扱うバイトのシーケンスを使用することです(それ以外の場合はデータに表示される可能性が低いほど具体的です)。

次に、書き込み時に、最初にバイトを書き込み、次にセパレータを書き込みます

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

読むときは、セパレーターを読んだかどうかを判断できるように、検査できるある種のスライディングウィンドウを使用する必要があります。基本的には、バイトを1つずつ繰り返し処理し、最後に読み取った数バイトをバッファーに保持します。バッファにセパレータが表示されたら、配列の終わりが見つかりました。

これに代わる方法として、固定長のブロックを、長さを説明するヘッダーと、現在の配列に別のパケットがあるかどうかを示すためのビットを使用して書き込むことができます。次に、ブロック全体を読み書きするだけです。

于 2012-10-19T16:03:19.320 に答える