5

我必须在文件中写入字节数组。我不能一次完成,所以我不能把我的数组放在一个容器里。我的数组的大小也是可变的。其次,文件非常大,所以我必须拆分它,以便逐个数组读取它。

我怎样才能做到这一点 ?我试图逐行编写我的字节数组,但我做不到。如何在我的数组之间放置一个分隔符,然后将它拆分到这个分隔符上?

编辑 :

我试过这个:

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

但是,我多次执行此代码,因此 ObjectOutputStream 每次都会添加一个新的标头,这会破坏文件。

我也尝试:

out.write(byteArray);

但我无法分离我的数组。所以我尝试附加一个'\ n',但没有奏效。在我寻找像 FileUtils 这样的库以便逐行编写 byte[] 但我没有找到之后。

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);

在阅读时,您需要使用某种可以检查的滑动窗口,以便确定您是否已阅读分隔符。基本上只是逐个迭代字节并将您读过的最后几个字节保存在某个缓冲区中。当您在缓冲区中看到分隔符时,您刚刚找到了数组的末尾。

对此的替代方法可以是写入固定长度的块,其中包含一些描述长度的标头,并且可能还有一些用于表示当前数组是否存在另一个数据包的位。然后,您只需读取和写入整个块。

于 2012-10-19T16:03:19.320 回答