java - Why doesn't my way of using FileChannel, ByteBuffer and CharBuffer work like the other way? -
given file
orange purple indigo pink
why won't myway method in code below give me content of bytebuffer via charset.decode? notice validate bytebuffer has file content, seems no matter methodology use within myway, cannot generated charbuffer have content. otherway method works expected. know what's going on? i've read javdoc bytebuffer , charbuffer didn't see explains (or missed it.) difference make use filechannel.read vs filechannel.map if can show content of buffer read?
public class junk { private static final int buffer_size = 127; private static final string charset = "utf-8"; public static void main(string[] args) { try { string filename = "two.txt"; myway(filename); otherway(filename); } catch (ioexception e) { throw new illegalstateexception(e); } } private static void myway(string filename) throws ioexception { system.out.println("i did way!......"); filechannel channel = filechannel.open(paths.get(filename), standardopenoption.read); // tried both `allocate` , `allocatedirect` bytebuffer buffer = bytebuffer.allocatedirect(buffer_size); int bytesread = channel.read(buffer); channel.close(); // manually build string bytebuffer. // validate buffer has content stringbuilder sb = new stringbuilder(); for(int i=0;i<bytesread;i++){ sb.append((char)buffer.get(i)); } system.out.println("manual string='"+sb+"'"); charbuffer charbuffer = charset.forname(charset).decode(buffer); // why no have chars??!! system.out.println("charbuffer='" + new string(charbuffer.array()) + "'"); system.out.println("charbuffer='" + charbuffer.tostring() + "'"); system.out.println("........my way sucks."); } private static void otherway(string filename) throws ioexception{ system.out.println("the other way..."); filechannel channel = filechannel.open(paths.get(filename), standardopenoption.read); bytebuffer buffer = channel.map(filechannel.mapmode.read_only, 0, channel.size()); channel.close(); charset chars = charset.forname(charset); charbuffer cbuf = chars.decode(buffer); string str = new string(cbuf.array()); system.out.println("str = '" + str + "'"); system.out.println("...works."); } } the output:
i did way!...... manual string='orange purple indigo pink' charbuffer='������������������������������������������������������������������������������������������������������' charbuffer='������������������������������������������������������������������������������������������������������' ........my way sucks. other way... str = 'orange purple indigo pink' ...works.
simple , subtle: don't rewind buffer.
when call filechannel#read(bytebuffer), method advance position() of buffer:
system.out.println("before "+buffer.position()); // prints 0 int bytesread = channel.read(buffer); system.out.println("after "+buffer.position()); // prints 28 when afterwards decode charbuffer, decode 99 bytes have never been written (and still 0).
just add
buffer.rewind(); // (or buffer.position(0)) buffer.limit(bytesread); after have read data file channel, decode method grabs part has received data.
Comments
Post a Comment