The concept of "stream" originates from the concept of pipe in UNIX. In UNIX, a pipe is an uninterrupted byte stream used to implement communication between programs or processes, or to read and write peripheral devices, external files, etc. It shields the details of data processing in the actual I/O device. A stream must have a source and a destination, which can be certain areas of computer memory, disk files, or even a URL on the Internet. The direction of the flow is important. According to the direction of the flow, the flow can be divided into two categories: input flow and output flow. In fact, input/output is for memory. In fact, the source and destination of the stream can be simply regarded as the producers and consumers of bytes. For the input stream, you do not need to care about its source, as long as you simply read the data from the stream, and for the input stream The output stream can also be unaware of its destination and simply write data to the stream.
a. Stream: A set of ordered data sequences.
b Byte stream: The smallest data unit in the data stream is bytes.
c. Character stream: The smallest data unit in the data stream is a character.
1. The classes in the java.io package correspond to two types of streams
One type of stream reads or writes directly from a specified location (such as a disk file or memory area). This type of stream is called a node stream, and other streams are called filter streams (packaging streams).
Filtering streams: Some streams can receive bytes from files and elsewhere, and other streams can combine bytes into more useful data types. A constructor that passes an existing stream to another stream and combines the two streams. The combined stream is called a filtered stream. The filter input stream often uses other input streams as its input source. After filtering or processing, it is provided to the user in the form of a new input stream. The filter output stream is similar. We rarely use a single class to create a flow object, but instead provide the desired functionality by overlaying multiple objects (i.e. the decorator design pattern).
Java's commonly used input and output streams are actually inherited from four abstract classes, which are:
Based on single-byte InputStream, OutputStream class (byte-oriented I/O)
Reader and Writer classes based on double-byte Unicode code units (character-oriented I/O)
Once the input stream is opened, the program can read data serially from the input stream. The process of reading/writing data from the input stream is generally as follows: open a stream channel --> read/write information --> close the stream channel.
In the Java platform, there are two ways to obtain the character encoding type of the local platform:
(a) System.getProperty("file.encoding");
(b) Charset cs=Charset.defaultCharset();
All input streams and output streams can be divided into byte (input, output) streams and character (input, output) streams. Those that process bytes are mainly (OutputStream/InputStream) series, and those that process characters are mainly (Reader/ Write) series
2. Byte-oriented input streams (InputStream series), these classes can be connected to FileInputStream objects to provide useful interfaces:
ByteArrayInputStream: Use a buffer in memory as an InputStream
StringBufferInputStream (deprecated in java1.1): Use a String object as an InputStream, and the underlying implementation uses StringBuffer
FileInputStream: Use a file as an InputStream to implement the file reading operation (file name, file, FileDescriptor object)
PipedInputStream: implements the concept of pipe, mainly used in threads (as a data source in multiple processes)
SequenceInputStream: Combine multiple InputStreams into one InputStream
Byte-oriented output streams (OutputStream series) can be connected to FilterOutputStream objects to provide useful interfaces:
ByteArrayOutputStream: Create a buffer in memory, store information in a buffer in memory, and initialize the buffer size (optional)
FileOutputStream: Store information in a file (file name, file, FileDescriptor)
PipedOutputStream: implements the concept of pipe, mainly used in threads (specifies the destination of data for multi-threads)
3. The corresponding (Reader/Writer) series :
Reader: Corresponding to InputStream, adapter InputStreamReader
Writer: corresponds to OutputStream, and the adapter is OutputStreamWriter
FileReader: Corresponds to FileOutputStream
FileWriter: corresponds to FileOurputStream
StringReader: No corresponding class
StringWriter: Corresponds to ByteArrayInputStream
CharArrayReader: Corresponds to ByteArrayOutputStream
CharArrayWriter: Corresponds to ByteArrayOutputStream
PipedReader: Corresponds to PipedInputStream
PipedWriter: Corresponds to PipedOutputStream
4. Conversion between two unrestricted streams ( using adapter class)
InputStreamReader and OutputStreamReader: Convert a byte-oriented stream into a character-oriented stream.
InputStreamReader is a bridge from a byte stream to a character stream: it reads bytes using a specified charset and decodes them into characters. The character set it uses can be specified by name or given explicitly, or it can accept the platform's default character set.
OutputStreamWriter is a bridge from character stream to byte stream: characters to be written to the stream can be encoded into bytes using the specified charset. The character set it uses can be specified by name or given explicitly, otherwise the platform default character set will be accepted
5. Read data from InputStream through FilterInputStream :
DataInputStream: Read basic type (int, char, long, etc.) data from the stream.
BufferedInputStream: Use a buffer to prevent having to perform an actual read operation every time
LineNumberInputStream: will record the number of lines in the input stream, and then call getLineNumber() and setLineNumber(int)
PushbackInputStream: Rarely used, generally used for compiler development
Write to OutputStream through FilterOutputStream:
DataIOutputStream: Basic type (int, char, long, etc.) data can be output to the stream according to the transplantation method.
BufferedOutputStream: Use a buffer to avoid the actual writing every time you send data
PrintStream: produces formatted output, where DataOutputStream handles data storage and PrintStream handles display
6. Change the behavior of the stream
Although BufferedOutputStream is a subclass of FilterOutputStream, BufferedWriter is not a subclass of FilterWriter (FilterWriter is an abstract class and does not have any subclasses)
There is no corresponding class for DataInputStream. Use DataInputStream unless you use BufferedReader instead when you want to use readLine()
BufferedReader: corresponds to BufferedInputStream
LineNumberReader: Corresponds to LineNumberInputStream
PushBackReader: Corresponds to PushbackInputStream
BufferedWrite: corresponds to BufferedOutStream
PrintWrite: corresponds to PrintStream
7. Self-independent class: RandomAccessFile
This class is suitable for files composed of records of known size. In addition to implementing the DataInput and DataOutput interfaces (DataInputStream and DataOutputStream also implement these two interfaces), RandomAccessFile is a completely independent class. It has and other I/O types have inherently different behaviors, can move forward and backward within a file, and are derived directly from Object.
Read and write operations on files can be completed through the RandomAccessFile object.
When generating an object, you can specify the nature of the file to be opened: r, read-only; w, write-only; rw can read and write
You can jump directly to the specified location in the file
Most (but not all) functionality of RandomAccessFile has been replaced by nio storage mapping files