Streams are an abstract concept of byte sequences.
Files are static storage forms of data, while streams refer to the form when data is transmitted.
Stream classes are divided into two major categories: node stream classes and filtered stream classes (also called process stream classes).
The class corresponding to the target device is called the node flow class. The program can also call the node flow class through an indirect flow class to achieve more flexible and convenient reading of various types of data. This indirect flow class is the filter flow class (also called the processing flow class), or the packaging class.
The call process of the wrapper class is as follows:
The relationship between flow classification
No matter how rich and complex the classification of streams is, its roots come from four basic classes. The relationship between these four classes is as follows:
| Byte Stream | Character stream | |
| Input Stream | InputStream | Reader |
| Output Stream | OutputStream | Writer |
Unicode encodes stored characters in Java, and the character stream processing class is responsible for converting other external coded character streams and Unicode character streams in Java. The classes InputStreamReader and OutputStreamWriter handle conversions of character streams and byte streams. A character stream (can handle one buffer at a time) is more efficient at one operation than a byte stream (one byte at a time).
InputStream
Since InputStream and OutputStream are abstact classes, they cannot indicate which IO device they correspond to. There are many subclasses below them, including specific IO devices such as networks, pipelines, memory, files, etc., and their various subclass objects used in actual programs.
Note: We call the IO source and target corresponding to the node flow class the stream node (Node).
Note: When writing the contents of file A to file B, the program uses the output class or input class for the operation of file A. The input and output class is relative to the program, not on behalf of the file, so we should create an input class to complete the operation on file A and an output class to complete the operation on file B.
OutputStream
Character-oriented stream Reader/Writer
A stream directed by Unicode characters means reading from the stream or writing information into the stream in Unicode characters. Similarly, Reader/Writer is also abstact class.
Reader
Writer
Reuse of IO program code:
Usually, when writing code, use -1 as the end of keyboard input, and do not use System.in directly in the written function. It is just that when calling the function, System.in is passed in as a parameter. In this way, when we want to read data from a file in the future to replace manual keyboard input, we can use this function directly, so the program does not need to make too many modifications, so as to achieve the effect of unchanging and adapting to changes.
Conversion of byte streams and character streams
InputStreamReader and OutputStreamReader: Convert a byte-oriented stream into a character-oriented stream.
The InputStreamReader class is a bridge from a byte stream to a character stream: it reads in the bytes and converts it into a character stream according to the specified encoding method.
The encoding method used may be specified by the name, or the default encoding method acceptable to the platform.
Each call to one of the read() methods of InputStreamReader may cause one or more bytes to be read from the base byte input stream.
In order to achieve higher efficiency, consider encapsulating the InputStreamReader with BufferedReader.
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
A summary of Java streaming usage
I have encountered many Java streams in my most professional work, and the summary is as follows:
1. Generate Zip format. What you encounter is to generate Zip files in a servlet, output them to the web client, and download them directly.
response.setContentType("application/zip"); response.addHeader("Content-Disposition", "attachment;filename=/"xxx.zip/""); ZipOutputStream out = new ZipOutputStream(response.getOutputStream()) for() { ZipEntry entry = new ZipEntry("aa" + i ".dat"); out.putNewEntry(entry); bytes[] bt = s.getBytes(); out.writeBytes(bt, 0, bt.length()); out.closeEntry(); } out.flush(); out.close(); ZipOutputStream inherits from java.io.FilterOutputStream. Therefore, the real write operation is written through the parameter OutputStream out.
Its void write(byte[] b, int off, int len) finally calls out.write(b, off, len);
If you want to generate a zip file, write new ZipOutputStream(new FileOutputStream(path));
2. Similar writing XML.
XMLWriter writer = new XMLWriter(new FileOutputStream(path), formatter)
Writer.write(doc).The principle is similar to the above
3. Write text files and add them.
PrintStream ps = new PrintStream(new FileOutputStream(path, true), "utf-8")ps.println(s); // Can write various types such as boolean, int, etc.PrintSteam also inherits from FilterOutputStream
DataOutputStream out = new DataOutputStream(socket.getOutputStream()); out.writeBytes(bt); out.writeBoolean(boolean v);
DataOutputStream is also a FilterOutputStream.
5. Read from text
BufferedReader reader = new BufferedReader(new FileReader(path)); reader.readLine();
The BufferedReader pattern is the same as the Filter pattern above. It stores an object that the Reader object is passed in as the parameter and used to actually read.
The class corresponding to Java 1.0 of BufferedReader is BufferedInputStream, which is a FilterInputStream.
6. Read from Socket
BufferedInputStream is = new BufferedInputStream(socket.getInputStream()); is.read(bt, 0, bt.length());
Summarize:
The base class Stream series are InputStream and OutputStream. They are abstract classes and the only methods required are (take Output as an example)
void write(int b) throws IOException; void write(byte b[]) throws IOExceptionvoid write(byte b[], int off, int len)
The most basic thing is byte operation. The first method seems to write an integer, but in fact it only writes one byte (the lowest eight bits). Its subclass is divided into two series, one is to directly operate the output device. What we encountered above are file (FileOutputStream) and Servlet output (ServletOutputStream). Other commonly used ones are also a ByteArrayOutputStream, which is operated directly in memory.
Next is the FilterOutputStream series, which receives an OutputStream object seat parameter, and the real write operation is completed through the object. For example, ZipOutputStream is only responsible for generating compressed data. As for whether this data is written to file, memory, or servletResponse, it is determined by the input parameters. This is the decorator pattern.
The commonly used operations in the Filter series include PrintStream (providing print, println, write(boolean[int, char, string]), and finally using the out.write method to write it in bytes.
There is also DataOutputStream, which provides writeByte/writeBoolean/writeDouble/writeLong/wiretUTF and other methods.
There are also socket/zip and other things that are not commonly used.
Java streaming is very convenient and complicated. Complexity means that implementing a function often requires multiple classes, and there are multiple combinations. It still needs to be summarized in practice.