eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

Partner – LambdaTest – NPI EA (cat= Testing)
announcement - icon

Distributed systems often come with complex challenges such as service-to-service communication, state management, asynchronous messaging, security, and more.

Dapr (Distributed Application Runtime) provides a set of APIs and building blocks to address these challenges, abstracting away infrastructure so we can focus on business logic.

In this tutorial, we'll focus on Dapr's pub/sub API for message brokering. Using its Spring Boot integration, we'll simplify the creation of a loosely coupled, portable, and easily testable pub/sub messaging system:

>> Flexible Pub/Sub Messaging With Spring Boot and Dapr

1. Overview

In this quick tutorial, we’ll look at the FileChannel class provided in the Java NIO library. We’ll discuss how to read and write data using FileChannel and ByteBuffer.

We’ll also explore the advantages of using FileChannel and some of its other file manipulation features.

2. Advantages of FileChannel

The advantages of FileChannel include:

  • Reading and writing at a specific position in a file
  • Loading a section of a file directly into memory, which can be more efficient
  • We can transfer file data from one channel to another at a faster rate
  • We can lock a section of a file to restrict access by other threads
  • To avoid data loss, we can force writing updates to a file immediately to storage

3. Reading with FileChannel

FileChannel performs faster than standard I/O when we read a large file.

We should note that although part of Java NIO, FileChannel operations are blocking and do not have a non-blocking mode.

3.1. Reading a File Using FileChannel

Let’s understand how to read a file using FileChannel on a file that contains:

Hello world

This test reads the file and checks it was read ok:

@Test
public void givenFile_whenReadWithFileChannelUsingRandomAccessFile_thenCorrect() 
  throws IOException {
    try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r");
        FileChannel channel = reader.getChannel();
        ByteArrayOutputStream out = new ByteArrayOutputStream()) {

        int bufferSize = 1024;
        if (bufferSize > channel.size()) {
           bufferSize = (int) channel.size();
        }
        ByteBuffer buff = ByteBuffer.allocate(bufferSize);

        while (channel.read(buff) > 0) {
            out.write(buff.array(), 0, buff.position());
            buff.clear();
        }
        
     String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8);
 
     assertEquals("Hello world", fileContent);
    }
}

Here we read bytes from the file using FileChannel, RandomAccessFile, and ByteBuffer.

We should also note that multiple concurrent threads can use FileChannels safelyHowever, only one thread at a time is allowed an operation that involves updating a channel’s position or changing its file size. This blocks other threads attempting a similar operation until the previous operation completes.

However, operations that provide explicit channel positions can run concurrently without being blocked.

3.2. Opening a FileChannel

In order to read a file using FileChannel, we must open it.

Let’s see how to open a FileChannel using RandomAccessFile:

RandomAccessFile reader = new RandomAccessFile(file, "r");
FileChannel channel = reader.getChannel();

Mode ‘r’ indicates that the channel is ‘open for reading’ only. We should note that closing a RandomAccessFile will also close the associated channel.

Next, we’ll see opening a FileChannel to read a file using FileInputStream:

FileInputStream fin= new FileInputStream(file);
FileChannel channel = fin.getChannel();

Similarly, closing a FileInputStream also closes the channel associated with it.

3.3. Reading Data from a FileChannel

To read the data, we can use one of the read methods.

Let’s see how to read a sequence of bytes. We’ll use a ByteBuffer to hold the data:

ByteBuffer buff = ByteBuffer.allocate(1024);
int noOfBytesRead = channel.read(buff);
String fileContent = new String(buff.array(), StandardCharsets.UTF_8);

assertEquals("Hello world", fileContent);

Next, we’ll see how to read a sequence of bytes, starting at a file position:

ByteBuffer buff = ByteBuffer.allocate(1024);
int noOfBytesRead = channel.read(buff, 5);
String fileContent = new String(buff.array(), StandardCharsets.UTF_8);
assertEquals("world", fileContent);

We should note the need for a Charset to decode a byte array into String.

We specify the Charset with which the bytes were originally encoded. Without it, we may end up with garbled text. In particular, multi-byte encodings like UTF-8 and UTF-16 may not be able to decode an arbitrary section of the file, as some of the multi-byte characters may be incomplete.

4. Writing with FileChannel

4.1. Writing into a File Using FileChannel

Let’s explore how to write using FileChannel:

@Test
public void whenWriteWithFileChannelUsingRandomAccessFile_thenCorrect()   
  throws IOException {
    String file = "src/test/resources/test_write_using_filechannel.txt";
    try (RandomAccessFile writer = new RandomAccessFile(file, "rw");
        FileChannel channel = writer.getChannel()){
        ByteBuffer buff = ByteBuffer.wrap("Hello world".getBytes(StandardCharsets.UTF_8));
 
        channel.write(buff);
 
     // verify
     RandomAccessFile reader = new RandomAccessFile(file, "r");
     assertEquals("Hello world", reader.readLine());
     reader.close();
    }
}

