preface
In the last article to get a good number of page views, the idea of continuing to add more has been wandering in mind, originally wanted to spend some time to in-depth study of Tomcat, but tomcat source code has a vital NIO, so have to first complete NIO, but NIO is based on BIO, so this article will first write IO flow.
Learn NIO(non-blocking IO), do not block IO wow!
I/O streams are an important part of Java, but it’s easy to overlook because there’s so little code that actually writes I/O at work.
The difficulty with IO is
- IO stream API many, various basic streams, wrapped streams nested use is difficult to remember
- Basically every method throws a non-runtime exception
As a result, many developers who have learned IO streams for a period of time cannot write the correct IO stream code.
This article will take you to learn IO flow from the theory + code way, through the graphical way to memorize common IO flow.
At the end of the article, there is a mind map summarized by IO. Many blog posts use the previous one. I think it is easy for readers to get stuck in it.
File
The File class is mainly an abstract representation of files and directories. Because the first response to learning IO streams is files, this class provides operations such as creating, deleting, and searching files. The main features are as follows
- In Java, where everything is an object, files and directories can be abstracted as File objects
- In the case of File, the wrapper is not really a File, it is just a pathname, and the disk File itself may or may not exist
- The contents of a File cannot be read by File, but by stream. File objects can serve as the source and destination of streams
A common constructor for the File class
A constructor | Method statement |
---|---|
File(String pathname) | Abstract the path string, which can be a relative or absolute path, to a File instance |
File(String parent, String child) | Build File instances from parent and child pathnames |
File(File parent, String child) | Build a File instance based on the parent File instance and child path name |
The following example shows the code for these files and directories
// pathname
File liuBei = new File("D:/ Three Kingdoms/LiuBei.jpg");
// String parent, String child
File guanYu = new File("D: / in The Three Kingdoms"."Guan yu. JPG");
/ / directory
File sanGuo = new File("D: / in The Three Kingdoms");
// File parent, String child
File zhangFei = new File(sanGuo, "Zhang fei. TXT");
// You can declare a file that does not exist
File zhuGeLiang = new File(sanGuo, "Zhuge Liang. TXT");
Copy the code
Absolute path and relative path
Absolute path: indicates a complete path starting from the drive letter. (Often used) Relative path: Path relative to the current project directory
File f = new File("D:/bbb.java");
// D:\bbb.java
System.out.println(f.getAbsolutePath());
File f2 = new File("bbb.java");
// F:\code\ad\bbb.java
System.out.println(f2.getAbsolutePath());
Copy the code
Path separator and newline character
Path separator
- Windows path separator: \
- Linux path separator: /
Java has the constant separator for the path separator
public static final String separator = "" + separatorChar;
Copy the code
A newline
- Windows newline: \r\n
- Linux newline character \n
Common methods of File
Create, delete
The method name | Method statement |
---|---|
boolean createNewFile() throws IOException | Creates an empty file with the abstract pathname and returns true if the file does not exist, or false if the file does exist |
boolean mkdir() | Create a directory named by this abstract pathname |
boolean mkdirs() | Create directories named by this abstract pathname, including any required but nonexistent parent directories. Create directories in cascades |
boolean delete() | Deletes the file or directory represented by this abstract pathname |
The above method is relatively simple, but it needs to be noted that
- When creating a multilevel directory, return false if mkdir fails and true if mkdirs succeeds (mkdirs is recommended).
- If the directory is not empty, the deletion fails. False is returned, that is, only files or empty directories can be deleted
File shuiHu = new File("D:/ The Four Great Novels/outlaws of the Marsh");
// Return false creation failed
boolean mkdir = shuiHu.mkdir();
// Return true creation failed
boolean mkdirs = shuiHu.mkdirs();
File four = new File("D:/ The Four Great Classics");
// False The directory can be deleted successfully only when the directory is empty
boolean delete = four.delete();
File shuiHu = new File("D:/ The Four Great Novels/outlaws of the Marsh");
// true deletes the water Margin directory correctly
boolean delete1 = shuiHu.delete();
File liuBei = new File("D:/ Three Kingdoms/LiuBei.jpg");
// Return true the liube.jpg file was deleted correctly
boolean delete2 = liuBei.delete();
Copy the code
File detection
The method name | Method statement |
---|---|
boolean isDirectory() | Check whether it is a directory |
boolean isFile() | Check whether it is a file |
boolean exists() | Check whether a file or directory exists |
boolean canWrite() | Whether the file is writable |
boolean canRead() | Whether the file is readable |
boolean canExecute() | Whether the file is executable |
long lastModified() | Returns the last time the file was modified |
Pay attention to is
- IsDirectory () or isFile() returns false if the file or directory does not exist
- Read, write, and execute permissions are granted to files by the operating system
File xiYou = new File(D:/ Journey to the West);
// Return false if the file or directory does not exist
System.out.println(xiYou.isDirectory());
Copy the code
File access
The method name | Method statement |
---|---|
String getAbsolutePath() | Returns the absolute path string of the File object |
String getPath() | Convert this abstract pathname to a pathname string |
String getName() | Returns the name of a file or directory |
long length() | Returns the number of bytes of the File represented by this File |
String[] list() | Returns a string array of files and directory names in a directory |
File[] listFiles() | Returns an array of files in a directory and a directory’s File objects |
Pay attention to
- Length () returns the number of bytes in the file, and the length of the directory is 0
- GetPath () is the same for files represented by absolute paths, but different for files represented by relative paths
- Calls to the listFiles and list methods must be actual directories, otherwise null is returned
- ListFiles and list can be passed into the FilenameFilter implementation class to filter files by file name
File shuiHu = new File("D:/ water margin");
/ / 0
System.out.println(shuiHu.length());
File liuBei = new File("D:/ Three Kingdoms/LiuBei.jpg");
/ / 24591
System.out.println(liuBei.length());
File f = new File("D:/bbb.java");
// D:\bbb.java
System.out.println(f.getPath());
File f2 = new File("bbb.java");
// bbb.java
System.out.println(f2.getPath());
File sanGuo2 = new File("D: / 2 of The Three Kingdoms");
// The directory does not exist, null is returned
String[] list = sanGuo2.list();
Copy the code
Interface for filtering files
@FunctionalInterface
public interface FilenameFilter {
// Take the directory and specify the filter name
boolean accept(File dir, String name);
}
Copy the code
Extension (implemented by the reader)
Read all files and directories under a directory, including all files and directories under subdirectories
IO stream
In the previous section, you learned how to use the File class to create, find, and delete files, but not to read or transfer the contents of a File.
IO streams are used to read, transmit, and write data.
I: input, O: the output
The main body here is talking about the program (that is, memory), reading data from the external device into the program is the input stream, from the program to write to the external program is the output stream
The classification of the IO
-
Local IO and network IO
Local I/O is used to operate local files. For example, you can copy and paste operation files on the Windows operating system using Java I/O
Network IO is used to send data or upload or download files over the network. We experience IO transmission all the time when we surf the Internet every day
-
Divided by direction, input flow and output flow
-
Divided by data type: byte stream and character stream
-
By function: node flow and processing flow
- Classes in which programs operate directly on target devices are called node flows
- The node flow is decorated and enhanced in function and performance, which is called the processing flow
The main entry point of AN I/O stream is a data source. Common source and destination devices are listed below
The source device
- Hard disk (file)
- Memory (byte arrays, strings, etc.)
- The network (Socket)
- The keyboard (System.) in
Purpose equipment
- Hard disk (file)
- Memory (byte arrays, strings, etc.)
- The network (Socket)
- The console System. (out)
This article first explores byte streams and character streams of local IO, and first enumerates common methods for byte streams and character streams
The method name | Method statement |
---|---|
void close() throws IOException | After a stream operation is complete, system resources must be released and the close method called, usually ina finally block, is guaranteed to be executed! |
Note:
- The I/O resources opened in the program do not belong to memory resources and cannot be reclaimed by the garbage collection mechanism. Therefore, you need to explicitly disable file resources
- The following code example does not explicitly call the close method and does not handle IOException, just for the sake of brevity and ease of reading
Byte stream
Everything is a byte
All file data (text, pictures, video, etc.) is stored in binary format and can be transmitted using a byte stream.
InputStream is the top-level abstraction of a byte InputStream
// Closeable has the close() method
public abstract class InputStream implements Closeable {}
Copy the code
The core approach is as follows
The method name | Method statement |
---|---|
int read() throws IOException; | Read one byte at a time, promoted to int, and return -1 at the end of the file |
int read(byte b[])throws IOException | Returns the number of bytes read each time a byte array is read, and -1 at the end (common) |
int read(byte b[], int off, int len) | Each read into the byte array, starting with offset off and length len, returns the number of valid bytes read and -1 at the end of the read |
OutputStream is the top-level abstraction of a byte OutputStream
// Flushable has the flush() method
public abstract class OutputStream implements Closeable.Flushable {}
Copy the code
The core approach is as follows
The method name | Method statement |
---|---|
void write(int b) throws IOException; | Writes an int value to the output stream |
void write(byte[] b) throws IOException; | Writes an array of bytes to the output stream |
void write(byte b[], int off, int len) throws IOException | Writes the byte array to the output stream by len lengths, starting with the offset off |
void flush() throws IOException | Flushes the output stream and forces buffered bytes to be written out |
File node flow
InputStream has a number of implementation classes. Let’s start with file node streams. The target device is a file
FileInputStream and FileOutputStream
A FileInputStream reads data from a disk file
public FileInputStream(File file) throws FileNotFoundException{}
public FileInputStream(String name) throws FileNotFoundException{};
Copy the code
The runtime throws a FileNotFoundException when the incoming file does not exist
- The read() method reads
File file = new File("D:/ three Kingdoms/Zhuge Liang.txt");
FileInputStream fileInputStream = new FileInputStream(file);
// Core code
int b;
while((b = fileInputStream.read()) ! = -1 ){
System.out.print((char) b);
}
// Output the result
abcde
Copy the code
- Read the read (byte [])
File file = new File("D:/ three Kingdoms/Zhuge Liang.txt");
FileInputStream fileInputStream = new FileInputStream(file);
// Core code
byte[] data = new byte[2];
while(fileInputStream.read(data) ! = -1) {
System.out.println(new String(data));
}
// Output the result
ab
cd
ed
Copy the code
Because the last time I read the above code, I only read a byte e, and the array is the same as the previous data CD, only replacing e, so I finally output Ed
Here is the correct pose read using FileInputStream
File file = new File("D:/ three Kingdoms/Zhuge Liang.txt");
FileInputStream fileInputStream = new FileInputStream(file);
// Core code
byte[] data = new byte[2];
int len;
while((len = fileInputStream.read(data)) ! = -1) {
Len is the number of valid bytes read each time
System.out.println(new String(data, 0, len));
}
// Output the result
ab
cd
e
Copy the code
Note: The use of array read, read multiple bytes each time, reduce the number of IO operations between systems, thus improving efficiency, recommended use
The source code parsing
public int read(a) throws IOException {
return read0();
}
private native int read0(a) throws IOException;
public int read(byte b[]) throws IOException {
return readBytes(b, 0, b.length);
}
private native int readBytes(byte b[], int off, int len) throws IOException;
Copy the code
The source code for read() and read(byte[]) is listed above, which can be seen as calling native methods, involving underlying system calls.
-
If you read a file with read(), the hard disk is accessed once for every byte read, which is less efficient.
-
If a file is read with read(byte[]), multiple bytes are read at a time. If the file is large, the hard disk is accessed frequently. If you read too many bytes at a time, it is not efficient.
A FileOutputStream writes data to a disk file
Constructor name | Method statement |
---|---|
FileOutputStream(File file) throws FileNotFoundException | Build a FileOutputStream using a File object |
FileInputStream(String name) throws FileNotFoundException | Build a FileOutputStream using a filename |
FileOutputStream(File file, boolean append) throws FileNotFoundException | When append passes true, the file is appended |
FileOutputStream(String name, boolean append) throws FileNotFoundException | When append passes true, the file is appended |
Note:
-
After the above constructor is executed, the file is automatically created if it does not exist
-
If file exists and Append does not pass it or passes false, it clears the file’s data
-
If file exists, Append passes true and does not clear the file’s data
File file = new File("D:/ three Kingdoms/zhaoyun.txt");
FileOutputStream fos = new FileOutputStream(file);
FileOutputStream fos1 = new FileOutputStream("D:/ three Kingdoms/Sima Yi.txt");
TXT and sima yi.txt will be created automatically after the above code is executed
Copy the code
Write data to a file
FileOutputStream fos = new FileOutputStream("D:/ three Kingdoms/Sima Yi.txt");
fos.write(96);
fos.write(97);
fos.write(98);
// The file content is ABC
FileOutputStream fos = new FileOutputStream("D:/ three Kingdoms/zhaoyun.txt");
fos.write("Zhao Yun of The Three Kingdoms".getBytes());
// The content of the document is Zhao Yun of The Three Kingdoms
Copy the code
Each time the above code is executed, the contents of the file will be overwritten. Sometimes this is not the scenario we want, we usually want to append the file
FileOutputStream fos = new FileOutputStream("D:/ three Kingdoms/zhaoyun.txt".true);
fos.write("I have the courage to do something wrong.".getBytes());
fos.close();
// The content of the document is that Zhao Yun of The Three Kingdoms has the courage of thousands of men
Copy the code
Application scenarios
The development of files involved in the upload, download, transfer are used in this node flow, will be used together with the decorated processing flow, described in the buffer flow section.
Extension (implemented by the reader)
File node stream is used to copy files
Memory node flow
ByteArrayInputStream reads data from an array of bytes in memory
public ByteArrayInputStream(byte buf[]) {}
Copy the code
Note: There is no need to close the data source and throw IOException because no underlying system calls are involved
ByteArrayOutputStream writes data to an array of bytes in memory and maintains an array internally
public ByteArrayOutputStream(a) {
// A mutable byte array is maintained internally
// protected byte buf[];
this(32);
}
Copy the code
Memory node flow code example
ByteArrayInputStream bis = new ByteArrayInputStream("data".getBytes());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int len = 0;
while((len = bis.read()) ! = -1){
bos.write(len);
}
/ / output data
System.out.println(new String(bos.toByteArray()));
Copy the code
Application scenarios
- The flow of in-memory operations is usually used when some temporary information is generated, and if temporary information is stored in a file, it can be troublesome to delete the file after code execution
- In combination with object streams, object and byte arrays can be exchanged
Characters of the flow
Character streams encapsulate methods more suitable for manipulating text characters
Reader is used to read text characters
public abstract class Reader implements Readable.Closeable {}
Copy the code
Core method
The method name | Method statement |
---|---|
int read() throws IOException | Reads a character from the input stream, returning -1 at the end of the file |
int read(char cbuf[]) throws IOException | Reads characters from the input stream into a char array |
Writer is used to write text characters
public abstract class Writer implements Appendable.Closeable.Flushable {}
Copy the code
Core method
The method name | Method statement |
---|---|
void write(int c) throws IOException | Writes a single character to the output stream |
void write(char[] cbuf) throws IOException | Writes an array of characters to the output stream |
void write(char[] cbuf, int off, int len) throws IOException | Writes a portion of the character array, starting with offset off and length len, to the output stream |
void write(String str) throws IOException | Write a string directly to the output stream (common) |
void write(String str, int off, int len) throws IOException | Writes part of a string, starting with offsets off and length len |
Writer append(char c) throws IOException | Appends characters to the output stream |
File node flow
Character streams are most suitable for files that operate on plain text characters, mainly FileReader and FileWriter
A FileReader writes data to a disk file
public FileReader(String fileName) throws FileNotFoundException{}
public FileReader(File file) throws FileNotFoundException {}
Copy the code
Note: A FileNotFoundException is thrown when the read file does not exist, as with FileInputStream
- Read () loops through the file
FileReader fileReader = new FileReader("D:/ three Kingdoms/zhaoyun.txt");
int b;
while((b = fileReader.read()) ! = -1) {
System.out.println((char) b);
}
Copy the code
- Read (char[]) Reads the file
FileReader fileReader = new FileReader("D:/ three Kingdoms/zhaoyun.txt");
int len;
char[] data = new char[2];
while((len = fileReader.read(data)) ! = -1) {
System.out.println(new String(data, 0, len));
}
// Two characters are read in sequence
Copy the code
The FileWriter constructor is similar to the FileOutStream constructor and FileOutputStream constructor.
public FileWriter(String fileName) throws IOException {}
public FileWriter(String fileName, boolean append) throws IOException {}
public FileWriter(File file) throws IOException{}
public FileWriter(File file, boolean append) throws IOException {}
Copy the code
A common method of writing data to a file
FileWriter fileWriter = new FileWriter("D:/ three Kingdoms/sunquan.txt");
fileWriter.write(97);
fileWriter.write('b');
fileWriter.write('C');
fileWriter.write("Right");
fileWriter.append("Force");
Copy the code
Note:
- If the close() or flush() methods are not performed, the data is only saved to the buffer, not to a file. This is different from FileOutputStream for the reason described in the common section of byte streams and character streams
Application scenarios
Plain text file IO operation, with the processing stream together to achieve.
Memory node flow
Character streams also have in-memory node streams, such as StringWriter and CharArrayWriter
A StringWriter writes data to an internal StringBuffer object.
/ / define
public class StringWriter extends Writer {
private StringBuffer buf;
public StringWriter(a) {
buf = newStringBuffer(); lock = buf; }}/ / application
StringWriter sw = new StringWriter();
sw.write("hello");
StringBuffer buffer = sw.getBuffer();
Hello / / output
System.out.println(buffer.toString());
Copy the code
A CharArrayWriter writes data to an internal char array
/ / define
public class CharArrayWriter extends Writer {
protected char buf[];
}
/ / application
CharArrayWriter caw = new CharArrayWriter();
caw.write("hello");
char[] chars = caw.toCharArray();
for (char c : chars) {
// output h e L L o
System.out.println(c);
}
Copy the code
A summary of the use of four common node flows
Common ground of byte stream and character stream
Flushable OutputStream Flushable Writer Flushable OutputStream Flushable Writer Flushable
Flush () : Forces the buffer to be flushed to the destination, after which the stream object can continue to be used
Close (): The resource is closed after the buffer is flushed forcibly. The stream object can no longer be used after the resource is closed
Buffer: can be understood as a memory area, when the program frequently operates on resources (such as files), the performance is low, because the read and write memory is fast, use the memory to buffer part of the data, do not frequently access system resources, is a way to improve efficiency
Streams that maintain buffers must be either close() or flush(), otherwise they will not be printed to the file
Processing flow
The sections above describe common node flows for byte streams and character streams, but real development uses more powerful processing flows
Processing flows are enhancements to node flows in terms of functionality and performance
The base classes for byte stream processing are FilterInputStream and FilterOutputStream
Buffer flow (emphasis)
Said in front of the node flow, are direct use of the underlying operating system method to read the data in the hard disk, the buffer flow is a kind of implementation process flow, enhance the performance of the node flow, in order to improve the efficiency, the buffer stream class at the time of initialization object, inside there is a buffer array, a one-time reading data from the underlying stream into an array, When a program executes read() or read(byte[]), it reads data directly from an in-memory array.
classification
Byte buffer stream: BufferedInputStream, BufferedOutputStream
Character buffer streams: BufferedReader, BufferedWriter
Byte buffer stream
The visible constructor passes in a node stream and decorates it
// Internal default 8192 =8*1024, that is, 8M buffer
public BufferedInputStream(InputStream in) {
/ / 8192
// The following byte array is maintained internally
// protected volatile byte buf[];
this(in, DEFAULT_BUFFER_SIZE);
}
public BufferedOutputStream(OutputStream out) {
this(out, 8192);
}
Copy the code
To feel the power of the buffering flow, use a copy of a 1-gigabyte movie
- Read data using basic streams (transferring one byte at a time)
long start = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("D:/ Three Kingdoms/video.mp4");
FileOutputStream fos = new FileOutputStream("D:/ three kingdoms/copy.mp4");
int data;
while((data = fis.read()) ! = -1) {
fos.write(data);
}
log.info("Copy movie time :{}ms", System.currentTimeMillis() - start);
// It is not ready in 5 minutes.
Copy the code
- Read data using basic streams (transferring a 8M byte array at a time)
long start = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("D:/ Three Kingdoms/video.mp4");
FileOutputStream fos = new FileOutputStream("D:/ three kingdoms/copy.mp4");
int len;
byte[] data = new byte[1024 * 1024 * 1024];
while((len = fis.read(data)) ! = -1) {
fos.write(data, 0, len);
}
log.info("Copy movie time :{}ms", System.currentTimeMillis() - start);
// Copy movie time :4651ms
Copy the code
- Read data using buffered streams (transferring one byte at a time)
long start = System.currentTimeMillis();
BufferedInputStream fis = new BufferedInputStream(new FileInputStream("D:/ Three Kingdoms/video.mp4"));
BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream("D:/ three kingdoms/copy.mp4"));
int data;
while((data = fis.read()) ! = -1) {
fos.write(data);
}
log.info("Copy movie time :{}ms", System.currentTimeMillis() - start);
// Copy movie time: 39,033ms
Copy the code
- Read data using buffered streams (transferring a 8M byte array at a time)(most often used)
long start = System.currentTimeMillis();
BufferedInputStream fis = new BufferedInputStream(new FileInputStream("D:/ Three Kingdoms/video.mp4"));
BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream("D:/ three kingdoms/copy.mp4"));
int len;
byte[] data = new byte[8 * 1024];
while((len = fis.read(data)) ! = -1) {
fos.write(data, 0, len);
}
log.info("Copy movie time :{}ms", System.currentTimeMillis() - start);
// Copy movie time :1946ms
Copy the code
From the four examples above, you can conclude that a buffered stream reads data much faster than a normal stream!
Note: the use of read and write mode, a transmission of several megabytes of data efficiency is relatively high, if the first file data are read into memory, in writing, so the number of read and write is small, but occupy too much memory space, a read too large data also seriously affect efficiency!
Character buffer stream
To decorate the character node stream, here is the constructor of the character buffer stream
public BufferedReader(Reader in) {
// private static int defaultCharBufferSize = 8192;
// An array of characters is maintained internally
// private char cb[];
this(in, defaultCharBufferSize);
}
public BufferedWriter(Writer out) {
this(out, defaultCharBufferSize);
}
Copy the code
A unique method for character-buffering streams
class | The method name | Method statement |
---|---|---|
BufferedReader | String readLine() throws IOException | Read line by line and return NULL on the last line |
BufferedWriter | void newLine() throws IOException | Write a line break to the file to implement a line break |
// Create a stream object
BufferedReader br = new BufferedReader(new FileReader("D:/ three Kingdoms/zhaoyun.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("D:/ three Kingdoms/Zhao Zilong.txt"));
String line = null;
while((line = br.readLine())! =null) {
System.out.println(line);
bw.write(line);
bw.newLine();
}
/ / the resultI am Zhao Zilong of Changshan, the head of a generalCopy the code
Correct posture for buffering flow
Buffer flow is the most important knowledge in IO flow, the following code to achieve the correct IO flow posture
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(new File("D:/ Three Kingdoms/video.mp4")));
bos = new BufferedOutputStream(new FileOutputStream(new File("D:/ three kingdoms/copy.mp4")));
int len;
// Transfer 8M files at a time. The actual test does not affect the transfer speed
byte[] data = new byte[8 * 1024];
while((len = bis.read(data)) ! = -1) {
bos.write(data, 0, len); }}catch (IOException e) {
log.error("error", e);
} finally {
// Finally block to close the stream to ensure that the resource must be closed
if(bis ! =null) {
try {
bis.close();
} catch (IOException e) {
log.error("error", e); }}if(bos ! =null) {
try {
bos.close();
} catch (IOException e) {
log.error("error", e); }}}Copy the code
Transformation flows
Character encoding and character set
A character encoding
The data stored in the computer is binary, and the numbers, English, Chinese characters and so on we see on the computer are the result of binary conversion
-
To convert a character into a binary, to an encoding
-
Convert binary to characters for decoding
Character encoding is the rule of correspondence between natural language and binary
Character set
ASCII character set, GBK character set, Unicode character set, etc., the specific introduction of each encoding is not introduced here.
IDEA, use FileReader to read text files in the project. IDEA can be set to GBK encoding, and garbled characters appear when reading the default UTF8 text file created in Windows systems.
The following example
The default character set of IDEA is UTF-8. Here change the character set to GBK
Running code and results
FileReader fileReader = new FileReader("D:/sanguo/utf8.txt");
int read;
while((read = fileReader.read()) ! = -1) {
System.out.print((char)read);
}
/ / huan 犲 ソ
Copy the code
InputStreamReader
A subclass of Reader that reads bytes and decodes them into characters using the specified character set. The character set can be customized or the platform’s default character set can be used.
The construction is as follows
// Use the platform default character set
public InputStreamReader(InputStream in) {}
// Specify a character set
public InputStreamReader(InputStream in, String charsetName)
throws UnsupportedEncodingException{}
Copy the code
Read “hello” from a file whose default character set is UTF8
// Create a stream object with UTF8 encoding by default
InputStreamReader isr = new InputStreamReader(new FileInputStream("D: / / utf8 kingdoms. TXT"));
// Create a stream object with GBK encoding
InputStreamReader isr2 = new InputStreamReader(new FileInputStream("D: / / utf8 kingdoms. TXT"), "GBK");
int read;
while((read = isr.read()) ! = -1) {
System.out.println((char) read);
}
while((read = isr2.read()) ! = -1) {
System.out.println((char) read);
}
// Output the resultHello huan 犲ソCopy the code
OutputStreamWriter
A subclass of Writer that encodes characters into bytes using the specified character set. The character set can be customized or the platform’s default character set can be used.
The construction is as follows
// Use the platform default character set
public OutputStreamWriter(OutputStream out) {}
// Use the platform default character set
public OutputStreamWriter(OutputStream out, String charsetName)
throws UnsupportedEncodingException{}
Copy the code
The following code, write hello to the file. The character sets and file sizes of the two files are different
// Create a stream object with UTF8 encoding by default
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:/ three Kingdoms/huang Zhong.txt"));
osw.write("Hello"); // Save to 6 bytes
// Create a stream object with GBK encoding
OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("D:/ three Kingdoms/machao.txt"),"GBK");
osw2.write("Hello");// Save to 4 bytes
Copy the code
Object flow
serialization
The JDK provides an object serialization mechanism that converts an object into a binary stream, which includes the data of the object, its type, and its properties. Java objects can be converted to binary streams and written to files. The file persists information about the object.
Similarly, reading information about an object from a file is a deserialization process
The object to be serialized satisfies the following conditions:
- The class must implement the java.io.Serializable interface.Serializable is a markup interface (without any abstract methods). Classes that do not implement this interface will not serialize or deserialize any state and will throw NotSerializableException.
- All attributes of the class must be serializable. If one attribute does not need to be serializable, it is decorated with the TRANSIENT keyword
ObjectOutputStream
This class implements the serialization of objects to external devices, such as hard disk files
public ObjectOutputStream(OutputStream out) throws IOException{}
Copy the code
Commonly used method
The method name | Method statement |
---|---|
void writeObject(Object obj) throws IOException | Writes out the specified object |
The following code writes the User object to a file
public class User implements Serializable {
private static final long serialVersionUID = 8289102797441171947L;
private String name;
private Integer age;
}
// Here is the core code for exporting the object to a file
User user = new User("D".20);
// Create a serialized stream object
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:/ three Kingdoms/machao.txt"));
// Write out the object
out.writeObject(user);
Copy the code
Note:
- A Serializable entity must add a serialVersionUID variable to the Serializable entity.
- Do not change serialVersionUID after it is generated to avoid deserialization failure. If it is changed, an InvalidClassException will be thrown
The content of the generated file is as follows
ObjectInputStream
This class deserializes the object written by ObjectOutputStream into A Java object
public ObjectInputStream(InputStream in) throws IOException
Copy the code
Commonly used method
The method name | Method statement |
---|---|
Object readObject() throws IOException, ClassNotFoundException | Read the object |
ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:/ three Kingdoms/machao.txt"));
// Force to user
User user = (User) in.readObject();
System.out.println(user);
// Output the contentUser(name= ma Chao, age=20)
Copy the code
Object and byte array conversion
Using a combination of object streams and byte array streams, Java objects and byte[] can be converted to each other
// Convert object to byte[]
public static <T> byte[] t1(T t) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(t);
return bos.toByteArray();
}
// Convert byte[] to an object
public static <T> T t2(byte[] data) throws IOException, ClassNotFoundException {
ByteArrayInputStream bos = new ByteArrayInputStream(data);
ObjectInputStream oos = new ObjectInputStream(bos);
return (T) oos.readObject();
}
Copy the code
Pipeline flow (Understanding)
A piped stream is mainly used for communication between two threads, that is, one thread sends data to the other thread through a piped stream
Note: Threads normally communicate using wait()/notify(). Streams can also communicate and pass data
The classes used are as follows
- PipedInputStream and PipedOutStream
- PipedReader and PipedWriter
Use the byte stream as an example
class Sender implements Runnable {
private PipedOutputStream pos;
private String msg;
public Sender(String msg) {
this.pos = new PipedOutputStream();
this.msg = msg;
}
@Override
public void run(a) {pos. Write (MSG) getBytes ()); }public PipedOutputStream getPos(a) {
returnpos; }}class Receiver implements Runnable {
private PipedInputStream pis;
public Receiver(a) {
this.pis = new PipedInputStream();
}
@Override
public void run(a) {
byte[] data = new byte[1024];
int len;
while((len = pis.read(data)) ! = -1) {
System.out.println(new String(data, 0, len));
}
}
}
Sender sender = new Sender("hello");
Receiver receiver = new Receiver();
receiver.getPis().connect(sender.getPos());
new Thread(sender).start();
new Thread(receiver).start();
// The console prints hello
Copy the code
Input and output streams (Understanding)
System.in and system. out represent the System standard input and output devices
The default input device is the keyboard, and the default output device is the console
The default device can be changed using the setIn, setOut methods of the System class
The method we often use in development to output content to the console.
System.out.println("a");
System.out.print("b");
class System{
public final static InputStream in = null;
public final static PrintStream out = null;
}
public PrintStream(String fileName) throws FileNotFoundException{}
Copy the code
Data flow (Understanding)
It is mainly convenient to read Java basic types and String data, DataInputStream and DataOutputStream implementation classes
DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:/ three Kingdoms/zhou Yu.txt"));
dos.writeUTF("Zhou yu");
dos.writeBoolean(false);
dos.writeLong(1234567890L);
DataInputStream dis = new DataInputStream(new FileInputStream("D:/ three Kingdoms/zhou Yu.txt"));
String s = dis.readUTF();
System.out.println(s);
boolean b = dis.readBoolean();
System.out.println(b);
/ / outputZhou yufalse
Copy the code
IO stream summary
The sections above describe each flow in detail, and there are many types of visible flows, which does add to the difficulty of memorizing. But it can be sorted out by mind mapping for easy memorization.
Mapping of byte streams
Character stream mapping
Division by function
Input and output mapping
conclusion
Short – term increase plan
- NIO
- Tomcat series source code analysis
The article is long, give a big thumbs up to those who see it! Due to the author’s limited level, the article will inevitably have mistakes, welcome friends feedback correction.
If you think this article is helpful to you, please ** like, comment, forward, read, follow ** go
Your support is my biggest motivation!!