CodeGym /Java Course /Java Core /Streams for file I/O

Streams for file I/O

Java Core
Level 8 , Lesson 2
Available

"We'll start with streams for file input/output. But first things first."

There are two classes for reading and writing files: FileInputStream and FileOutputStream. As you probably already guessed, FileInputStream can sequentially read bytes from a file, and FileOutputStream can sequentially write bytes to a file. Here are the methods that these classes have:

Method What the method does
FileInputStream(String fileName);
— This is the constructor. It lets you specify the name of a file on disk, from which the created object will read data.
int read();
— This method reads one byte from the file and returns it. The return value is widened to an int.
int available();
— This method returns the number of unread (available) bytes.
void close();
— This method «closes» the stream. You call this when you're done working with the stream.
The object then performs the housekeeping operations needed to close the file, etc.
At this point, you can't read any more data from the stream.

Just for the fun of it, let's calculate the sum of all the bytes in a file. Here's what the code looks like:

Sum up all the bytes in a file
public static void main(String[] args) throws Exception
{
 //Create a FileInputStream object bound to «c:/data.txt».
 FileInputStream inputStream = new FileInputStream("c:/data.txt");
 long sum = 0;

 while (inputStream.available() > 0) //as long as there are unread bytes
 {
  int data = inputStream.read(); //Read the next byte
  sum +=  data; //Add it to the running total
 }
 inputStream.close(); // Close the stream

 System.out.println(sum); // Display the sum on the screen.
}

"We've already looked into something like this. How is FileOutputStream organized?"

"OK. Look at this:"

Method What the method does
FileOutputStream (String fileName);
"This is the constructor. It lets you specify the name of a file on disk, to which the created object will write data."
void write(int data);
"This method writes the next byte, truncating data to one byte."
void flush();
"The data to be written is often first collected in large blocks in memory, and then only written to disk."

The flush command forces all unsaved information to be written to disk.

void close();
"This method «closes» the stream. You call this when you're done working with the stream."
The object then performs the housekeeping operations needed to close the file, etc.

You can't write data to the stream any longer, and flush is called automatically.

"That's it?"

"Yep, there's actually only one method for writing: write(). It writes only one byte at a time. But it lets you write as much information as you want to the file."

Programming is a process of dividing one large and complex task into many small ones. Essentially the same process is happening here: reading and writing large blocks of data is broken into reading and writing in bite-sized pieces—one byte at a time.

Here's how you can use these classes to copy a file on disk:

Copy a file on disk
public static void main(String[] args) throws Exception
{
 //Create a stream to read bytes from a file
 FileInputStream inputStream = new FileInputStream("c:/data.txt");
 //Create a stream to write bytes to a file
 FileOutputStream outputStream = new FileOutputStream("c:/result.txt");

 while (inputStream.available() > 0) //as long as there are unread bytes
 {
  int data = inputStream.read(); // Read the next byte into the data variable
  outputStream.write(data); // and write it to the second stream
 }

 inputStream.close(); //Close both streams. We don't need them any more.
 outputStream.close();
}

"Thanks, Rishi. I finally understand how this code actually works."

Comments (13)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Kent Hervey Level 19, United States Expert
9 November 2023
Is this right? sum += data; //Add it to the running total or should it be sum++ since we are getting the total number of bytes...not the actual bytes?
TheLordJackMC Level 39, Princeton, idk somewhere
18 July 2021
wierd how we're only learning from one person at a time
Collin M Level 22, Germiston, South Africa
2 October 2020
This lecture was very clear and very well presented. I love CodeGym!
Seferi Level 22, United Federation of Planets
4 October 2020
Just curious, you wrote this comment on 2nd of October as level 18 and today is 4th of October and you are level 22. Did you really advance 4 levels in two days ? Way to go mate!
Collin M Level 22, Germiston, South Africa
6 October 2020
😄! I can't do that in two days my friend, I joined CodeGmy in September 2018 and I left it January 2019 at level 20, at that time Java Collections and Multithreading Quests were in development so I couldn't go any further. So I came back last month and somehow I'm reviewing concepts in the java core quest.
Collin M Level 22, Germiston, South Africa
6 October 2020
If you can check my profile, you will see that my rating is very low, simply because there were no rating feature by then.
Henrique Level 41, São Paulo, Brazil
17 June 2020
What does "read into" mean? Is it the same as "read from", or is it something different? My mother tongue is not English, so I'm not fully understanding this language construction... Thanks.
Henk Level 19, Pretoria, South-Africa
1 June 2019
just not sure why it assumes the read byte is a number, not a character (why does it assume it's an Int ?). I am obviously missing something here ? Is it the ASCII representation of the character that it reads ?
robin Level 23, Lublin, Poland
3 June 2019
The input stream is reading bytes, which, in turn, consist of bits, which are basically 0s and 1s :) I believe this is why they decided to use int to represent these.
Ed Maphis Level 20, Painesville, United States
17 June 2019
The functions read bytes into ints. So the ints are still the same "number" as the byte.
Gellert Varga Level 23, Szekesfehervar, Hungary
10 June 2021
InputStream classes read bytes (not characters). Bytes are always just numbers, between 0 and 255 (or between -128 and 127.) What a byte means is a matter of separate agreement (encoding).The same byte can be part of a character, part of an image, or part of a video file, etc. If we consider text characters, there are many different character encodings. At first, only the 128 most important characters were coded = ASCII. At that time, a single byte meant one character. This table was soon to be extended to 256 characters. Still a single byte represents a single character. But because of the different characters in different languages, many such code tables had to be made. You always had to say in advance which one you were using. For example, LATIN-1 (for Western languages), LATIN-2: for Central European languages, WINDOWS-1251: for Cyrillic languages, ISO-8859-6: arabic, etc. The same byte can mean a different character in one table and a different character in another! This caused a lot of problems, so it had to be standardised worldwide. The most common character encoding is UTF-8. It has a variable byte length. Basic characters are transmitted in 1 byte. Sometimes it uses 2 bytes to represent a character, but it is able to encode any of the 65536 base characters (from the base Unicode table) in maximum 3 bytes. UTF-16 is also a variable length (2 bytes or 4 bytes) character encoding method. It can distinguish more than 1 million different characters. UTF-32 character encoding always uses 4 bytes for each character, even the simplest ones (which UTF-8 can solve with 1 byte). Overall, in the simplest case, a single byte can represent a complete character, but in many cases, several bytes must be scanned to get all the information of a single character. Reader classes make things easier, they read characters, not bytes. (They know how many bytes must be read to get a single character.)
matemate123 Level 50, Kraków, Poland
19 January 2023
Thanks man, it’s very intresting and informative comment
Aakash potepalli Level 22, Bangalore, India
27 April 2019
awesome