random access file in java

2019-04-10 08:07发布

问题:

I have the following fields:

  • Inventory control (16 byte record)
    • Product ID code (int – 4 bytes)
    • Quantity in stock (int – 4 bytes)
    • Price (double – 8 bytes)

How do I create a fixed length random access file using the above lengths? I tried some examples online, but I either get an EOF exception or random address values when I try to access them.

I tried some more examples and couldn't understand the concept very well. I'm trying a project with it and will try to explore more on it.

Here is some example data. There might be holes in the data where No. in stock could be 23 == 023.

          Quantity
ID. No.   In Stock   Price

-------   --------   ------
 1001       476      $28.35
 1002       240      $32.56
 1003       517      $51.27
 1004       284      $23.75
 1005       165      $32.25

Thanks for the help.

回答1:

java.io.RandomAccessFile is the class you're looking for. Here's an example implementation (you'll probably want to write some unit tests, as I haven't :)

package test;

import java.io.IOException;
import java.io.RandomAccessFile;

public class Raf {
    private static class Record{
        private final double price;
        private final int id;
        private final int stock;

        public Record(int id, int stock, double price){
            this.id = id;
            this.stock = stock;
            this.price = price;
        }

        public void pack(int n, int offset, byte[] array){
            array[offset + 0] = (byte)(n & 0xff);
            array[offset + 1] = (byte)((n >> 8) & 0xff);
            array[offset + 2] = (byte)((n >> 16) & 0xff);
            array[offset + 3] = (byte)((n >> 24) & 0xff);
        }

        public void pack(double n, int offset, byte[] array){
            long bytes = Double.doubleToRawLongBits(n);
            pack((int) (bytes & 0xffffffff), offset, array);
            pack((int) ((bytes >> 32) & 0xffffffff), offset + 4, array);
        }

        public byte[] getBytes() {
            byte[] record = new byte[16];
            pack(id, 0, record);
            pack(stock, 4, record);
            pack(price, 8, record);
            return record;
        }
    }

    private static final int RECORD_SIZE = 16;
    private static final int N_RECORDS = 1024;

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        RandomAccessFile raf = new RandomAccessFile(args[0], "rw");
        try{
            raf.seek(RECORD_SIZE * N_RECORDS);

            raf.seek(0);

            raf.write(new Record(1001, 476, 28.35).getBytes());
            raf.write(new Record(1002, 240, 32.56).getBytes());
        } finally {
            raf.close();
        }
    }
}


回答2:

With recent Java versions, you can manage Random access files using FileChannel. SeekableByteChannel interface define methods which allow you to change the position of the pointer in the destination entity like file which the channel is connected to. FileChannel implements SeekableByteChannel allowing you to manage random access files using channels. Methods size, position, truncate allow you to read and write files randomly.

see http://www.zoftino.com/java-random-access-files for details and example.