Java IO series:

  1. First, sort out the huge Java IO system
  2. Path, Files, RondomAccessFile
  3. Serialization and deserialization

An overview,

1. The concept of IO streams

The IO section of the Java class library is huge because it covers so many areas:

  • Standard input output
  • File manipulation
  • The flow of data over a network
  • String flow
  • Object flow
  • Zip file stream…..

Java abstracts input and output asflowIt’s like a water pipe connecting two containers. Reading data from external memory into memory is called an input stream, and writing data from memory into external memory is called an output stream.

2. I/O flow division

2.1 Division according to flow direction

Input stream and output stream

Note that the input and output streams are relative to the program

2.2 Division based on transmitted data units

Byte stream and character stream

These are also the four base flows in Java IO flows. These four base flows are abstract classes from which all other flows inherit.

  1. Byte stream: The smallest unit of data in a data stream is the byte
  2. Character stream: The smallest unit of data in a data stream is a character

2.3 Classification based on functions

Node flow and wrapper flow

Node flow: Data can be read and written from or to a specific place (node), directly connecting to a data source. For example, the most common is the file FileReader, can also be array, pipe, String, the keywords are ByteArray/CharArray, Piped, String respectively.

Processing flow (packaging flow) : A typical decorator design pattern is to connect and encapsulate an existing stream instead of directly connecting to a data source. The main purpose of using a processing stream is to perform input and output work more easily. For example, PrintStream has powerful output functions, and BufferedReader provides a caching mechanism

2.4 Some special stream types

Conversion stream: Conversion stream only converts byte stream to character stream, because character stream is more convenient to use, we will only convert to the more convenient direction. Such as InputStreamReader and OutputStreamWriter.

Buffered stream: A processing stream with the keyword Buffered, which adds caching to the wrapped stream to improve the efficiency of input and output. Flush () is used to write the contents of the buffer to the actual physical node. However, in current versions of Java, simply remember to close the output stream (calling the close() method), and the flush() method on the output stream is automatically executed, ensuring that the contents of the buffer are written.

Object stream: There is the keyword Object, which is used primarily to save the target Object to disk or to allow direct transfer of the Object over the network (Object serialization).

Templates for manipulating IO streams:

  1. Create a source or target object
  2. Create an IO stream object
    • For packaging
  3. Specific I/O operations
  4. Close the resource

Note: open file IO resources in the program do not belong to the memory resources, garbage collection mechanism cannot reclaim this resource. If this resource is not turned off, the disk files are always referenced by the program and cannot be deleted or changed. So you should manually call the close() method to close the stream resource.

Java IO flow architecture diagram

Ii. Standard IO

Java programs can exchange brief information with the outside world through command line parameters. It also specifies how to exchange information with standard input and output devices, such as keyboards and monitors.

1. Standard input/output data stream

Java System standard data flow: java.lang.System:

java.lang.System   
public final class System  extends Object{   
   static  PrintStream  err;// Standard error stream
   static  InputStream  in;// Standard input (keyboard input stream)
   static  PrintStream  out;// Standard output (display output)
}
Copy the code

Note: (1) The System class cannot create objects, only its three static members can be used directly. (2) Each time the main method is executed, the above three objects are automatically generated.

2. System.out

System.out outputs data to the standard output device of type PrintStream. Methods:

  • Void print(parameter)
  • Void println(argument)

3. System.in

System.in Reads standard input device data (data from standard input, usually the keyboard). Its data type is InputStream. Methods:

  • Int read() // Returns the ASCII code. If =-1 is returned, no bytes are read.
  • Int read(byte[] b) // Read multiple bytes into buffer B. The return value is the number of bytes read

4. System.err

System.err Prints a standard error. The data type is PrintStream. Consult the API for detailed instructions.

Input/outputStream

A typical implementation of inputStream FileInputStream example:

//1. Create the target object. Input stream represents that file's data is saved to the program. Do not write drive letters, the default file is in the root directory of the project
    //a.txt Saves the file AAaBCDEF
