Understand Java IO flows
Java IO stream is the basis of the implementation of input/output, it can facilitate the implementation of data input/output operations, in Java, different input/output sources (keyboard, file, network connection, etc.) abstract into the expression of “flow”.
Classification of streams
1. Byte stream and character stream
- InputStream
- Reader
- OutputStream
- Writer
The two flow the usage of the basic similar, mainly is the manipulation of data, different byte stream operation is a byte, are those binaries, and characters of the flow will deal with our general to identify these characters text file, byte stream processing 8-bit bytes, characters, stream processing characters of 16 bytes (a character in the Java 2 bytes)
2. Node flow and processing flow
Node flow: A stream used to read and write data, sometimes referred to as a low-level stream because it is less efficient to execute
Processing stream: It encapsulates an existing stream to perform operations such as reading and writing. This is called a high-level stream
So how do we tell if a stream is a node stream or a process stream?
The construction parameter of a node flow is usually a physical address, while the construction parameter of a processing flow is usually an object of the flow
3. Input streams and output streams
Input stream: As the name implies, the ability to read data from a specified object
Output stream: Output data to a specified location
The general direction of the input stream is from the outside to the program
The output stream is from the execution program to the outside of memory
Four base classes for input and output streams:
- InputStream
- Reader
- OutStream
- Writer
These four classes are abstract and cannot instantiate objects. We usually create subclasses of them, and there are many accessors available in these four classes
Byte stream and character stream
So with that in mind, let’s focus on the use of these two streams
The input stream:
InputStream method:
- Int read () : Reads a single byte from the input stream, returning the read byte of data
- Int read (byte[] arr) : Reads data from the input stream and stores it in the byte array arR. Returns the number of bytes read and -1 when the data is read
- Int read (byte[] arr, int OFF, int length) : Reads length bytes from the input stream into an array of bytes, starting at the off position of the array
Reader methods:
- Int read () : Reads a single character from the input stream, returning the ASCII encoding of the character
- Int read (char[] arr) : Reads data from the input stream into the ARR character array
- Int read (char[] arr, int off, int length) : Reads the length character from the input stream into the character array, starting with the array subscript off
Example: Read the java.txt file as bytes and print it to the console
// using Java7 features, there is no need to manually close resources
try(FileInputStream fis=new FileInputStream("Java.txt")) {byte[] arr=new byte[1024];
int hasRead;
while((hasRead=fis.read(arr))>0){
System.out.println(new String(arr,0,hasRead)); }}Copy the code
Note: there is sometimes a problem here, when we sometimes read incomplete encoding, that is, the byte of a character is read twice, there may be a garble problem, when printing, if simply copying the text is no problem.
try(FileReader fr=new FileReader("Java.txt")) {char[] arr=new char[1024];
int hasRead;
while((hasRead=fr.read(arr))>0){
System.out.println(new String(arr,0,hasRead)); }}Copy the code
The output stream:
The OutputStream method:
- Void write (int a) : outputs the specified byte to the output stream, where a can be either a byte or a character
- Void write (byte[]/char[] arr) : Writes data from byte arrays or character arrays to the output stream
- Void write (byte[]/char[] arr, int OFF, int length) : Write (byte[]/char[] arr, int OFF, int length) to the output stream
Writer’s method:
- Void write (String String) : Stores the String String to the output stream
- Void write (String String, int off, int length) : Outputs a String of specified length to the output stream
Example: Copy the contents of the java. TXT file to the java2.txt file
try(
FileInputStream fis=new FileInputStream("Java.txt");
FileOutputStream fos=new FileOutputStream("Java2.txt"); {byte[] arr=new byte[1024];
int hasRead;
while((hasRead=fis.read(arr))>0){
fos.write(arr,0,hasRead); }}Copy the code
Normally, we’re dealing with characters in a character stream, or a byte stream, because byte streams are more versatile, and characters are converted from binary
How to use processing streams
Processing flow: Wrapping existing flow objects can improve the efficiency of processing data and make it easier for some data operations
Let’s talk about a very powerful stream called PrintStream, which is essentially a byte stream, which is a processing stream that we use to output data, and if we want to output text, we should wrap the output stream as PrintStream output
1. First we will create an output stream object
2. Create a print stream object, pass in parameters, and wrap the output stream
Example:
try(
FileOutputStream fos=new FileOutputStream("Java.txt");
PrintStream ps=new PrintStream(fos);
)
{
ps.println("Hello, tomorrow.");
ps.println(new Date());
}
Copy the code
The effect of this code execution is to print the string hello tomorrow and an instance object of the Date class to a java.txt file
Note: When we close the processing stream, the stream it wraps will also close
Transformation flows
Java provides two transformation flows
- InputStreamReader: Converts a byte input stream into a character input stream
- OutputStreamReader: Converts a byte output stream into a character output stream
We’ll do one thing: in Java, System.in stands for standard input, the keyboard, and System.out stands for standard output, the console
Sometimes we can turn a byte input stream into a character input stream
Example: In this example we convert system. in to a character input stream, and then use BufferedReader to process the stream wrapper to speed up efficiency
try(
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
)
{
String line=null;
while((line=br.readLine())! =null) {if("exit".equals(line)){
break;
}else{ System.out.println(line); }}}Copy the code
This code first converts the standard input stream into a character input stream, then wraps it in a buffered stream,
The buffered stream has a readLine method that reads an entire line, in this case from the keyboard, to loop through
Redirect to the standard I/O stream
With Java we often read what we want from the keyboard via system.in or output data to the console using system.out, but sometimes we want to read from text, or save the data to text instead of printing it to the console. What do we do?
Class methods are provided in the System class:
- Void setIn (InputStream in) : redirect to the standard InputStream and get data from the stream specified by in instead of the keyboard
- Void setOut (PrintStream out) : Repoints to the standard output stream and prints the output to the out output stream instead of the console
Example:
try(
PrintStream ps=new PrintStream(new FileOutputStream("Java.txt")); { System.setOut(ps); System.out.println("Hello tomorrow.");
System.out.println(new Date());
}
Copy the code
In this code, the standard output of the System refers to the stream specified by PrintStream, so the output of subsequent system.out.println operations will enter the text instead of being displayed on the console. You can also write data to text using ps.println()
Example:
try(
FileInputStream fis=new FileInputStream("Java.txt"); { System.setIn(fis); Scanner sc=new Scanner(System.in);
sc.useDelimiter("\n");
while(sc.hasNext()){ System.out.println(sc.next()); }}Copy the code
This code respecifies standard input, not from the keyboard, but from the text, using a loop to constantly determine if the text has any data, and if so, to read
sc.useDelimiter("\n");
Copy the code
This means that the content is delimited by carriage return, otherwise it is delimited by space by default
Powerful stream: RandomAccessFile stream
The RandomAccessFile stream is a rich Java stream that can read and write data arbitrarily, which supports “random access”.
We can use this stream when we don’t need to read all of the data, but only part of it
But it has a disadvantage, it can only manipulate text files, not other streams
Since it can be read arbitrarily, it means that there is an internal pointer to the current file location
- Long getFilePointer () : Returns the current position of the file pointer
- Void seek (long pos) : moves the file pointer to pos
It has several read and write modes:
- R: Open the file in read-only mode
- Rw: Opens the file in both read and write mode, if not created automatically
Example: Read part of the data in the java. TXT file
try(
RandomAccessFile raf=new RandomAccessFile("Java.txt"."r"); { raf.seek(100);
byte[] arr=new byte[1024];
int hasRead;
while((has=raf.read(arr))>0){
System.out.println(new String(arr,0,hasRead)); }}Copy the code
It has all the methods for basic input and output streams.
Example: Append files to files
try(
RandomAccessFile raf=new RandomAccessFile("Java.txt"); { raf.seek(raf.length()); raf.write("Append text");
}
Copy the code
Point to the end of the file and continue writing data
So how do we implement insert data? When we change the pointer to the specified position and write data, the following data will be overwritten, so we need to save this part of the file and then restore
File tempFile=File.createTempFile("temp.txt".null);
tempFile.deleteOnExit();
try(
RandomAccessFile raf=new RandomAccessFile(fileName,"rw");
FileInputStream fis=new FileInputStream(tempFile);
FileOutputStream fos=new FileOutputStream(tempFile);
)
{
raf.seek(pos);
byte[] arr=new byte[1024];
int hasRead;
while((hasRead=raf.read(arr))>0){
fos.write(arr,0,hasRead);
}
raf.seek(pos);
raf.write(InsertContent.getBytes());// Convert a string to a byte array
while((hasRead=fis.read(arr))>0){
raf.write(arr,0,hasRead); }}Copy the code
In the above code we define a temporary file and specify that it will be deleted automatically when the program ends
We first record the text after the insertion position into a temporary file, and then we insert the content we want to insert
We then write the contents of the temporary file back into the file to complete the insert operation
Note:
We can also append files to text in this way:
FileWriter fw=new FileWriter("Java.txt".true);
Copy the code
The last parameter indicates whether to append data