- Java NIO File Read Write with Channels
- Buffered File Read Write
- Read File
- Write File
- Stream File Read Write
- Read File
- Write File
- Simple NIO File Read Write
- File Read with ByteChannel
- File Write with ByteChannel
- File Read with FileChannel
- File Write with FileChannel
- Example Channel File I/O Full Code
- Popular Articles
- Reading a File with Channels and Buffers
Java NIO File Read Write with Channels
In this Java tutorial, we will see about how to read and write files using NIO channels. Channels are used for data transfer between a buffer and an entity. There are different channels like ByteChannel, FileChannel, SocketChannel and DatagramChannel. In this tutorial we will learn about using ByteChannel and FileChannel to perform file IO operations. Just wanted to remind you, I am publishing a Java NIO tutorial series and this tutorial is part of it. Go through the NIO Channel tutorial to know more about NIO channels.
Before going into using NIO channels to read and write files, let us do a quick recap of our standard file I/O operations. Hope you remember the buffered readers and IO streams which we have been using long to do IO operations in Java.
Buffered File Read Write
We create an instance of BufferedReader and read line by line till end of file.
Read File
Charset charset = Charset.forName(«US-ASCII»); Path filePath = FileSystems.getDefault().getPath(«.», «temp.txt»); BufferedReader bufferedReader = Files.newBufferedReader(filePath, charset); String line = null; while ((line = bufferedReader.readLine()) != null)
Write File
Charset charset = Charset.forName("US-ASCII"); Path filePath = FileSystems.getDefault().getPath(".", "tempCopy1.txt"); BufferedWriter bufferedWriter = Files.newBufferedWriter(filePath, charset); System.out.println(string); bufferedWriter.write(string, 0, string.length());
Stream File Read Write
Read File
Path filePath = FileSystems.getDefault().getPath(«.», «temp.txt»); InputStream inputStream = Files.newInputStream(filePath); BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream)); String line = null; while ((line = bufferedReader.readLine()) != null)
Write File
Path filePath = FileSystems.getDefault().getPath(".", "tempCopy2.txt"); OutputStream outputStream = new BufferedOutputStream( Files.newOutputStream(filePath, StandardOpenOption.CREATE, StandardOpenOption.APPEND)); outputStream.write(byteArray, 0, byteArray.length);
Simple NIO File Read Write
Before going into NIO channels lets see a simplistic NIO way to read write files. If you got a small file and just want to read it in one go, then use the readAllBytes from NIO Files API and similarly for write operation too.
// create a path for file named temp.txt from current folder Path filePath = FileSystems.getDefault().getPath(".", "temp.txt"); // read a complete file in one go as byte array // use this to read small files byte[] byteArray = Files.readAllBytes(filePath); Path fileCopy = FileSystems.getDefault().getPath(".", "tempCopy.txt"); Files.write(fileCopy, byteArray);
File Read with ByteChannel
We create an instance for byte channel using Files NIO utility class. Then we allocate a ByteBuffer using which the data will be read. rewind is used to read again the data it already contains. rewind sets the buffer position to zero. flip is used to prepare a buffer for get operation and makes it ready.
public static void byteChannelRead() throws IOException < Path filePath = FileSystems.getDefault().getPath(".", "temp.txt"); SeekableByteChannel byteChannel = Files.newByteChannel(filePath); ByteBuffer byteBuffer = ByteBuffer.allocate(10); Charset charset = Charset.forName("US-ASCII"); while (byteChannel.read(byteBuffer) >0) < byteBuffer.rewind(); System.out.print(charset.decode(byteBuffer)); byteBuffer.flip(); >>
File Write with ByteChannel
We set the options mode like create/append using StandardOpenOption and then write the buffer using the channel.
public static void byteChannelWrite(ByteBuffer byteBuffer) throws IOException < Setoptions = new HashSet(); options.add(StandardOpenOption.CREATE); options.add(StandardOpenOption.APPEND); Path file = Paths.get("./byByteChannel.txt"); SeekableByteChannel byteChannel = Files.newByteChannel(file, options); byteChannel.write(byteBuffer); >
File Read with FileChannel
ByteChannel and FileChannel usage are almost similar, the way we create the instances are little bit different.
public static void fileChannelRead() throws IOException < RandomAccessFile randomAccessFile = new RandomAccessFile("./temp.txt", "rw"); FileChannel fileChannel = randomAccessFile.getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(512); Charset charset = Charset.forName("US-ASCII"); while (fileChannel.read(byteBuffer) >0) < byteBuffer.rewind(); System.out.print(charset.decode(byteBuffer)); byteBuffer.flip(); >fileChannel.close(); randomAccessFile.close(); >
File Write with FileChannel
public static void fileChannelWrite(ByteBuffer byteBuffer) throws IOException < Setoptions = new HashSet(); options.add(StandardOpenOption.CREATE); options.add(StandardOpenOption.APPEND); Path path = Paths.get("./byFileChannel.txt"); FileChannel fileChannel = FileChannel.open(path, options); fileChannel.write(byteBuffer); fileChannel.close(); >
Example Channel File I/O Full Code
package com.javapapers.java.nio; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.SeekableByteChannel; import java.nio.charset.Charset; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.OpenOption; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.HashSet; import java.util.Set; public class JavaNIOReadWriteChannels < public static void main(String args[]) throws IOException < byteChannelRead(); String string = "foo bar"; byte[] byteArray = string.getBytes(); ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray); byteChannelWrite(byteBuffer); fileChannelRead(); fileChannelWrite(byteBuffer); >public static void byteChannelRead() throws IOException < Path filePath = FileSystems.getDefault().getPath(".", "temp.txt"); SeekableByteChannel byteChannel = Files.newByteChannel(filePath); ByteBuffer byteBuffer = ByteBuffer.allocate(10); Charset charset = Charset.forName("US-ASCII"); while (byteChannel.read(byteBuffer) >0) < byteBuffer.rewind(); System.out.print(charset.decode(byteBuffer)); byteBuffer.flip(); >> public static void byteChannelWrite(ByteBuffer byteBuffer) throws IOException < Setoptions = new HashSet(); options.add(StandardOpenOption.CREATE); options.add(StandardOpenOption.APPEND); Path file = Paths.get("./byByteChannel.txt"); SeekableByteChannel byteChannel = Files.newByteChannel(file, options); byteChannel.write(byteBuffer); > public static void fileChannelRead() throws IOException < RandomAccessFile randomAccessFile = new RandomAccessFile("./temp.txt", "rw"); FileChannel fileChannel = randomAccessFile.getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(512); Charset charset = Charset.forName("US-ASCII"); while (fileChannel.read(byteBuffer) >0) < byteBuffer.rewind(); System.out.print(charset.decode(byteBuffer)); byteBuffer.flip(); >fileChannel.close(); randomAccessFile.close(); > public static void fileChannelWrite(ByteBuffer byteBuffer) throws IOException < Setoptions = new HashSet(); options.add(StandardOpenOption.CREATE); options.add(StandardOpenOption.APPEND); Path path = Paths.get("./byFileChannel.txt"); FileChannel fileChannel = FileChannel.open(path, options); fileChannel.write(byteBuffer); fileChannel.close(); > >
Popular Articles
Reading a File with Channels and Buffers
Learn to read small and large files from the filesystem using the Java NIO APIs Path, FileChannel, ByteBuffer and MappedByteBuffer.
- We are using the RandomAccessFile instance that behaves like a large array of bytes stored in the file system. It uses file pointers that act as a cursor to maintain the current read location in the file.
- A ByteBuffer represents the buffered bytes in the memory during the read/write operations.
- A MappedByteBuffer is a direct byte buffer whose content is a memory-mapped region of a file.
1. Reading Small Files with ByteBuffer and FileChannel
Use this technique to read a small file. The idea is to create a ByteBuffer large enough where all the file content fits into the buffer, and the file can be read in a single read() operation.
try(RandomAccessFile aFile = new RandomAccessFile("test.txt", "r"); FileChannel inChannel = aFile.getChannel();) < long fileSize = inChannel.size(); //Create buffer of the file size ByteBuffer buffer = ByteBuffer.allocate((int) fileSize); inChannel.read(buffer); buffer.flip(); // Verify the file content for (int i = 0; i < fileSize; i++) < System.out.print((char) buffer.get()); >> catch (IOException e)
2. Reading Large Files with ByteBuffer and FileChannel
Use this technique to read a large file where all the file content will not fit into the buffer at a time. To avoid OutOfMemory issues, we can read the file in chunks with a fixed size small buffer.
try (RandomAccessFile aFile = new RandomAccessFile("test.txt", "r"); FileChannel inChannel = aFile.getChannel();) < //Buffer size is 1024 ByteBuffer buffer = ByteBuffer.allocate(1024); while (inChannel.read(buffer) >0) < buffer.flip(); for (int i = 0; i < buffer.limit(); i++) < System.out.print((char) buffer.get()); >buffer.clear(); // do something with the data and clear/compact it. > > catch (IOException e)
3. Reading a File using MappedByteBuffer
MappedByteBuffer extends the ByteBuffer class with operations that are specific to memory-mapped file regions.
try (RandomAccessFile aFile = new RandomAccessFile("test.txt", "r"); FileChannel inChannel = aFile.getChannel();) < MappedByteBuffer buffer = inChannel .map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); buffer.load(); for (int i = 0; i < buffer.limit(); i++) < System.out.print((char) buffer.get()); >buffer.clear(); // do something with the data and clear/compact it. > catch (IOException e)
All the above techniques will read the content of the file and print it to the console.