NIO Simultaneous read and write operation

Hi

I encountered a problem with filechannel. When i had updated the file using a filechannel, changes are not reflected in the buffer, therefore the data is missing after reading the buffer.

So a new buffer from the file needs to be created for every update done and this is very slow since the OS needs to remap the file again. Is there any efficient mechanism that will update the buffer when a write operation is done to the filechannel. Alternatives are also appreciated.

Many thanks.

Example below.

RandomAccessFile rFileAccess =new RandomAccessFile(gl_pathname,"rw");

FileChannel fc = rFileAccess.getChannel();

MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size());

Charset charset = Charset.forName("ISO-8859-1");

CharsetDecoder decoder = charset.newDecoder();

charBuffer = decoder.decode(mbb);

//Write to the same file @ gl_pathname

ByteBuffer bb = ByteBuffer.wrap("This is not the length of the message put in. The actual length can be very much longer than what is in this string. Thank you.".getBytes());

fc.write(bb, fc.size());

String sb =new String("");

while(charBuffer.hasRemaining()){

char c = charBuffer.get();

sb += c;

}

[1598 byte] By [kajiwaraa] at [2007-11-26 14:55:10]
# 1
Write to the file via the mapped byte buffer instead of via the channel.
ejpa at 2007-7-8 8:43:40 > top of Java-index,Java Essentials,Java Programming...
# 2
that would create ajava.nio.BufferOverflowException
kajiwaraa at 2007-7-8 8:43:40 > top of Java-index,Java Essentials,Java Programming...
# 3

I'm not pro at all with NIO, but shouldn't you use the decoder after writing to the file channel ?

Something like:

RandomAccessFile rFileAccess = new RandomAccessFile(gl_pathname, "rw");

FileChannel fc = rFileAccess.getChannel();

MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size());

Charset charset = Charset.forName("ISO-8859-1");

CharsetDecoder decoder = charset.newDecoder();

//Write to the same file @ gl_pathname

ByteBuffer bb = ByteBuffer.wrap("This is not the length of the message put in. The actual length can be very much longer than what is in this string. Thank you.".getBytes());

fc.write(bb, fc.size());

charBuffer = decoder.decode(mbb);

String sb = new String("");

while(charBuffer.hasRemaining()){

char c = charBuffer.get();

sb += c;

}

Franck_Lefevrea at 2007-7-8 8:43:40 > top of Java-index,Java Essentials,Java Programming...
# 4
Sorry but there is a read operation performed before the write operation therefore the decode(mbb) must appear before fc.write(bb, fc.size);Message was edited by: kajiwara
kajiwaraa at 2007-7-8 8:43:40 > top of Java-index,Java Essentials,Java Programming...
# 5
> that would create a java.nio.BufferOverflowExceptionNo, a programming error would create a BufferOverFlowException. That's a bug in your code, not an inherent result of writing and reading via the same mapped byte buffer.
ejpa at 2007-7-8 8:43:40 > top of Java-index,Java Essentials,Java Programming...
# 6
I not really very familiar with java nio. I would appreciate if someone would advise me on the technique. Thanks
kajiwaraa at 2007-7-8 8:43:40 > top of Java-index,Java Essentials,Java Programming...
# 7
if i use mbb.put(bb); instead of fc.write(bb, fcsize());it will produce a BufferOverflowException.
kajiwaraa at 2007-7-8 8:43:40 > top of Java-index,Java Essentials,Java Programming...
# 8
it is that i have to allocate a new buffer and then transfer the data to the new buffer?
kajiwaraa at 2007-7-8 8:43:40 > top of Java-index,Java Essentials,Java Programming...
# 9

No, it is that you have to get your buffer positions and limits and flips and rewinds organized. mb.put(bb) just puts the entire contents of bb into mb starting from the current position, and if bb won't fit between position and limit you'll get an overflow. You probably need to reset or rewind the buffer so position = zero and limit = capacity. If you don't want to clobber the entire buffer mb you'll have to use a different put method.

OTOH why do you have this other 'bb' in the first place? You should be using the mapped byte buffer for that directly, e.g. decoding straight into it.

ejpa at 2007-7-8 8:43:40 > top of Java-index,Java Essentials,Java Programming...
# 10

Its not about changing the contents that is already present in the mbb, but it

about appending new data to it and the file will grow in size.

The problem is that mbb is not updated after a append using fc.write(), so i will

only have a image of the file prior to writing it. If using mappedbytebuffer.put(),

the new data and mbb data will be greater than its capacity and will return a

bufferoverflowexception and also creating a new mbb takes too many

resources. because a file could easily be up to 10MB or even more in most

cases.

kajiwaraa at 2007-7-8 8:43:40 > top of Java-index,Java Essentials,Java Programming...
# 11
I don't think it is an application that java.nio.Buffer could do well.(Why do you use it, in the first place?)You'd be better off using classic java.io and java.util data objects.
hiwaa at 2007-7-8 8:43:40 > top of Java-index,Java Essentials,Java Programming...