Reputation: 439
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();
}
Upvotes: 1
Views: 1184
Reputation: 24998
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..
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
Upvotes: 2