Baffling FileChannel exercise
<p>I've been stuck all morning on this, perhaps someone could help me out. The exercise is reading back a file containing a number of Strings (with no separater characters) from one file and the binary int lengths of the of the corresponding Strings from another file. I've verified that the files are written correctly by using the author's provided solution as well as my own for the writing class.</p>

<p>I'm sure there a few different ways to do this, but here is the code I have:</p>

<pre><code>public class ProverbReader {
   public static void main(String[] args) {
    Path sayingsFile = Paths.get("d:/java IO/Sayings.txt");
    Path sayingsLengthFile = Paths.get("d:/java IO/SayingsLength.bin");

    if(!Files.exists(sayingsFile) || !Files.exists(sayingsLengthFile)) {

        System.out.println("One or both files do not exist, exiting program");
        System.exit(1);
    }

    final int SAYINGS_COUNT = 20;
    final int INT_BYTES = 4;
    final int CHAR_BYTES = 2;

    int[] lengths = new int[SAYINGS_COUNT];

    try (ReadableByteChannel sayingsIn = Files.newByteChannel(sayingsFile);
        ReadableByteChannel lengthsIn =
                Files.newByteChannel(sayingsLengthFile)){

        ByteBuffer buf = ByteBuffer.allocate(SAYINGS_COUNT * INT_BYTES);

        while (true) {
            if (lengthsIn.read(buf) == -1)
                break;

            buf.flip();
            int numberRead = buf.remaining()/INT_BYTES;

            int totalChars = 0;
            for (int i = 0; i &lt; numberRead; ++i) {
                lengths[i] = buf.getInt();
                totalChars += lengths[i];
            }

            ByteBuffer strBuf = ByteBuffer.allocate(totalChars * CHAR_BYTES);

            if (sayingsIn.read(strBuf) == -1) {
                System.out.println("A serious error has occured, terminating");
                System.exit(1);
            }

            strBuf.flip();

            char[] charArray = new char[totalChars];

            strBuf.asCharBuffer().get(charArray);

            int count = 0;
            for (int i = 0; i &lt; numberRead; ++i) {
                String saying = String.valueOf(charArray, count, lengths[i]);
                System.out.printf(
                   "Length of saying: %3d Saying: %s%n", lengths[i], saying);
                count += lengths[i];
            }
            buf.clear();
        }
    } catch (IOException e) {
        e.printStackTrace();
        System.exit(1);
    }
}
</code></pre>

<p>}</p>

<p>The output is:</p>

<pre><code>Length of saying:  44 Saying: ?A nod is as good as a wink to a blind horse
Length of saying:  27 Saying: .Least said, soonest mended
Length of saying:  42 Saying: .There are 10 kinds of people in the world
Length of saying:  50 Saying: .those that understand binary and those that don't
Length of saying:  47 Saying: .You can't amke a silk purse out of a sow's ear
Length of saying:  33 Saying: .Hindsight is always twnty-twenty
Length of saying:  29 Saying: .Existentialism has no future
Length of saying:  43 Saying: .Those who are not confused are misinformed
Length of saying:  32 Saying: .Better untaught that ill-taught
</code></pre>

<p>The '?' should not be there, and the last saying is missing the '.'</p>

<p>The file was written with a BufferWriter:</p>

<pre><code>try(BufferedWriter fileOut =
   Files.newBufferedWriter(file,  Charset.forName("UTF-16")))
</code></pre>

<p>I did get it working with a BufferedReader instead of the FileChannel, but I don't understand the behavior of the FileChannel, since the file is encoded as UTF-16?</p>

<p>Here is the code that generates the files:</p>

<pre><code>public class WriterOutputToFile {

public static void main(String[] args) {
    String[] sayings = { "A nod is as good as a wink to a blind horse.",
            "Least said, soonest mended.",
            "There are 10 kinds of people in the world.",
            "those that understand binary and those that don't.",
            "You can't amke a silk purse out of a sow's ear.",
            "Hindsight is always twnty-twenty.",
            "Existentialism has no future.",
            "Those who are not confused are misinformed.",
            "Better untaught that ill-taught." };

    Path dir = Paths.get("d:/java io/");

    Path file = dir.resolve("Sayings.txt");

    try {
        Files.createDirectories(file.getParent());
    } catch(IOException e) {
        System.err.println("Error craeting directory: " + file.getParent());
        e.printStackTrace();
        System.exit(1);
    }
    try(BufferedWriter fileOut = Files.newBufferedWriter(file,  Charset.forName("UTF-16"))) {

        for(int i = 0; i &lt; sayings.length; ++i) {
            fileOut.write(sayings[i]);
        }
    } catch (IOException e) {
        System.err.println("error writing file: " + file);
        e.printStackTrace();
    }

    Path fileLength = dir.resolve("SayingsLength.bin");
    ByteBuffer buf = ByteBuffer.allocate(sayings.length * 4);
    IntBuffer intBuf = buf.asIntBuffer();

    int[] lengths = new int[sayings.length];
    for(int i = 0; i &lt; lengths.length; ++i) {
        lengths[i] = sayings[i].length();
        intBuf.put(lengths[i]);
    }

    try (BufferedOutputStream lengthOut = new BufferedOutputStream(Files.newOutputStream(fileLength))) {
        lengthOut.write(buf.array(), 0, buf.capacity());
        System.out.println("dir createred");
    } catch (IOException e) {
        System.err.println("error writing file: " + file);
        e.printStackTrace();
    }

}
</code></pre>

<p>}</p>