File target = new File("io"+File.separator+"a.txt");
// create an input stream object
InputStream in = new FileInputStream(target);
//3, specific IO operation (read the data in the file a.txt into the program)
    /** * Note: * int read(byte[] b): Reads multiple bytes and stores them in array B, starting at index 0 of array B. Return read several bytes * int Read (byte[] b,int off,int len): Read multiple bytes and store them in array B, starting at index 0 of array B, with len bytes */
//int read(): reads a byte, returns the byte read
int data1 = in.read();// Get the first byte of data in the a.txt file
System.out.println((char)data1); //A
//int read(byte[] b): reads multiple bytes and stores them in array B
byte[] buffer  = new byte[10];
in.read(buffer);// Get the first 10 bytes of the a.txt file and store it in the buffer array
System.out.println(Arrays.toString(buffer)); //[65, 97, 66, 67, 68, 69, 70, 0, 0, 0]
System.out.println(new String(buffer)); //AaBCDEF[][][]

//int read(byte[] b,int off,int len): Reads multiple bytes and stores them in array B, starting from index off to len
in.read(buffer, 0.3);
System.out.println(Arrays.toString(buffer)); //[65, 97, 66, 0, 0, 0, 0, 0, 0, 0]
System.out.println(new String(buffer)); //AaB[][][][][][][]
// Close the stream resource
in.close();
Copy the code

A typical implementation of an outputStream FileOutputStream example:

// create the target object. Output stream indicates which file to save the data to. Do not write drive letters, the default file is in the root directory of the project
File target = new File("io"+File.separator+"a.txt");
// create a byte output stream object for the file. The second argument is Boolean, true means that the file is appended to the data, false means overwrite
OutputStream out = new FileOutputStream(target,true);
// Write data to file a.txt.
    /** * void write(int b): write a byte to a file * void write(byte[] b): write all bytes from array B to a file * void write(byte[] b,int off,int len): write array B to a file Write len bytes from the off index to the file */
out.write(65); // Write A to the file
out.write("Aa".getBytes()); // Write Aa to the file
out.write("ABCDEFG".getBytes(), 1.5); // Write BCDEF to the file
// After the above operation, the data in the a.txt file is AAaBCDEF

// Close the stream resource
out.close();
System.out.println(target.getAbsolutePath());
Copy the code

An example of copying a file:

/** * Copy the a.txt file to b.txt */
// create source and target
File srcFile = new File("io"+File.separator+"a.txt");
File descFile = new File("io"+File.separator+"b.txt");
// create an input/output stream object
InputStream in = new FileInputStream(srcFile);
OutputStream out = new FileOutputStream(descFile);
// read and write operations
byte[] buffer = new byte[10];// Create an array of 10 bytes to store the read data
int len = -1;// Indicates how many bytes have been read, or -1 indicates that the end of the file has been read
while((len=in.read(buffer))! = -1) {// Prints the read data
    System.out.println(new String(buffer,0,len));
    // Read len starting from 0 in the buffer array into a b. TXT file
    out.write(buffer, 0, len);
}
// Close the stream resource
out.close();
in.close();
Copy the code

The Reader/Writer

  1. Why a character stream? Since it is easy to use byte streams to manipulate Chinese characters or special symbolic languages, since Chinese characters are more than one byte, character streams are recommended to solve this problem.
  2. When are character streams used? Generally can use notepad to open the file, we can see the content is not garbled. It’s a text file, you can use character streams. Binary files (such as images, audio, and video) must be manipulated using byte streams

FileWriter example:

// create a source
File srcFile = new File("io"+File.separator+"a.txt");
// create a character output stream object
Writer out = new FileWriter(srcFile);
//3. Specific I/O operations
    /*** * void write(int c): write one character * void write(char[] buffer): Write multiple characters buffer * void write(char[] buffer,int off,int * void write(String STR): write out a String */
//void write(int c): writes out a character
out.write(65);// Write A to the a.txt file
//void write(char[] buffer): Write multiple characters out of the buffer
out.write("Aa smart pan".toCharArray());// Write Aa to the a.txt file
//void write(char[] buffer,int off,int len)
out.write("Aa smart pan".toCharArray(),0.2);// Write Aa to the a.txt file
//void write(String STR): Writes out a String
out.write("Aa smart pan");// Write Aa to the a.txt file

