Java

How to Read From a Local File in Java

A local file is in the hard drive or a flash drive attached to the USB port. Files can be classified into two categories: text files and byte files. Typical text files are files created by a text editor. The image file is an example of a byte file consisting mainly of raw bytes.

This article gives a basic explanation of how to read local text and byte files in Java. To read a text file, use the class, FileReader. To read a byte file, use the class, FileInputStream. Both classes are in the java.io.* package, which should be imported. The first half of this article deals with reading text files, and the second half deals with the reading of byte files.

Reading Text Files

Constructing a FileReader Object

Before learning how to construct a FileReader object, create the following text file, with a text editor and press the Enter Key at the end of the first two lines:

A text 1 A text 1 A text 1 A text 1 A text 1

B text 2 B text 2 B text 2 B text 2 B text 2

C text 3 C text 3 C text 3 C text 3 C text 3

If the Enter Key is not pressed at the end of the last line, the text editor may add a newline when the file is saved. After producing the previous text, save the content, with the name temp.txt, using the text editor menu, [email protected]:~/dir1$, into the directory. This means the directory, dir1, should have been created.

Constructing a File Reader

The FileReader class has five constructors. Only one is illustrated in this article (in order to keep the article short). The syntax for the constructor is:

public FileReader(String fileName) throws FileNotFoundException

This is created in the memory a stream (copy) of the file, whose path and name is the string, fileName. It throws a FileNotFoundException if the file is not found in the directory indicated. After copying the file content, the opened file object has to be closed to release any system resources associated with the opened file.

Important Methods of FileReader

If the constructor is successfully created, then the file is considered open. After using the file, the file has to be closed. The syntax to close a file is:

public void close() throws IOException

After the file has just been opened, effective reading of the file has not yet occurred. To read one character at a time (one then the next), employ the syntax of the FileReader method:

public int read() throws IOException

This returns the character (as integer) read or -1 if the end of the stream (file copy flow in memory) has been reached.

To read the next sequence of characters of the file, into an array, employ the syntax of the FileReader method:

public int read(char[] cbuf, int off, int len) throws IOException

It returns the number of characters read or -1 if the end of the stream was reached. Off in the syntax means offset. It is the index in the file where the reading of the following sequence of characters is to start. Len is the number of characters to read. It should be the length of the array, while cbuf is the array the sequence of characters are read into.

Remember that the FileReader object has to be closed with its close method after this effective reading.

The syntax of the method, to know if the next read will not return -1, is:

public boolean ready() throws IOException

It returns true if there is something to be read and false otherwise.

Reading Into a String

The following code, reads the previous file, character-by-character, into a StringBuilder string:

            StringBuilder sb = new StringBuilder();
try{
FileReaderfr = new FileReader("dir1/temp.txt");

                while (fr.ready()) {          
                    char ch = (char)fr.read();
sb.append(ch);
                }
            }
catch(Exception e) {
e.getMessage();
            }
System.out.println(sb);

The code begins with the instantiation of a StringBuilder object, sb. Then, there is the try-catch construct. The try-block starts with the instantiation of the FileReader, fr. And there is the while-loop, which iterates until ready() returns false. The first statement in the while-loop reads and returns the next character as an integer. It has to be cast to char. The next statement in the while-loop appends the next character to the string, sb. The output is:

A text 1 A text 1 A text 1 A text 1 A text 1

B text 2 B text 2 B text 2 B text 2 B text 2

C text 3 C text 3 C text 3 C text 3 C text 3

It is exactly the file’s content, but it added an extra line in the author’s computer.

Reading Into an Array

When reading into an array, the content of the array has to be released, for the next sequence of characters to be read. The following code illustrates this:

            StringBuilder sb = new StringBuilder();
try{
FileReaderfr = new FileReader("dir1/temp.txt");

                while (fr.ready()) {    
char[] arr = new char[5];
                    int offset = 0;
fr.read(arr, offset, 5);
                    offset = offset + 5;
System.out.print(arr);
                }
            }
catch(Exception e) {
e.getMessage();
            }
System.out.println();

The value of offset has to be incremented for each iteration by the length of the array. The output is:

A text 1 A text 1 A text 1 A text 1 A text 1

B text 2 B text 2 B text 2 B text 2 B text 2

C text 3 C text 3 C text 3 C text 3 C text 3

It is exactly as the content of the file, but it added extra line, in the author’s computer.

Reading Byte Files

Constructing a FileInputStream Object

The following image file is called bars.png. It is in the directory [email protected]:~/dir1$, which is the same directory as temp.txt. It consists of just three color bars:

Constructing a FileInputStream

A constructor for a FileInputStream object is:

Since it throws an exception, it should be in a try-catch construct. Remember that this class is for reading bytes.

Important Methods of FileInputStream

