devxlogo

Working with Files and I/O in Java

Working with Files and I/O in Java

The java.nio package contains the types required to perform input output operations in Java. The introduction of the java.nio package has simplified input — output operations. This article presents a discussion on how to perform input — output operations in Java with special focus on the java.nio package.

When you work with files for I/O, you basically work with streams. A stream may be defined as a sequence of bytes. There are two types of streams. These include: input stream and output stream. While the former is used to read data from a source, the latter is used to write data to a destination.

The Java NIO Package

Input/output operations in Java have been simplified and made non-blocking with the new java.nio.file API. The java.nio package comprises a collection of types that provide support for non-blocking I/O in Java. Incidentally, the Java NIO package was introduced with J2SE 1.4 in 2002. Note that the java.nio package provides support for implementing high-speed input-output sans the need of writing custom native code.

When working with enterprise applications, you might want to be notified when a file is updated or uploaded to a destination. The Java NIO API provides excellent support for change notification and change detection to handle such situations.

The Java NIO API comprises of the following:

  • Buffers – this represents a chunk of memory into which data can be written to read the data back at a later point of time if needed.
  • Charsets – these are comprised of encoders and decoders
  • Selectors – these provide support for multiplexed non-blocking I/O. A Selector is responsible for enabling a thread to select the appropriate Channel from amongst the list of registered Channels.
  • Channels – these represent a medium that can be used to transport data between the byte buffers and entities. Each source of data is mapped using an appropriate Channel. Typical examples of channels include: FileChannel, AsynchronousFileChannel, AsynchronousSocketChannel, etc.

You can learn more about the Java NIO API here.

Why do we need non-blocking I/O?

Let’s now understand why we need non-blocking I/O, or, why it is helpful. In blocking I/O, when you perform a read or a write operation, the worker thread is blocked until the input – output operation is complete. In other words, the worker thread is blocked until the read or write operation completes. On the contrary, in non-blocking I/O, your program doesn’t have to wait until the I/O is complete. In essence, the program continues to execute without having to block and wait till the I/O is complete. This boosts the application’s responsiveness and performance.

Here’s how non-blocking I/O in the java.nio package works. The I/O operation executes in parallel using another thread while the calling thread continues to execute its instructions.

Programming the java.nio package

In this section, we will explore how to program the java.nio package to read and write data. The following piece of code shows how you can write data using the java.nio package. Note how the Charset class has been used with UTF-8 encoding to specify the encoding to be used.

public static void main(String[] args) {        BufferedWriter bufferedWriter  = null;        try{            Path file = Files.createFile(Paths.get("C:\sample.txt"));            String text = "This is a test";             bufferedWriter = Files.newBufferedWriter(file, Charset.forName("UTF-8"));            bufferedWriter.write(text, 0, text.length());         }catch(IOException e){            e.printStackTrace();        }finally{            try {                bufferedWriter.close();            } catch (IOException x) {                x.printStackTrace();            }        }     }

The instance of the BufferedWriter is closed in the final block. The appropriate exception handling mechanism is incorporated to handle any runtime errors. The Files class contains a list of static methods that you can use to work with files, directories, etc.

Here’s the complete code listing for your reference.

import java.io.BufferedWriter;import java.io.IOException;import java.nio.charset.Charset;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;public class ProgrammingNIO {    public static void main(String[] args) {        BufferedWriter bufferedWriter  = null;        try{            Path file = Files.createFile(Paths.get("C:\sample.txt"));            String text = "This is a test";             bufferedWriter = Files.newBufferedWriter(file, Charset.forName("UTF-8"));            bufferedWriter.write("This is a test", 0, text.length());         }catch(IOException e){            e.printStackTrace();        }finally{            try {                bufferedWriter.close();            } catch (IOException x) {                x.printStackTrace();            }        }     }}

If you were to read the contents of a file, you would have to use the BufferedReader class. The following code snippet illustrates how it can be achieved.

InputStream stream = Files.newInputStream(file);bufferedReader = new BufferedReader(new InputStreamReader(stream));System.out.println(bufferedReader.readLine());
devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist