How do I use a FileChannel to read data into a Buffer?

The example below show how to use a FileChannel to read some data into a Buffer. We create a FileChannel from a FileInputStream instance. Because a channel reads data into buffer we need to create a ByteBuffer and set its capacity. Read data from a channel into buffer using the FileChannel.read() method.

To read out the data from the buffer we need to flip the buffer first using the Buffer.flip() method. The method will change the buffer from writing-mode into reading-mode. After the entire buffer is read clear the buffer using the clear() method call.

package org.kodejava.io;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class FileRead {
    public static void main(String[] args) {
        String path = "D:/Temp/source.txt";
        try (FileInputStream fis = new FileInputStream(path);
             FileChannel fileChannel = fis.getChannel()) {

            ByteBuffer buffer = ByteBuffer.allocate(64);

            int bytesRead = fileChannel.read(buffer);
            while (bytesRead != -1) {
                buffer.flip();

                while (buffer.hasRemaining()) {
                    System.out.print((char) buffer.get());
                }

                buffer.clear();
                bytesRead = fileChannel.read(buffer);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

How do I create a NIO Buffer?

This post show you how to use the java.nio buffer such as ByteBuffer, CharBuffer, DoubleBuffer, etc. To create a buffer you can use the allocate(int capacity) method. Each buffer object has the allocate(int capacity) method. You need to pass the value of the capacity of the buffer to be created when calling this method.

package org.kodejava.io;

import java.nio.*;

public class BufferAllocate {
    public static void main(String[] args) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(64);
        CharBuffer charBuffer = CharBuffer.allocate(64);
        ShortBuffer shortBuffer = ShortBuffer.allocate(64);
        IntBuffer intBuffer = IntBuffer.allocate(64);
        LongBuffer longBuffer = LongBuffer.allocate(64);
        FloatBuffer floatBuffer = FloatBuffer.allocate(64);
        DoubleBuffer doubleBuffer = DoubleBuffer.allocate(64);
    }
}

How do I copy file using FileChannel class?

The example below show you how to copy a file using the java.nio.channels.FileChannel class.

package org.kodejava.io;

import java.io.*;
import java.nio.channels.FileChannel;

public class FileCopy {
    public static void main(String[] args) {
        //// Define the source and target file
        File source = new File("D:/Temp/source.txt");
        File target = new File("D:/Temp/target.txt");

        // Create the source and target channel
        try (FileChannel sourceChannel = new FileInputStream(source).getChannel();
             FileChannel targetChannel = new FileOutputStream(target).getChannel()) {

            // Copy data from the source channel into the target channel
            targetChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

How do I read a file into byte array?

package org.kodejava.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class ReadFileIntoByteArray {
    public static void main(String[] args) throws IOException {
        File file = new File("README.md");
        try (InputStream is = new FileInputStream(file)) {
            if (file.length() > Integer.MAX_VALUE) {
                throw new IOException("File is too large.");
            }

            int offset = 0;
            int bytesRead;
            byte[] bytes = new byte[(int) file.length()];
            while (offset < bytes.length
                    && (bytesRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
                offset += bytesRead;
            }
        }
    }
}

How do I detect non-ASCII characters in string?

The code below detect if a given string has a non ASCII characters in it. We use the CharsetDecoder class from the java.nio package to decode string to be a valid US-ASCII charset.

package org.kodejava.io;

import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharacterCodingException;
import java.nio.CharBuffer;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

public class NonAsciiValidation {
    public static void main(String[] args) {
        // This string contains a non ASCII character which will produce exception
        // in this program. While the second string has a valid ASCII only characters.
        byte[] invalidBytes = "Copyright © 2021 Kode Java Org".getBytes();
        byte[] validBytes = "Copyright (c) 2021 Kode Java Org".getBytes();

        // Returns a charset object for the named charset.
        CharsetDecoder decoder = StandardCharsets.US_ASCII.newDecoder();
        try {
            CharBuffer buffer = decoder.decode(ByteBuffer.wrap(validBytes));
            System.out.println(Arrays.toString(buffer.array()));

            buffer = decoder.decode(ByteBuffer.wrap(invalidBytes));
            System.out.println(Arrays.toString(buffer.array()));
        } catch (CharacterCodingException e) {
            System.err.println("The information contains a non ASCII character(s).");
            e.printStackTrace();
        }
    }
}

Below is the result of the program:

[C, o, p, y, r, i, g, h, t,  , (, c, ),  , 2, 0, 2, 1,  , K, o, d, e,  , J, a, v, a,  , O, r, g]
The information contains a non ASCII character(s).
java.nio.charset.MalformedInputException: Input length = 1
    at java.base/java.nio.charset.CoderResult.throwException(CoderResult.java:274)
    at java.base/java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:820)
    at org.kodejava.io.NonAsciiValidation.main(NonAsciiValidation.java:23)