If the constructor is successfully created, then the file is considered open. After reading the bytes, the file has to be closed, employing the following syntax:

public void close() throws IOException

After the file has just been opened, effective reading of the file has not yet occurred. To read one byte at a time (one then the next), employ the syntax of the FileInputStream method:

public int read() throws IOException

This returns the byte (as integer) read, or -1 if the end of the stream (file copy flow in memory) has been reached.

Remember that after this effective reading, the FileInputStream object has to be closed, with its close method.

To have an estimate of the number of bytes remaining to be read, employ the method syntax:

public int available() throws IOException

Since this method returns an estimate, when used in conjunction with read(), one cannot be sure that all the bytes of the file have been read. And the following method that reads all the bytes should be preferred:

public byte[] readAllBytes() throws IOException

This method returns all remaining bytes but would still read the whole file.

Reading Into an ArrayList

The ArrayList has to be imported from the java.util.* package. The following code reads an estimate of all the bytes into an ArrayList object:

ArrayList al = new ArrayList();
try{
FileInputStream fir = new FileInputStream("dir1/bars.png");

                while (fir.available() > 0) {          
                    byte bt = (byte)fir.read();
al.add(bt);
                }
            }
catch(Exception e) {
e.getMessage();
            }
System.out.println(al);

The code begins with the instantiation of an ArrayList object, al. Then, there is the try-catch construct. The try-block begins with the instantiation of the FileInputStream, fir. And there is the while-loop, which iterates until available() and suggests that no byte is left to be read. The first statement in the while-loop reads and returns the next byte as an integer. It has to be cast to a byte. The next statement in the while-loop appends (adds) the next character to the list, al. The output is:

[-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, -7, 0, 0, 0, -10, 8, 6, 0, 0, 0, 20, 25, 33, 69, 0, 0, 0, 6, 98, 75, 71, 68, 0, -1, 0, -1, 0, -1, -96, -67, -89, -109, 0, 0, 3, 48, 73, 68, 65, 84, 120, -100, -19, -42, 49, 74, 67, 81, 0, 68, -47, -81, -68, 52, 105, 83, -120, 85, 42, 65, -112, -12, 41, 44, 92, 64, -74, -26, 34, 92, -110, -115, -107, 32, -23, -19, 44, 4, 9, -60, 85, 60, 62, 92, -50, 89, -63, 52, 23, -26, -26, -70, 44, -41, 5, 104, 58, -99 - - - and continues - - - ]

Bytes are integers. Hopefully, the image of the previous three bars consists of all these bytes. The idea is for the programmer to change some of the bytes, modify the image, and then save the result; then re-display it with the image-viewer while presenting a modified picture. However, this extra schedule is not addressed in this article.

Reading Into an Array

The readAllBytes() method returns an array of bytes. So, just receive the return values, with a byte array, as the following code shows:

byte[] arr = new byte[1000];
try{
FileInputStream fir = new FileInputStream("dir1/bars.png");

arr = fir.readAllBytes();
            }
catch(Exception e) {
e.getMessage();
            }

            for (int i=0; i<arr.length; i++)
System.out.print(arr[i] + ", ");
System.out.println();

The code begins with the declaration of the array that will receive the bytes. The size (length) here should be above the estimated size. The estimated size can be obtained with the available() method. The principal code is in the try-block. The output is:

-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, -7, 0, 0, 0, -10, 8, 6, 0, 0, 0, 20, 25, 33, 69, 0, 0, 0, 6, 98, 75, 71, 68, 0, -1, 0, -1, 0, -1, -96, -67, -89, -109, 0, 0, 3, 48, 73, 68, 65, 84, 120, -100, -19, -42, 49, 74, 67, 81, 0, 68, -47, -81, -68, 52, 105, 83, -120, 85, 42, 65, -112, -12, 41, 44, 92, 64, -74, -26, 34, 92, -110, -115, -107, 32, -23, -19, 44, 4, 9, -60, 85, 60, 62, 92, -50, 89, -63, 52, 23, -26, -26, -70, 44, -41, 5, 104, 58, -99, - - - and continues - - -

This output and the previous one are the same on the author’s computer.

Conclusion

Local text and byte files can be read. To read a text file, use the stream class, FileReader. To read a byte file, use the stream class, FileInputStream. Both classes are in the java.io.* package, which should be imported. These two classes have constructors and methods that enable reading. We hope you found thid article helpful. Check out other Linux Hint articles for more tips and tutorials.

About the author

Chrysanthus Forcha

Discoverer of mathematics Integration from First Principles and related series. Master’s Degree in Technical Education, specializing in Electronics and Computer Software. BSc Electronics. I also have knowledge and experience at the Master’s level in Computing and Telecommunications. Out of 20,000 writers, I was the 37th best writer at devarticles.com. I have been working in these fields for more than 10 years.