# FileInputStream

The *Java* *FileInputStream* class, `java.io.FileInputStream`, makes it possible to read the contents of a file as a stream of bytes. The Java `FileInputStream` class is a subclass of [Java InputStream](https://jenkov.com/tutorials/java-io/inputstream.html). This means that you use the Java `FileInputStream` as an `InputStream` (`FileInputStream` behaves like an `InputStream`).

### Java FileInputStream Example

Here is a simple `FileInputStream` example:

```
InputStream input = new FileInputStream("c:\\data\\input-text.txt");

int data = input.read();
while(data != -1) {
  //do something with data...
  doSomethingWithData(data);

  data = input.read();
}
input.close();
```

Note: The proper exception handling has been skipped here for the sake of clarity. To learn more about correct exception handling, go to [Java IO Exception Handling](https://jenkov.com/tutorials/java-io/io-exception-handling.html).

Note also, that since `FileInputStream` is a subclass of `InputStream`, we can cast the created `FileInputStream` to an `InputStream` everywhere we want to, as we do in the example above.

### FileInputStream Constructors

The `FileInputStream` class has a three different constructors you can use to create a `FileInputStream` instance. I will cover the first two here.

The first constructor takes a `String` as parameter. This `String` should contain the path in the file system to where the file to read is located. Here is a code example:

```
String path = "C:\\user\\data\\thefile.txt";

FileInputStream fileInputStream = new FileInputStream(path);
```

Notice the `path` `String`. It needs double backslashes (`\\`) to create a single backslash in the `String`, because backslash is an escape character in Java Strings. To get a single backslash you need to use the escape sequence `\\`.

On unix the file path could have looked like this:

```
String path = "/home/jakobjenkov/data/thefile.txt";
```

Notice the use of the for-slash (the normal slash character) as directory separator. That is how you write file paths on unix. Actually, in my experience Java will also understand if you use a `/` as directory separator on Windows (e.g. `c:/user/data/thefile.txt`), but don't take my word for it. Test it on your own system!

The second `FileInputStream` constructor takes a `File` object as parameter. The `File` object has to point to the file you want to read. Here is an example:

```
String path = "C:\\user\\data\\thefile.txt";
File   file = new File(path);

FileInputStream fileInputStream = new FileInputStream(file);
```

Which of the constructors you should use depends on what form you have the path in before opening the `FileInputStream`. If you already have a `String` or `File`, just use that as it is. There is no particular gain in converting a `String` to a `File`, or a `File` to a `String` first.

### read()

The `read()` method of a `FileInputStream` returns an `int` which contains the byte value of the byte read. If the `read()` method returns -1, there is no more data to read in the `FileInputStream`, and it can be closed. That is, -1 as int value, not -1 as byte value. There is a difference here!

You use the `read()` method just like the [`read()` method of an `InputStream`](https://jenkov.com/tutorials/java-io/inputstream.html). Here is an example of reading all data in a Java `FileInputStream` :

```
FileInputStream fileInputStream =
    new FileInputStream("c:\\data\\input-text.txt");


int data = fileInputStream.read();
while(data != -1) {
    // do something with data variable

    data = fileInputStream.read(); // read next byte
}
```

When the `while` loop terminates, all bytes have been read from the `FileInputStream`.

### read(byte\[])

Being an `InputStream` the `FileInputStream` also has two `read()` methods which can read data into a `byte` array. These methods are inherited from the [Java InputStream](https://jenkov.com/tutorials/java-io/inputstream.html) class, by the way. These methods are:

* `int read(byte[])`
* `int read(byte[], int offset, int length)`

The first method attempts to fill up the `byte` array passed as parameter to it with bytes from from the `FileInputStream`.

The second method attempts to read `length` bytes into the `byte` array, starting from cell `offset` in the `byte` array, and filling forward from there.

Both methods return the number of bytes actually read into the `byte` array. In case there are less bytes to read than what there is space for in the array, or less than you specified in the `length` parameter, less bytes will be read into the `byte` array. If all bytes have been read from the `FileInputStream`, these `read()` methods will return `-1`. Therefore it is necessary to inspect the value returned from these `read()` method calls.

Here is an example of calling one of the `read(byte[])` methods:

```
FileInputStream fileInputStream = new FileInputStream("c:\\data\\input-text.txt");

byte[] data      = new byte[1024];
int    bytesRead = fileInputStream.read(data, 0, data.length);

while(bytesRead != -1) {
  doSomethingWithData(data, bytesRead);

  bytesRead = fileInputStream.read(data, 0, data.length);
}
```

Notice that `read(data, 0, data.length)` is equivalent to `read(data)` .

The `doSomethingWithData()` method implementation has been left out of this example to keep it short. But - it represents any set of actions you want to carry out on the read data.

### Read Performance

Reading an array of bytes at a time is faster than reading a single byte at a time from a Java `FileInputStream`. The difference can easily be a factor 10 or more in performance increase, by reading an array of bytes rather than reading a single byte at a time.

The exact speedup gained depends on the size of the byte array you read, and the OS, hardware etc. of the computer you are running the code on. You should study the hard disk buffer sizes etc. of the target system before deciding. However buffer sizes of 8KB and up will give a good speedup. However, once your byte array exceeds the capacity of the underlying OS and hardware, you won't get a bigger speedup from a bigger byte array.

You will probably have to experiment with different byte array size and measure read performance, to find the optimal byte array size.

### Transparent Buffering via BufferedInputStream

You can add transparent, automatic reading and buffering of an array of bytes from a `FileInputStream` using a [Java BufferedInputStream](https://jenkov.com/tutorials/java-io/bufferedinputstream.html) . The `BufferedInputStream` reads a chunk of bytes into a byte array from the underlying `FileInputStream`. You can then read the bytes one by one from the `BufferedInputStream` and still get a lot of the speedup that comes from reading an array of bytes rather than one byte at a time. Here is an example of wrapping a Java `FileInputStream` in a `BufferedInputStream` :

```
InputStream input = new BufferedInputStream(
                      new FileInputStream("c:\\data\\input-file.txt"),
                        1024 * 1024        /* buffer size */
    );
```

Notice, that a `BufferedInputStream` is an `InputStream` subclass and can be used in any place where an `InputStream` can be used.

### Close a FileInputStream

When you are finished reading data from a Java `FileInputStream` you must close it. You close a `FileInputStream` by calling the `close()` method inherited from `InputStream`. Here is an example of opening a `FileInputStream`, reading all data from it, and then closing it:

```
FileInputStream fileInputStream = new FileInputStream("c:\\data\\input-text.txt");

int data = fileInputStream.read();
while(data != -1) {
  data = fileInputStream.read();
}
fileInputStream.close();
```

Notice how the `while` loop continues until a `-1` value is read from the `FileInputStream` `read()` method. After that, the while loop exits, and the `FileInputStream` `close()` method is called.

The above code is not 100% robust. If an exception is thrown while reading data from the `FileInputStream`, the `close()` method is never called. To make the code more robust, you will have to use the Java [Java try with resources](https://jenkov.com/java-exception-handling/try-with-resources.html) construct. Proper exception handling for use of Java IO classes is also explained in my tutorial on [Java IO Exception Handling](https://jenkov.com/tutorials/java-io/io-exception-handling.html).

Here is an example of closing a Java `FileInputStream` using the try-with-resources construct:

```
try( FileInputStream fileInputStream = new FileInputStream("file.txt") ) {

    int data = fileInputStream.read();
    while(data != -1){
        data = fileInputStream.read();
    }
}
```

Notice that the `FileInputStream` is declared inside the parentheses after the `try` keyword. This signals to Java that this `FileInputStream` is to be managed by the try-with-resources construct.

Once the executing thread exits the `try` block, the `FileInputStream` is closed. If an exception is thrown from inside the `try` block, the exception is caught, the `FileInputStream` is closed, and then the exception is rethrown. You are thus guaranteed that the `FileInputStream` is closed, when used inside a try-with-resources block.

### Convert FileInputStream to Reader

The Java `FileInputStream` is a byte based stream of data. As you may know, the Java IO API also has a character based set of input streams called "Readers". You can convert a Java `FileInputStream` to a Java `Reader` using the [Java InputStreamReader](https://jenkov.com/java-io/inputstreamreader.html). You can read more about how to use the `InputStreamReader` by clicking the link in the previous sentence, but here is a quick example of converting a Java `FileInputStream` to an `InputStreamReader`:

```
InputStream inputStream       = new FileInputStream("c:\\data\\input.txt");
Reader      inputStreamReader = new InputStreamReader(inputStream);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://amartyushov.gitbook.io/tech/programming-languages/java/io-nio/java-io-files/fileinputstream.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
