From System.in to Files: Java I/O Clarified
What you will get after reading this !
- Java i/o (past -> present)
- how data flows ? (keyboard -> memory -> file -> object)
- decoding why new stream layers are introduced
- decorator patternnn in java world !!
- byte vs character vs object streamssss !!
- how System.in and System.out connect with this ?
CHAPTER 1 :- The Ancient Era
Java knew what files are but didn’t knew how can i access them (as they were just sitting behind os )
Invention : File class -> Can only create, delete and check file metadata with this :_)
Piroblem : Can’t read/write actual data inside file
Solution : In the next eraaaaaaa
CHAPTER 2:- The Birth of Streams
Java said everything is a stream (nothing just a fancy way to say flow of data, so byte stream means flow of bytes)
Invention :
1. InputStream (reading the data stream coming into our javaaa prog)
2. OutputStream (writing to the stream going out of our javaaa prog)
Piroblem : Just a abstract class -> these classes are of no use without any solid implementation -> it can’t talk to os for files or keyboard for i/o
Solution : In the next eraaaaaaa
CHAPTER 3:- First Real Stream
++ Before even talking to files, Java make stream for something more important : YOU ❤
Invention :
1. System.in -> take input from keyboard (uses InputStream internally)
2. System.out -> give output to user’s console (uses OutputStream class’s methods internally) (how? -> OutputStream extended by FilterOutputStream and overrides its methods like write() -> this write method actually tells how to make system call to os. Now, FilterOutputStream extended by PrintStream which gives methods like println that again internally uses its parent’s method write() to make actual system call to os -> hope you got it! i’ll attach a pic)
Piroblemia : Byte-by-byte reading
CHAPTER 4:- Second Real Stream
Java remembers we also had files to handle
Invention :
1. FileInputStream -> Tells how to read a file actually (how? -> extends InputStream class and just override its read method)
2. FileOutputStream -> Tells how to write in a file actually (how? -> extends OutputStream class and just override its write method like FilterOutputStream was extending)
Piroblem : It does byte-by-byte reading or we can say, in laymen, character-by-character reading -> making it very slow -> each byte reading makes a sc to os (BOOM!)
Soluchan : Add caching bro, get chunk of data, why disturb os everytime !!
CHAPTER 5:- Buffered Streams -> Performance enhancer !!
Java using caching intelligently using buffers (reduced all those expensive system calls)
Invention :
1. BufferedInputStream -> Add buffering while java reading from file (Extends FilterInputStream and override its read() method + buffering logic added)
2. BufferedOutputStream -> Add buffering while java writes into the file (Extends FilterOutputStream and override its write() method + buffering logic added) (while reading -> bring 8kb of data initially from hard-disk to my customizable buffer which is stored in memory, for subsequent hits read from memory -> if buffer empty, bring more data -> sc reduced !!!!
Problem : Still byte-by-byte flow !!
CHAPTER 6:- Decorating Existing classes
Get Devendrabedwal’s stories in your inbox
Join Medium for free to get updates from this writer.
Let’s wrap existing streams to power up
Decorator example :- BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream(“file.txt”)
)
);
CHAPTER 7: -Data Streams
byte-by-byte is ok for characters as every ascii can be represented as 1byte but what if we want to transfer “int var=300” -> 3 separate bytes created and wrong value decode -> it breaks here
Invention :
1. DataInputStream -> can read any datatype using this stream (just use its correct internal methods like read, readInt, readDouble, readBoolean)
2. DataOutputStream -> can write any datatype using this stream (just use its correct internal methods like writeInt, writeDouble, writeBoolean)
Problem : Ok, but how can i read a full object directly ??
CHAPTER 8:- Output Streamsssss — Serialization Intro
Java evolves and serialization comes into picture -> serialization simply means converting (obj -> bytes) and deserialization is (bytes -> obj)
Invention :
1. ObjectInputStream -> reading the byte data and de-serializing it back to the object
2. ObjectOutputStream -> serializing the object, converting into bytes and saving in a file
Piroblem : But how can i handle non-ascii or hindi language?
CHAPTER 9:- Character Streams
Bytes fail for text/some non-english language → encoding matters
Invention :
1. InputStreamReader -> Can convert bytes -> characters using a specific charset and decode it
2. OutputStreamWriter -> Can encode any character and write it in file
Problem : Little speed issue, can be optimized using buffer again !!
CHAPTER 10:- Buffered Readers/Writers
Now Java becomes developer-friendly and efficiently processes text
Invention :
1. BufferedReader -> Read files including any character with buffers
2. BufferedWriter -> Write any character to file using buffers
Below snippets are using Buffered Reader for console i/o and file i/o in java
One last hierarchy charts
BYTE STREAMS (Raw Data Flow)
Used for binary data (images, files, videos, etc.)
CHARACTER STREAMS (Text Handling)
Used for text (encoding-aware)
There are more dots to be connected !!
What next?
- Building chat client and server using above knowledge
- Handling large file reading and processing (any format like excel, doc, txt, etc). Base line is same !!