4.2. Opening a FileChannel

In order to write into a file using FileChannel, we must open it.

Let’s see how to open a FileChannel using RandomAccessFile:

RandomAccessFile writer = new RandomAccessFile(file, "rw");
FileChannel channel = writer.getChannel();

Mode ‘rw’ indicates that the channel is ‘open for reading and writing’.

Let’s also see how to open a FileChannel using FileOutputStream:

FileOutputStream fout = new FileOutputStream(file);
FileChannel channel = fout.getChannel();

4.3. Writing Data with FileChannel

To write data with a FileChannel, we can use one of the write methods.

Let’s see how to write a sequence of bytes, using a ByteBuffer to store the data:

ByteBuffer buff = ByteBuffer.wrap("Hello world".getBytes(StandardCharsets.UTF_8));
channel.write(buff);

Next, we’ll see how to write a sequence of bytes, starting at a file position:

ByteBuffer buff = ByteBuffer.wrap("Hello world".getBytes(StandardCharsets.UTF_8));
channel.write(buff, 5);

5. Current Position

FileChannel allows us to get and change the position at which we are reading or writing.

Let’s see how to get the current position:

long originalPosition = channel.position();

Next, let’s see how to set the position:

channel.position(5);
assertEquals(originalPosition + 5, channel.position());

6. Get the Size of a File

Let’s see how to use the FileChannel.size method to get the size of a file in bytes:

@Test
public void whenGetFileSize_thenCorrect() 
  throws IOException {
    RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r");
    FileChannel channel = reader.getChannel();

    // the original file size is 11 bytes.
    assertEquals(11, channel.size());

    channel.close();
    reader.close();
}

7. Truncate a File

Let’s understand how to use the FileChannel.truncate method to truncate a file to given size in bytes:

@Test
public void whenTruncateFile_thenCorrect() 
  throws IOException {
    String input = "this is a test input";

    FileOutputStream fout = new FileOutputStream("src/test/resources/test_truncate.txt");
    FileChannel channel = fout.getChannel();

    ByteBuffer buff = ByteBuffer.wrap(input.getBytes());
    channel.write(buff);
    buff.flip();

    channel = channel.truncate(5);
    assertEquals(5, channel.size());

    fout.close();
    channel.close();
}

8. Force File Update into Storage

An operating system may cache file changes for performance reasons, and data may be lost if the system crashes. To force file content and metadata to write to disk continuously we can use the force method:

channel.force(true);

This method is guaranteed only when the file resides on a local device.

9. Load a Section of a File into Memory

Let’s see how to load a section of a file in memory using FileChannel.map. We use FileChannel.MapMode.READ_ONLY to open the file in read-only mode:

@Test
public void givenFile_whenReadAFileSectionIntoMemoryWithFileChannel_thenCorrect() 
  throws IOException { 
    try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r");
        FileChannel channel = reader.getChannel();
        ByteArrayOutputStream out = new ByteArrayOutputStream()) {

        MappedByteBuffer buff = channel.map(FileChannel.MapMode.READ_ONLY, 6, 5);

        if(buff.hasRemaining()) {
          byte[] data = new byte[buff.remaining()];
          buff.get(data);
          assertEquals("world", new String(data, StandardCharsets.UTF_8));	
        }
    }
}

Similarly, we can use FileChannel.MapMode.READ_WRITE to open the file into both read and write mode.

We can also use FileChannel.MapMode.PRIVATE mode, where changes do not apply to the original file.

10. Lock a Section of a File

Let’s understand how to lock a section of a file to prevent concurrent access of a section using the FileChannel.tryLock method:

@Test
public void givenFile_whenWriteAFileUsingLockAFileSectionWithFileChannel_thenCorrect() 
  throws IOException { 
    try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "rw");
        FileChannel channel = reader.getChannel();
        FileLock fileLock = channel.tryLock(6, 5, Boolean.FALSE )){
 
        //do other operations...
 
        assertNotNull(fileLock);
    }
}

The tryLock method attempts to acquire a lock on the file section. If the requested file section is already blocked by another thread, it throws an OverlappingFileLockException exception. This method also takes a boolean parameter to request either a shared lock or an exclusive lock.

We should note that some operating systems may not allow a shared lock, defaulting instead to an exclusive lock.

11. Closing a FileChannel

Finally, when we are done using a FileChannel, we must close it. In our examples we have used try-with-resources.

If necessary, we can close the FileChannel directly with the close method:

channel.close();

12. Conclusion

In this tutorial, we’ve seen how to use FileChannel to read and write files. In addition, we’ve explored how to read and change the file size and its current read/write location and looked at how to use FileChannels in concurrent or data critical applications.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

eBook Jackson – NPI EA – 3 (cat = Jackson)