0

I've been getting some strange outputs from this code upon reading from a large file, the file was printed using a while loop to 99,999 digits however, upon reading the file and printing the contents it only outputs 99,988 lines. Also, is using a ByteBuffer the only option for reading back the file? I've seen some other code using a CharBuffer, but I'm not sure which one I should use, and in what cases I should use them. NOTE: filePath is a Path object pointing to a file on the disk.

    private void byteChannelTrial() throws Exception {
        try (FileChannel channel = (FileChannel) Files.newByteChannel(filePath, READ)) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            String encoding = System.getProperty("file.encoding");
            while (channel.read(buffer) != -1) {
                buffer.rewind();
                System.out.print(Charset.forName(encoding).decode(buffer));
                buffer.clear();
            }
        }
Sarah Szabo
  • 10,345
  • 9
  • 37
  • 60
  • That code should print the entire contents of the file correctly. Is it printing what it does print correctly? and have you considered using a `BufferedReader` wrapped around an `InputStreamReader` wrapped around a `FileInputStream`? – user207421 Mar 25 '13 at 07:14
  • Are you counting digits or lines (you mention both)? Also, how are you determining the number of lines written? – Perception Mar 25 '13 at 07:15
  • Every new integer corresponds with a line. So the number count is the line count. – Sarah Szabo Mar 25 '13 at 07:18

3 Answers3

2

Usually, flip() is called before buffer data is read. the rewind() method does bellowing works:

public final Buffer rewind() {
    position = 0;
    mark = -1;
    return this;
}

it does not set the 'limit' as flip() does:

public final Buffer flip() {
    limit = position;
    position = 0;
    mark = -1;
    return this;
}

So, take a tray using flip() instead of rewind() before reading.

horaceman
  • 375
  • 1
  • 5
1

For reading text BufferedReader is the best

    try (BufferedReader rdr = Files.newBufferedReader(Paths.get("path"),
            Charset.defaultCharset())) {
        for (String line; (line = rdr.readLine()) != null;) {
            System.out.println(line);
        }
    }

BTW

String encoding = System.getProperty("file.encoding");
Charset.forName(encoding);

is equivalent to

Charset.defaultCharset();
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
0

Well, it actually turns out that this combination works:

    private void byteChannelTrial() throws Exception {
        try (FileChannel channel = (FileChannel) Files.newByteChannel(this.filePath, READ)) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while (channel.read(buffer) != -1) {
                buffer.flip();
                System.out.print(Charset.defaultCharset().decode(buffer));
                buffer.clear();
            }
        }
    }

As to why it works, i am not quite certain.

Sarah Szabo
  • 10,345
  • 9
  • 37
  • 60
  • It works because you are calling `flip()` instead of `rewind()`, as per @horaceman's answer. – user207421 Mar 26 '13 at 06:33
  • For reference this code may fail to decode multi-byte chars, or with combining chars (diacritics, emojis) on buffer limit because the bytes may be incomplete in the current buffer. This will typically happen with UTF-8 encoding. – bric3 Jan 05 '21 at 22:00