1

I am trying to write char, double and integer back to my binary file base on my String arraylist. However, after finishing writing and I read the binary file again it generates erros. Anyone could help with this I really appreciate it.

ArrayList<String>temp = new ArrayList<String>();
    for(int i = 0;i<temp.size();i++){
                String decimalPattern = "([0-9]*)\\.([0-9]*)";  
                boolean match = Pattern.matches(decimalPattern, temp.get(i));
                if(Character.isLetter(temp.get(i).charAt(0))){
                    os.writeChar(temp.get(i).charAt(0));
                }
                else if(match == true){
                    Double d = Double.parseDouble(temp.get(i));
                    os.writeDouble(d);
                }       
                else
                {
                 int in = Integer.parseInt(temp.get(i));
                 os.writeInt(in);
                }
            }
            os.close();
         }
6
  • 2
    What errors? can you show us how you read the file? Commented Apr 27, 2013 at 18:28
  • What errors are you gettin? Commented Apr 27, 2013 at 18:28
  • 4
    The problem is that you're randomly writing char, double and int in your binary file, so when reading it you don't know how to read it i.e. must I first read a char, a double or an int? Commented Apr 27, 2013 at 18:28
  • You can use Channel if you want to do random reading and writing. FileChannel or a SeekableByteChannel will do. However, I recommend FileChannel as it is much easier. Commented Apr 27, 2013 at 18:32
  • 1
    @LittleChild you can write an answer showing the usage of Channel to solve this problem. Commented Apr 27, 2013 at 18:39

1 Answer 1

2

This is a very simple example which will show you how to read your data sequentially:

public void readFile(String absoluteFilePath){
    ByteBuffer buf = ByteBuffer.allocate(2+4+8) // creating a buffer that is suited for data you are reading
    Path path = Paths.get(absoluteFilePath);

    try(FileChannel fileChannel = (FileChannel)Files.newByteChannel(path,Enum.setOf(READ))){
        while(true){
            int bytesRead = fileChannel.read(buf);
            if(bytesRead==-1){
                break;
            }
            buf.flip(); //get the buffer ready for reading.
            char c = buf.asCharBuffer().readChar(); // create a view buffer and read char
            buf.position(buf.position() + 2); //now, lets go to the int
            int i = buf.asIntBuffer().readInt(); //read the int
            buf.position(buf.position()+ 4); //now, lets go for the double.
            double d = buf.asDoubleBuffer().readDouble();
            System.out.println("Character: " + c + " Integer: " + i + " Double: " + d);
            buf.clear();
        }
    }catch(IOException e){
        e.printStackTrace();
    }// AutoClosable so no need to explicitly close
}  

Now, assuming that you always write data as (char,int,double) into your file and that there are no chances where your data would be out of order or incomplete as (char,int) / (char,double), you can simply read the data randomly by specifying the position in the file, measured in bytes, from where to fetch the data as:

channel.read(byteBuffer,position);  

In your case, the data is always 14 bytes in size as 2 + 4 + 8 so all your read positions will be multiples of 14.

First block at: 0 * 14 = 0  
Second block at: 1 * 14 = 14  
Third block at: 2 * 14 = 28

and so on..

enter image description here

Similar to reading, you can also write using

channel.write(byteBuffer,position)  

Again, positions will be multiples of 14.

This applies in case of FileChannel which is a super class of ReadableByteChannel which is a dedicated channel for reading, WritableByteChannel which is a dedicated channel for writing and SeekableByteChannel which can do both reading and writing but is a little bit more complex.

When using channels and ByteBuffer, take care as to how you read. There is nothing to prevent me from reading 14 bytes as a set of 7 characters. Although this looks scary, this gives you complete flexibility on how you read and write data

Sign up to request clarification or add additional context in comments.

3 Comments

Sorry I forgot to mention this point, the order of char, double and int must based on the a txt file. if the txt file is char double and int. And then when you are writing data back to binary file it also supposed to be char double int char double int...(separate line) and so on..
It is binary so separate line will not be visible. When you read back the data, it depends on you to represent it the way you want. If the txt file has data in any order then it must have some way of identifying what piece of data you are about to read next. Maybe a code which identifies what comes next
Also, when you write with channels, you will create a .bin file and not a txt file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.