1. Basic input streams and output streams <br />Flow is one of the most important basic concepts in Java. File reading and writing, network transmission and reception, process communication, and streaming is used in almost all places where input and output are required.
What is streaming used for? It is for input and output. Why do input and output use "stream"? Because the basic unit of program input and output is bytes, input is to obtain a string of bytes, and output is to send a string of bytes. However, in many cases, it is impossible for a program to receive all bytes before processing, but to receive a little bit of processing. For example, when you download World of Warcraft, it is impossible to download it all into memory and save it to the hard disk, but just download it and save it a little. At this time, this method is very suitable.
In Java, each stream is an object. There are two types of streams: input stream (InputStream) and output stream (OutputStream). For the input stream, you just need to keep taking out the bytes from the stream; for the output stream, you just need to pass the prepared byte string to it.
How are stream objects obtained? Different external systems also have different ways of obtaining streams. For example, when reading and writing files, you need to create a FileInputStream/FileOutputStream object, while network communication uses Socket objects to obtain input and output streams. Generally speaking, if a class has methods such as getInputStream() or getOutputStream(), it means that it is input and output through a stream object.
InputStream is an input stream. Here is an example of reading a file through InputStream:
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.FileNotFoundException ; import java.util.Arrays; /** * Read through stream File */ public class ReadFileDemo { // Program entry public static void main(String[] args) { String path = "c:/boot.ini"; File file = new File(path); // Create input stream Inpu tStream is ; try { is = new FileInputStream(file); } catch (FileNotFoundException e) { System.err.println("File" + path + "Not exist."); return; } // Start reading byte[] content = new byte[0]; // Save the read file content byte[] buffer = new byte[10240]; // Define the cache try { int eachTime = is.read(buffer); // The first time reading. If the return value is -1, it means there is no content to read. while (eachTime != -1) { // The read content is placed in the buffer, and now merge it into the content. content = concatByteArrays(content, buffer, eachTime); eachTime = is.read(buffer); // Continue to read} } catch (IOException e) { System.err.println("Read file content failed." ); e .printStackTrace(); } finally { try { is.close(); } catch (IOException e) { // The exceptions here can be ignored and not processed} } // The output file contentString contentStr = new String(content); Syst em. out.println(contentStr); } /** * Merge two byte strings* * @param bytes1 Byte string 1 * @param bytes2 Byte string 2 * @param sizeOfBytes2 The length that needs to be taken out from bytes2* * @return The result of the merge of the first sizeOfBytes2 bytes1 and bytes2*/ private static byte[] concatByteArrays(byte[] bytes1, byte[] bytes2, int sizeOfBytes2) { byte[] resu lt = Arrays.copyOf(bytes1, (bytes1 .length + sizeOfBytes2)); System.arraycopy(bytes2, 0, result, bytes1.length, sizeOfBytes2); return result; } }
Although it is very verbose, this is indeed the basic usage of InputStream. Note that this is just an example of how to read a byte string from the input stream. In fact, Java provides an easier way to read text files. It will be introduced later.
Using OutputStream output is a very simple thing than reading from a stream. Here is an example:
import java.io.OutputStream; import java.io.FileOutputStream; import java.io.File; import java.io.IOException; import java.util.Date; /** * Will the current Save date to file*/ public class SaveFileDemo { public static void main(String[] args) throws IOException { String path = "c:/now.txt"; File file = new File(path); if (!file.exists() && !file.createNe wFile() ) { System.err.println("File cannot be created."); return; } OutputStream os = new FileOutputStream(file); // Create output stream (provided that the file exists) os.write(new Date().toString( ).getBytes()); // Write the current time to the file os.close(); // The stream must be closed before the content will be written to the file. System.out.println("File writing is completed."); } }
Java also provides other streaming operations, but they all extend or wrapper InputStream and OutputStream. So these two classes are the basis and they must be understood.
2. Reader and Writer
InputStream and OutputStream are introduced, and then Reader and Writer are introduced. These two classes actually wrap InputStream and OutputStream. However, they process not bytes, but characters. If the contents in a stream are text, it will be easier to process with Reader/Writer. Here is an example of reading a text file using Reader:
import java.io.FileReader; import java.io.IOException; import java.io.Reader; /** * Read text file*/ public class ReadTextFileDemo { // Program entry public st atic void main(String[] args) { String path = "c:/boot.ini"; String content = ""; try { Reader reader = new FileReader(path); char[] buffer = new char[10240]; int count; while ((count = reader. read(buffer)) != -1) { content += new String(buffer, 0, count); } } catch (IOException e) { System.err.println("Read file failed."); e.printStackTrace (); } System.out.println(content); } }
As for how to use Writer to write text content into a file, I won’t give an example here. Please try writing it yourself.
The above example is still not the most common way to read text files. Java provides a BufferedReader, which we usually use to read text files. Here is an example:
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; /** * Use BufferedReader to read text files*/ public class ReadTextDemo 2 { public static void main(String[] args) { String path = "c:/boot.ini"; String content = ""; try { BufferedReader reader = new BufferedReader(new FileReader(path)); String line; while ((line = reader.readLine() ) != null) { content += line + "/n"; } } catch (IOException e) { System.err.println("Read file failed."); e.printStackTrace(); } System.out.println(content); } }
3. Object serialization <br />Object serialization is also an important aspect of streaming applications. Serialization is to convert an object into a string of bytes, which can be saved or passed to another Java program for use. ObjectOutputStream and ObjectInputStream are specially used for serialization and deserialization. Here is a simple example:
import java.io.ObjectOutputStream; import java.io.FileOutputStream; import java.io.File; import java.io.IOException; import java.io.Serializab le; import java.io.ObjectInputStream; import java.io.FileInputStream; import java.io.EOFException; /** * ObjectOutputStream/ObjectInputStream Example. * These two classes are used for serialization and deserialization respectively. */ public class SerializationDemo { public static void main(String[] args) throws Exception { String path = "c:/persons.data"; File f = new File(path); if (!f.exists()) { f.createNewFile(); } writePersons(path); readPersons(path); } // Read Person object from the specified file private static void readPersons(String path) throws IOException, Clas sNotFoundException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream (path)); Person p; while (true) { try { p = (Person) ois.readObject(); System.out.println(p); } catch (EOFException e) { break; } } } // The Person object is saved to the specified file private static void writePersons(String path) throws IOException { Person[] persons = new Person[]{ new Person("Zhang San", 23), new Person("Li Si", 24 ) }; ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path)); for (Person person : persons) { oos.writeObject(person); } oos.close( ); } //////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Person implements Serializable { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.a ge = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '/'' + ", age=" + age + '}'; } } }
This example cannot read and write bytes and characters, because both classes are packaged. The above is just a simple example, and there are still many things to pay attention to if you want to write serialization well. If you want to have a deeper understanding of serialization, you can check it out here. This article only focuses on the parts related to streaming. In fact, serialization is rarely used because serialization reduces flexibility, so it is generally not used if you don’t use it.