This article has participated in the weekend study program, click the link to see details: juejin.cn/post/696572…
What is an IO stream
JavaIO stream is a computer term. It is mainly used to process the transmission of data. — Baidu Encyclopedia
A stream is a flow of data, and an IO stream is a flow of input and output. In Java, data is streamed. Data cannot be transferred from one device to another at once, so it can only be streamed bit by bit. An input stream reads data from somewhere else into the program, and an output stream writes data from the program to somewhere else.
Two, IO stream classification
1. Four abstract classes
IO provides four of the most important abstract classes: InputStream,OutputStream,Reader, and Writer.
A character is equal to two bytes. According to the units of data output, there are two types, byte streams and character streams
Graph LR ((byte stream)) - enter A - > B (InputStream) A output -- -- -- > C (OutputStream) D (flow) (characters) - input - output - > E (Reader) D - > F (Writer)
You can also divide it into input streams and output streams depending on the input or output and depending on what you’re doing, you can also divide it into node streams and processing streams and a node stream is reading or writing data from a particular node. When you look at a node, it feels esoteric. Basically, it means reading or writing data from a place, which can be a database, a console, a file, etc. The processing flow is the proxy node flow that implements some other function. For example, a BufferedWriter can only write one character at a time if it is a normal FileWriter. If a BufferedWriter is installed, it can write more quickly.
2. Various implementation classes
Graph LR A((InputStream))-->AN[node stream] AN-->A1(FileOutputStream) AN-->A2(PipedOutputStream) AN-->A3(ByteArrayOutputStream) A5(PrintStream) AH-->A6(DataOutputStream) AH-->A7(ObjectOutputStream) AH-->A7(ObjectOutputStream) B((OutputStream))-->BN[node stream] BN-->B1(FileInputStream) BN-->B2(PipedInputStream) BN-->B3(ByteArrayInputStream) B-->BH BH-->B4(BufferedInputStream) BH-->B5(SequenceInputStream) BH-->B6(DataInputStream) BH-->B7(ObjectInputStream) BH-->B8(PrintStream) D((Reader))-->DN DN-->D1(FileReader) DN-->D2(PipedReader) DN-->D3(CharArrayReader) D-->DH DH-->D4(BufferedReader) DH-->D5(InputStreamReader) C((Writer))-->CN (node stream) CN-->C1(FileWriter) CN-->C2(PipedWriter) C--> C5(InputStreamWriter) C--> C6(PrintWriter) C--> C5(InputStreamWriter) C--> C6(PrintWriter)
There may be some omissions, more detailed can see the Java official documentation.
How to use it
Take FileInputStream and FileOutputStream for example
Code 1.
package test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/ * * *@authorXXJ * IO stream test */
public class IOTest {
public static void main(String[] args) {
// Open a file first
File file= new File("C:\\Users\\Administrator\\Desktop\\test.txt");
try{
// Write data first
FileOutputStream fileOutputStream=new FileOutputStream(file);
fileOutputStream.write("ABCD".getBytes());
fileOutputStream.close();
// Read the data
FileInputStream fileInputStream=new FileInputStream(file);
int i= 0;
while((i=fileInputStream.read())! = -1){
System.out.println("Data read via a fileInputStream:"+i);
System.out.println("Data read via a fileInputStream:"+ (char)i);
System.out.println("-- -- -- -- -- -");
}
fileInputStream.close();
}catch (Exception e){}
}
}
Copy the code
2. Output the result
Because I added (char) I automatically converted the ASCII code table and my desktop also generated test.txt, so take the code and run with it.
3. Explain
You might say, well, you’re not doing this right, you’re not doing a FileInputStream and you’re not doing a FileOutputStream, why is it that each read happens to be one letter, not one byte? A byte is eight bits. If you look at the ASCII code table, there are already hundreds of symbols or letters in it. You can’t just use four bits to represent them, but at least eight bits.
Take FileReader and FileWriter for example
Code 4.
public class IOTest {
public static void main(String[] args) {
try{
/ / write first
File file=new File("C:\\Users\\Administrator\\Desktop\\writer.txt");
FileWriter fileWriter=new FileWriter(file);
fileWriter.write("ABC one two three");
fileWriter.close();
/ / read
FileReader fileReader=new FileReader(file);
int i=0;
while((i=fileReader.read())! = -1){
System.out.println("Data read by reader:"+i);
System.out.println("Data read by reader:"+ (char)i);
System.out.println("-- -- -- -- -- -");
}
fileReader.close();
}catch (Exception e){}
}
}
Copy the code
5. Output the result
6. Explain
I have a question, why FileReader can read letters, just like FileInputStream, then why can it read just one Chinese and one letter? 19968=0x4e00 writer.txt is
4142 43 e4b8 80e4 ba8c e4b8 89
Copy the code
There’s no 4e00, Then we convert it to binary (1) 19968=100111000000000 (2) 20108=100111010001100 (3) 19977=100111000001001 0 xe4b880e4ba8ce4b889 = 111001001011100010000000111001001011101010001100111001001011100010001001 I used String. The replace () method, E4b8 80E4 ba8c E4b8 89 does not contain the binary of one, two and three.
This is where encodings come in. The common list of encodings that support Chinese is UTF-8, so I pulled 1, 2, 3 into it to see the base conversion
This. It’s really a set of things. At this point, it’s not clear exactly how do you decide to read only one byte or read only one character
Four, the characteristics of various IO streams
Different IO stream use is similar, but there are some different details, specific can look up Baidu or directly see the source code of each implementation class, After all, they all inherit InputStream,OutputStream,Reader, and Writer, respectively, and the processing stream is indirectly inherited from the Filter stream.
The last write to the FileOutputStream is with the native modifier.
private native void writeBytes(byte b[], int off, int len, boolean append)
throws IOException;
Copy the code
The difference between byte streams and character streams
- Byte streams can operate only one byte at a time, and character streams can operate two bytes
- Byte streams can handle any file type, while character streams can only handle text files
1. The node flow
The File stream
Bytes: FileInputStream, FileOutputStream Characters: FileReader, FileWriter
The characteristics of
All of these require the creation of a File object before they can be used, and all read and write operations are done on the created File object. The only difference is that the first two are byte streams and the last two are character streams, which are used if you want to read or write Chinese.
Piped flow
Byte: PipedInputStream, PipedOutStream, character: PipedReader, PipedWriter generally is used for communication between threads
The characteristics of
When using these streams, you don’t need to create a File object as compared to a File stream, you just create it like a normal stream, but before the Piped can communicate with each other, you need to connect the two pipes using the connect method
A Piped stream does not need to use a file as a carrier of data.
Byte/character array stream
Bytes: ByteArrayInputStream, ByteArrayOutputStream Characters: CharArrayReader, CharArrayWriter
Each of these four streams has an array inside it, and is used to store data into the array, read from the array, or write the data from the array elsewhere.
The characteristics of
Byte: only bytes can be read or written. ByteArrayInputStream is created by passing a parameter (an array of bytes) to the constructor and ByteArrayOutputStream is used by calling writeTo. These two streams help us to store data in the cache first and then read and write more quickly. CharArrayWriter is similar to ByteArrayInputStream or ByteArrayOutputStream, except that Char starts with read and write characters. Byte is reading and writing bytes, which is the same thing.
2. The processing flow
When processing streams are used, they need to be nested with a node stream, and then use the same method as using node streams.
Buffered stream buffer
Byte: BufferedInputStream, BufferedOutputStream characters: BufferedReader, BufferedWriter
These four streams are similar to byte/character streams in that they also have an internal array that acts as a cache. However, the byte/character array stream caches data into the array. It does not flush the array. It reads or writes from the array. Buffered has an array that does not change twice (you can pass size in the constructor). Once the array is full, the array is read or written to somewhere else, and then the array is flushed.
Byte/character array streams are recommended to be closed once used.
The characteristics of
After using other node streams, the method is similar to that used for node streams, but a flush() method is used to flush all the data inside the cache when the Buffered stream is written.
Transformation of flow
Characters: InputStreamReader, OutputStreamWriter
The characteristics of
The ability to convert a byte stream into a character stream is created by passing a byte stream and character set (GBK by default) to the constructor in much the same way as a character stream.
The data flow
Bytes: DataInputStream, DataOutputStream
The characteristics of
Data flow is the ability to write data according to different types and read data according to the corresponding type. Just like when you write, you put data into boxes of different types. When you read, you read according to the box type and in the order in which it was written.
Printing flow
Byte: PrintStream Character: PrintWriter
The characteristics of
These two streams do not have corresponding input streams and are used in the same way as any other processing stream. Once a node stream is mounted, the data can be written directly using print() or println(). System.out.println() is a method that uses PrintStream internally.
Object flow
Bytes: ObjectInputStream, ObjectOutputStream
The characteristics of
One thing these two streams can do is serialize the data we are writing to or reading from. Serialization is the conversion of objects to binary data. To use these two streams, the first step is to install a node stream, the second step is to implement the Serializable interface on the class to be serialized, and the rest of the usage is similar to a normal node stream.
Five, the summary
These streams are really a lot, so let’s summarize the usage scenarios. Both write and read are text types and Chinese, we use character streams. To write or read any other miscellaneous file type without Chinese, use a byte stream. To consider threaded communication, use Piped streams; To manipulate a File, use the File stream; To store data in memory, use byte/character array streams, no performance or functionality requirements, these three are sufficient. To improve read/write performance, use a Buffered stream. If you want a data format, create a data stream. For ease of use or line feed, use a print stream; To serialize an object, create an object stream.
— — — — — — — — — — — — — — —
The more you know, the more you don’t know.
If you have questions about this article, please comment directly or send me a personal message. If you think my writing is good, you can also support me by clicking “like”
Without permission, shall not be reproduced!
Wechat search [programmer Xu Xiaobai], attention can be the first time to read the latest articles. There are 50 high frequency college recruitment interview questions prepared by me, as well as a variety of learning materials.