By Md. Sabuj Sarker | 8/24/2017 | General |Beginners

Working With Files in Java

Working With Files in Java

Almost every real life Java application interacts with the file system. Files are the most convenient way of handling input and output. Every computer program revolves around the concepts of input, processing, and output. We can take input from a file, process it and save the output to another file. Every Java programmer should have knowledge of working with files and the file system. Java provides many APIs for working with files and the file system. In this article we are going to use classes from the java.io package. This package contains all the classes to interact with file I/O. There is another package called java.nio that I would like to discuss in a future article.

To start, use whatever IDE you like and create a Java project for practicing the code discussed in this article. Create a public class with the main method in it. I am going to name the class as JavaInputOutput but you are free to name it whatever you like.

import java.io.*;

public class JavaInputOutput {
   public static void main(String[] args){

   }
}

I have imported all the classes from the java.io package as wildcard import. In the examples I am going to import every class individually to avoid any type of ambiguity.

Files and Paths in Java

Operating systems distinguish every file in the system by path name. On Windows systems an absolute path name starts with a drive letter, but on Unix systems it starts with a forward slash. Path names can also be resolved relatively. For example, if you have a file called info.txt inside the current working directory then you can refer to it by info.txt instead of providing its full path like C:\Users\DiscoverSDK\MyJavaProgram\info.txt. When the file is not in the current working directory or under any sub-directory inside the current working directory then you must provide the full path name to work on it. As the directory separator, Windows uses the backward slash \ and Unix systems use the forward slash /. In Java you do not need to worry much about that, because Java handles cross platform issues automatically most of the time.

To abstract the OS file and directory paths, Java provides a class called File. Do not get confused with the name File—it abstracts both file and directory path. The File class resolves relative file/directory names according to the current user directory. The current user directory is the directory from which the JVM is invoked when executing the java application. So, usually it is the current working directory.

Let's create a File object by providing a relative path as a string.

import java.io.File;

public class JavaInputOutput {
   public static void main(String[] args){
       File fInfo = new File("info.txt");
   }

}

 

Checking Existence of a File

If we work randomly and blindly on the file system, we may lose valuable data or our program may crash. A whole bunch of other things may also happen. Often times we need to check whether some file exists or not. To check for the existence of a file, the File class provides a convenient method called exists(). Currently I do not have a file called info.txt in the directory from where I am running this Java application.

import java.io.File;

public class JavaInputOutput {
   public static void main(String[] args){
       File fInfo = new File("info.txt");

       if (fInfo.exists()) {
           System.out.println("info.txt exists");
       }else {
           System.out.println("info.txt does not exist");
       }
   }
}

Output:

info.txt does not exist

Now, create an empty text file with the file name inside the directory from where you are running your Java program. In other words, create info.txt in the current working directory. Hit 'build' and run the program again to see the following output.

info.txt exists

 

Listing a Directory

Often, we need to list a directory for listing files and subdirectories for processing them or for other purposes. The File class has a method called list() to list a directory. I am going to create a directory called 'MyDir' inside the current working directory and populate the directory with some dummy files and folders to test our code.

import java.io.File;

public class JavaInputOutput {
   public static void main(String[] args){
       File fInfo = new File("MyDir");

       String[] files = fInfo.list();

       for (String fileOrDirName: files) {
           System.out.println(fileOrDirName);
       }
   }
}

 

Output:

dir1
dir2
file1.txt
filex

 

Stream and Java I/O

Most parts of the I/O system in Java revolves around the concept of stream. The I/O can be file I/O, network I/O, console I/O or something else. Stream in Java means flow of data. The data can be binary data or text data. Think of stream like the flow of water through pipes or as a waterfall. But instead of water, in Java the flow is of data. In the following sections we are going to read and write files based on the concept of streams.

Every class based on the concept of stream has some methods related to reading and writing data along with closing the stream. They may also have ways to read data line by line. We will get acquainted with some of them in our code examples.

Reading Binary Files

Any type of file can be considered as a binary file. Because, to the file system there are only bytes in files. We abstract bytes as character, string, integer, etc. in Java. Even a plain text file is made with bytes. We abstract the bytes as other types of data for our convenience.

Let's edit the info.txt file with a text file editor and put the following programming joke inside it.

3 Database SQL walked into a noSQL bar.
A little while later...
They walked out Because they COULDN'T FIND A TABLE