// Close the stream resource
/*** * Note that if there is a concept of buffering, data will not be written to the file if it does not reach the size of the buffered array
out.flush();
out.close();
Copy the code

A typical FileReader implementation for Reader:

// create a source
File srcFile = new File("io"+File.separator+"a.txt");
// create a character output stream object
Reader in = new FileReader(srcFile);
//3. Specific I/O operations
    /*** * int read(): reads one character at a time, -1 * int read(char[] buffer): reads characters into an array of characters, returns the number of characters read * int read(char[] buffer,int off,int len): stores the characters read into an array of characters Buffer, which returns the number of characters read, starting with the index off and length len * */
//int read(): reads one character at a time, returns -1 at the end
int len = -1;// Define the number of characters currently read
while((len = in.read())! = -1) {// Prints all the contents of the a.txt file
    System.out.print((char)len);
}

//int read(char[] buffer): reads characters into an array of characters
char[] buffer = new char[10]; // Read 10 characters at a time
while((len=in.read(buffer))! = -1){
    System.out.println(new String(buffer,0,len));
}

//int read(char[] buffer,int off,int len)
while((len=in.read(buffer,0.10))! = -1){
    System.out.println(new String(buffer,0,len));
}
// Close the stream resource
in.close();
Copy the code

Copy with character stream:

/** * Copy the a.txt file to b.txt */
// create source and target
File srcFile = new File("io"+File.separator+"a.txt");
File descFile = new File("io"+File.separator+"b.txt");
// create a character input/output stream object
Reader in = new FileReader(srcFile);
Writer out = new FileWriter(descFile);
// read and write operations
char[] buffer = new char[10];// Create an array of 10 characters to store the read data
int len = -1;// Indicates how many bytes have been read, or -1 indicates that the end of the file has been read
while((len=in.read(buffer))! = -1){
   out.write(buffer, 0, len);
}

// Close the stream resource
out.close();
in.close();
Copy the code

Five, packaging flow

  • Includes buffered streams, transform stream object streams, and so on
  • The wrapper flow hides the differences of the underlying node flow and provides a more convenient input-output function to the outside world, leaving us concerned only with the operation of this high-level flow
  • The node flow is wrapped with the wrapper flow, and the program operates directly on the wrapper flow, while the underlying layer is still the node flow and IO device operation
  • When closing the wrapper flow, you just need to close the wrapper flow

1. The flow of buffer

1.1 an overview of the

Buffered stream: a wrapper stream that is used for caching to speed up data reading and writing.

Byte buffer streams: BufferedInputStream, BufferedOutputStream

Character buffer streams: BufferedReader, BufferedWriter

If we look at the underlying JDK source code for the buffer stream, we can see that the program defines such a cache array with a size of 8192

BufferedInputStream:

Case Replay: When we read a character input/output stream or byte input/output stream, we usually define a byte or character array. We first store the read/write data in this array, and then fetch the data in the array. This is much faster than reading/writing data one by one, which is where buffered streams come in. But the buffer stream defines an array to store the data we read/write, and when the internal array is full (note: when we operate, the external array is still defined and the small array is put into the internal array), the next step is taken.

1.2 example

Byte buffer stream:

// Buffer the input stream in bytes
BufferedInputStream bis = new BufferedInputStream(
        new FileInputStream("io"+File.separator+"a.txt"));
// Define a byte array to store data
byte[] buffer = new byte[1024];
int len = -1;// Define an integer representing the number of bytes read
while((len=bis.read(buffer))! = -1){
    System.out.println(new String(buffer,0,len));
}
// Close the stream resourcebis.close(); <br><br>// Bytes buffer output stream
BufferedOutputStream bos = new BufferedOutputStream(
        new FileOutputStream("io"+File.separator+"a.txt"));
bos.write("ABCD".getBytes());
bos.close();
Copy the code

Character buffer stream:

// Character buffered input stream
BufferedReader br = new BufferedReader(
        new FileReader("io"+File.separator+"a.txt"));
         // This is a character array, not a byte stream
char[] buffer = new char[10];
int len = -1;
while((len=br.read(buffer))! = -1){
    System.out.println(new String(buffer,0,len));
}
br.close();

