“This is the fifth day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

“Lao Wang, Java IO is too top?” The recruit egg son small 2 complain to the old wang with very cool head, “you see, I carried on a simple classification to IO according to the transmission way, can make out so many things!”

PS: In order to help more Java beginners, the Path to Java Programmer advancement has been open source on GitHub. This column has collected 590 stars so far. If you like this column and think it is helpful, you can click a star and hit 1000 stars, which is also convenient for more systematic learning in the future!

GitHub address: github.com/itwanger/to…

Code cloud address: gitee.com/itwanger/to…

Having not done IO for a long time, Lao Wang was surprised to see this mind map. When he was learning Java IO, he had a big head. It was all classes, and it was probably the most classes in all Java packages. It was Input and Output, Reader and Writer.

Looking at xiao Er, who was about to explode, Lao Wang took a deep breath and patiently said to Xiao Er, “It’s mainly the designers of Java who have considered much, so IO gives people a very messy feeling. Let me sort it out for you.”

01. Transmission mode division

Let’s go with your mind map.

There are two modes of transmission, byte and character, so you have to figure out what the difference is between byte and character, right?

A byte is a unit of measurement used in computers to indicate storage capacity. Typically, a byte has eight bits.

A char can be the letters, numbers, and symbols used in computers, such as A, 1, and $.

Generally speaking, a letter or character takes up one byte, and a Chinese character takes up two bytes.

It depends on the character encoding. For example, in UTF-8, an English letter (case insensitive) is one byte and a Chinese character is three bytes. In Unicode, an English letter is one byte and a Chinese character is two bytes.

PS: For character encodings, see the previous section: Kuen Jin Kuen

Now that you understand the difference between bytes and characters, it’s much easier to look at byte streams and character streams.

Byte streams are used to process binary files such as pictures, MP3s, and videos.

Character streams are used to process text files, which can be thought of as a special kind of binary file, but encoded so that people can read it.

In other words, the byte stream can handle all files, while the character stream can only handle text.

Although there are many IO classes, the core is four abstract classes: InputStream, OutputStream, Reader, Writer.

(Abstract Dafa is good)

While there are many methods in the IO class, there are only two core ones: read and write.

InputStream class

  • int read(): Read data
  • int read(byte b[], int off, int len): Reads len bytes from the off position and puts them into array B
  • long skip(long n): Skips a specified number of bytes
  • int available(): Returns the number of bytes that are readable
  • void close(): Closes the stream to release resources

OutputStream class

  • void write(int b): Writes a byte, although the argument is an int, but only the lower 8 bits are written, the higher 24 bits are discarded.
  • void write(byte b[], int off, int len): writes len bytes from array B, starting at position OFF
  • void flush(): Forcibly refreshes and writes data to the buffer
  • void close(): close the flow

Reader class

  • int read(): Reads a single character
  • int read(char cbuf[], int off, int len): Reads len characters, starting at the off position, and then puts them into array B
  • long skip(long n): Skips a specified number of characters
  • int ready(): Is it ready to read
  • void close(): Closes the stream to release resources

Writer class

  • void write(int c): Writes a character
  • void write( char cbuf[], int off, int len): Writes len characters from the cbuf array starting at position OFF
  • void flush(): Forcibly refreshes and writes data to the buffer
  • void close(): close the flow

By understanding these methods, the soul of IO is basically mastered.

Two, operation object division

Small two, you think about it carefully, IO IO, is not the Input/Output?

  • Input: Reads external data into memory, such as files from hard disk to memory, data from network to memory, and so on
  • Output: Write data from memory to the outside world, such as writing data from memory to a file, Output data from memory to the network, etc.

All programs, when they’re executed, are in memory, and once they’re shut down, the data in memory is gone, so if you want to persist, you have to export the data out of memory, like a file.

File operation is the most typical operation in IO, and also the most frequent operation. If you think about it in terms of the objects that IO operates on, for example, you can classify IO into files, arrays, pipes, primitive data types, buffering, printing, object serialization/deserialization, and conversion.

1) file

File streams, which are streams that directly manipulate files, can be subdivided into byte streams (FileInputStream and FileOuputStream) and character streams (FileReader and FileWriter).

FileInputStream example:

int b;
FileInputStream fis1 = new FileInputStream("fis.txt");
// loop read
while((b = fis1.read())! = -1) {
    System.out.println((char)b);
}
// Close the resource
fis1.close();
Copy the code

FileOutputStream example:

FileOutputStream fos = new FileOutputStream("fos.txt");
fos.write("Silent King II.".getBytes());
fos.close();
Copy the code

Examples of FileReader:

int b = 0;
FileReader fileReader = new FileReader("read.txt");
// loop read
while((b = fileReader.read())! = -1) {
    // Autolift type is promoted to int, so char is cast
    System.out.println((char)b);
}
/ / close the flow
fileReader.close();
Copy the code

FileWriter example:

FileWriter fileWriter = new FileWriter("fw.txt");
char[] chars = "Silent King II.".toCharArray();
fileWriter.write(chars, 0, chars.length);
fileWriter.close();
Copy the code

When you master the input and output of the file, the rest of the natural master, are very good.

2) array

In general, a file stream with a buffer stream is sufficient for reading and writing files, but it is not good to read and write files frequently to improve efficiency, so array streams, sometimes called memory streams, appear.

Examples of ByteArrayInputStream:

InputStream is =new BufferedInputStream(
        new ByteArrayInputStream(
                "Silent King II.".getBytes(StandardCharsets.UTF_8)));
/ / operation
byte[] flush =new byte[1024];
int len =0;
while(-1! =(len=is.read(flush))){ System.out.println(new String(flush,0,len));
}
// Release resources
is.close();
Copy the code

Examples of ByteArrayOutputStream:

ByteArrayOutputStream bos =new ByteArrayOutputStream();
byte[] info ="Silent King II.".getBytes();
bos.write(info, 0, info.length);
// Get data
byte[] dest =bos.toByteArray();
// Release resources
bos.close();
Copy the code

3) pipe

Pipes in Java are different from pipes in Unix/Linux, where different processes communicate through pipes, but in Java, the two parties must be in the same process, that is, within the same JVM, and pipes provide the ability to communicate between threads.

Data written by one thread via PipedOutputStream can be read by another thread via the associated PipedInputStream.

final PipedOutputStream pipedOutputStream = new PipedOutputStream();
final PipedInputStream pipedInputStream = new PipedInputStream(pipedOutputStream);

Thread thread1 = new Thread(new Runnable() {
    @Override
    public void run(a) {
        try {
            pipedOutputStream.write("Silent King II.".getBytes(StandardCharsets.UTF_8));
            pipedOutputStream.close();
        } catch(IOException e) { e.printStackTrace(); }}}); Thread thread2 =new Thread(new Runnable() {
    @Override
    public void run(a) {
        try {
            byte[] flush =new byte[1024];
            int len =0;
            while(-1! =(len=pipedInputStream.read(flush))){ System.out.println(new String(flush,0,len));
            }

            pipedInputStream.close();
        } catch(IOException e) { e.printStackTrace(); }}}); thread1.start(); thread2.start();Copy the code

4) Basic data types

Basic Data Types An input/output stream is a byte stream that can read and write not only bytes and characters but also basic data types.

DataInputStream provides a series of methods that can read primitive data types:

DataInputStream dis = new DataInputStream(newFileInputStream (" das. TXT "));byte b = dis.readByte() ;
short s = dis.readShort() ;
int i = dis.readInt();
long l = dis.readLong() ;
float f = dis.readFloat() ;
double d = dis.readDouble() ;
boolean bb = dis.readBoolean() ;
char ch = dis.readChar() ;
Copy the code

DataOutputStream provides a series of methods that can write basic data types:

DataOutputStream das = new DataOutputStream(newFileOutputStream (" das. TXT ")); das.writeByte(10);
das.writeShort(100);
das.writeInt(1000);
das.writeLong(10000L);
das.writeFloat(12.34 F);
das.writeDouble(12.56);
das.writeBoolean(true);
das.writeChar('A');
Copy the code

5) buffer

The CPU is fast. It’s 100 times faster than memory and a million times faster than disk. That means programs interact quickly with memory and slowly with hard disk, which can lead to performance problems.

To reduce the interaction between the program and the hard disk and improve the efficiency of the program, Buffer streams, the ones with the class name prefixed with Buffer, are introduced. Like BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter.

A buffered stream sets up a buffer in memory. It will not interact with memory or disk until the buffer stores enough data with operations. Simply put, read/write more at a time, read/write fewer times, and your program will perform better.

6) print

PrintStream is probably the most commonly used Java programmer’s life: System.out actually returns a PrintStream object that can be used to print a variety of objects.

System.out.println("The Silent King is the real king!");
Copy the code

PrintStream ultimately outputs byte data, whereas PrintWriter extends the Writer interface, so its print()/println() methods ultimately output character data. It’s almost exactly like PrintStream.

StringWriter buffer = new StringWriter();
try (PrintWriter pw = new PrintWriter(buffer)) {
    pw.println("Silent King II.");
}
System.out.println(buffer.toString());
Copy the code

7) Object serialization/deserialization

Serialization is essentially turning a Java object into an array of bytes, which can then be saved to a file or transmitted remotely over the network.

ByteArrayOutputStream buffer = new ByteArrayOutputStream();
try (ObjectOutputStream output = new ObjectOutputStream(buffer)) {
    output.writeUTF("Silent King II.");
}
System.out.println(Arrays.toString(buffer.toByteArray()));
Copy the code

Instead of serialization, there is deserialization, which is the process of converting byte arrays into Java objects.

try (ObjectInputStream input = new ObjectInputStream(new FileInputStream(
        new File("Person.txt")))) {
    String s = input.readUTF();
}
Copy the code

8) conversion

InputStreamReader is a bridge from a byte stream to a character stream that reads bytes using a specified character set and decodes them into characters.

InputStreamReader isr = new InputStreamReader(
        new FileInputStream("demo.txt"));
char []cha = new char[1024];
int len = isr.read(cha);
System.out.println(new String(cha,0,len));
isr.close();
Copy the code

OutputStreamWriter turns the output object of a character stream into the output object of a byte stream, and acts as a bridge between the character stream and the byte stream.

File f = new File("test.txt"); Writer out =new OutputStreamWriter(new FileOutputStream(f)) ; // The byte stream becomes a character stream
out.write("hello world!!");// Use character stream output
out.close() ;
Copy the code

“Small two, you see, after I comb, is not feeling IO also not many things! For different scenarios, different services, you can choose the corresponding IO stream, namely read and write.” Lao Wang breathed a sigh of relief as he finished.

At this moment of small 2, still immersed in Lao Wang’s gushing. Not only feel that Lao Wang’s lung capacity is really big, but also feeling that Lao Wang is worthy of being a “veteran” who has worked for more than ten years, all of a sudden feel his head big IO to comb very clear.

This is the 68th installment in the Java Programmer’s Path to Advancement column. This column is humorous, easy to understand, extremely friendly and comfortable for Java beginners 😘, including but not limited to Java syntax, Java Collections framework, Java IO, Java concurrent programming, Java virtual machine and other core knowledge points.

GitHub address: github.com/itwanger/to…

Code cloud address: gitee.com/itwanger/to…

White and dark PDF versions are ready, let’s become better Java engineers together, together!