To read a file we need to use the FileIntputStream class from java.io class.

import java.io.File;
import java.io.FileInputStream;

public class JavaInputOutput {
   public static void main(String[] args) throws Exception{
       File fInfo = new File("info.txt");
       FileInputStream fin = new FileInputStream(fInfo);

       int i;
       while( (i = fin.read())  != -1 ){
           System.out.print((char)i);
       }
   }
}

Output:

3 Database SQL walked into a noSQL bar.
A little while later...
They walked out Because they COULDN'T FIND A TABLE

I have avoided all types of exceptions by using throws Exception on the main method. On production systems you are advised to handle specific exceptions and take actions accordingly. When you are learning, it is alright avoiding exceptions this way.

There are many methods to get data more efficiently. I have shown you the most fundamental way of getting the data from a FileInputStream.

Reading Text Files

In binary mode we get one byte as a unit of data. But in the modern world we have lots of languages all over the world. A byte can represent at most 256 types of characters and thus is unable to represent characters from all the human languages. Java solved this problem from its birth. It provides 16 bit character and thus every character in a string is also 16 bit. So, if we have non-ASCII characters in our text files we have to read that in text mode so that we do not lose the meaning of our characters. In Java's java.io package we have a class called FileReader that gives us a way to read character or text data instead of binary data.

import java.io.File;
import java.io.FileReader;

public class JavaInputOutput {
   public static void main(String[] args) throws Exception{
       File fInfo = new File("info.txt");
       FileReader fin = new FileReader(fInfo);

       int i;
       while( (i = fin.read())  != -1 ){
           System.out.print((char)i);
       }
   }
}

The output is the same as before. Instead of reading each character separately, you can read many characters at a time by using a character buffer array.

Writing Binary Files

I am going to write to a file that does not exist in the file system. Let's call it info2.txt. When the FileOutputStream sees that that file is nonexistent, it will create a file with that name.

import java.io.File;
import java.io.FileOutputStream;

public class JavaInputOutput {
   public static void main(String[] args) throws Exception{
       File fInfo = new File("info2.txt");
       FileOutputStream fout = new FileOutputStream(fInfo);

       // data
       String joke = "3 Database SQL walked into a noSQL bar.\n" +
               "A little while later...\n" +
               "They walked out Because they COULDN'T FIND A TABLE";
       fout.write(joke.getBytes("UTF-8"));
       fout.close();
   }
}

Now, check your current working directory and open the new file to see the content and verify it. We converted string to bytes before writing by invoking the getBytes() method on the string. We provided our expected encoding name as the argument.

Writing Text Files

We discussed in the file reading section the importance of text files. Here we are just going to see the examples of how to write text files. To write text files, we need to use FileWriter class from java.io package.

import java.io.File;
import java.io.FileWriter;

public class JavaInputOutput {
   public static void main(String[] args) throws Exception{
       File fInfo = new File("info3.txt");
       FileWriter fout = new FileWriter(fInfo);

       // data
       String joke = "3 Database SQL walked into a noSQL bar.\n" +
               "A little while later...\n" +
               "They walked out Because they COULDN'T FIND A TABLE";
       fout.write(joke);
       fout.close();
   }
}

Notice that we did not need to transform the string to bytes using this class.

Java has a lot of classes for working with input/output for both files and network i/o. Every class contains a lot of methods. In this article I tried to provide you a good lesson on how to start your journey to working with files. You are advised to read the official documentations and practice accordingly.

By Md. Sabuj Sarker | 8/24/2017 | General

{{CommentsModel.TotalCount}} Comments

Your Comment

{{CommentsModel.Message}}

Recent Stories

Top DiscoverSDK Experts

User photo
3355
Ashton Torrence
Web and Windows developer
GUI | Web and 11 more
View Profile
User photo
3220
Mendy Bennett
Experienced with Ad network & Ad servers.
Mobile | Ad Networks and 1 more
View Profile
User photo
3060
Karen Fitzgerald
7 years in Cross-Platform development.
Mobile | Cross Platform Frameworks
View Profile
Show All
X

Compare Products

Select up to three two products to compare by clicking on the compare icon () of each product.

{{compareToolModel.Error}}

Now comparing:

{{product.ProductName | createSubstring:25}} X
Compare Now