// Character buffered output stream
BufferedWriter bw = new BufferedWriter(
        new FileWriter("io"+File.separator+"a.txt"));
bw.write("ABCD");
bw.close();
Copy the code

2. Transformation flows

2.1 an overview of the

  • InputStreamReader: Converts a byte input stream to a character input stream
  • OutputStreamWriter: Converts a byte output stream to a character output stream
/** * Copy the a.txt file to b.txt */
// create source and target
File srcFile = new File("io"+File.separator+"a.txt");
File descFile = new File("io"+File.separator+"b.txt");
// create a byte input/output stream object
InputStream in = new FileInputStream(srcFile);
OutputStream out = new FileOutputStream(descFile);
// create a conversion input/output object
Reader rd = new InputStreamReader(in);
Writer wt = new OutputStreamWriter(out);
// read and write operations
char[] buffer = new char[10];// Create an array of 10 characters to store the read data
int len = -1;// Indicates how many characters have been read, or -1 indicates that the end of the file has been read
while((len=rd.read(buffer))! = -1){
    wt.write(buffer, 0, len);
}
// Close the stream resource
rd.close();
wt.close();
Copy the code

2.2 The difference between a transformation stream and a subclass

Found the following hierarchy: OutputStreamWriter: | – FileWriter:

InputStreamReader: |–FileReader;

OutputStreamWriter and InputStreamReader are Bridges between characters and bytes: you can also call them character conversion streams. Character conversion stream principle: byte stream + code table

  • InputStreamReader isr = new InputStreamReader(new FileInputStream(“a.txt”)); // Default character set.
  • InputStreamReader isr = new InputStreamReader(new FileInputStream(“a.txt”),”GBK”); // Specify the GBK character set.
  • FileReader fr = new FileReader(“a.txt”);

The function of these three sentences is the same, of which the third sentence is the most convenient.

Note: When specifying additional encodings, subclasses must never be used; character conversion streams must be used. When do you subclass?

  1. It’s a file.
  2. Use the default encoding.

3. Memory stream (array stream)

3.1 an overview of the

The data is stored temporarily in an array, that is, in memory, and then retrieved directly from memory when needed. Therefore, closing the memory stream is invalid, and the method of the class can still be called after closing it. Close () of the underlying source code is an empty method.

3.2 byte memory flow

  • ByteArrayOutputStream
  • ByteArrayInputStream
// Byte array output stream: program -- memory
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// Write data to memory
bos.write("ABCD".getBytes());
// Create a newly allocated byte array. The size is the current size of this output stream to which the valid contents of the buffer have been copied.
byte[] temp = bos.toByteArray();
System.out.println(new String(temp,0,temp.length));

byte[] buffer = new byte[10];
/// byte array input stream: memory -- "program
ByteArrayInputStream bis = new ByteArrayInputStream(temp);
int len = -1;
while((len=bis.read(buffer))! = -1){
    System.out.println(new String(buffer,0,len));
}

// It's ok not to write it here, because close() is an empty method body in the source code
bos.close();
bis.close();
Copy the code

3.3 Character memory stream

  • StringReader
  • StringWriter
// String output stream, the bottom layer is concatenated with StringBuffer
StringWriter sw = new StringWriter();
sw.write("ABCD");
sw.write("Smart pan");
System.out.println(sw.toString());/ / the ABCD smart pan

// String input stream
StringReader sr = new StringReader(sw.toString());
char[] buffer = new char[10];
int len = -1;
while((len=sr.read(buffer))! = -1){
    System.out.println(new String(buffer,0,len));/ / the ABCD smart pan
}
Copy the code

4. Combine the flow

To combine multiple input streams into a single stream, also called a sequential stream, because the first stream is read before the next stream is read.

// Define the byte input merge stream
SequenceInputStream seinput = new SequenceInputStream(
        new FileInputStream("io/a.txt"), new FileInputStream("io/b.txt"));
byte[] buffer = new byte[10];
int len = -1;
while((len=seinput.read(buffer))! = -1){
    System.out.println(new String(buffer,0,len));
}

seinput.close();
Copy the code

5. Object flow

For details on serialization and deserialization, see the article:

Serialization and deserialization


Reference: www.cnblogs.com/furaywww/p/…