1. Overview of IO flow
1.IO: input (Input reads data)/output (Output writes data)
2. Stream: It is an abstract concept and a general term for data transmission. That is to say, the transmission of data between devices is called a stream. The essence of stream is data transmission. IO stream is used to deal with data transmission problems between devices.
3. Common applications: file upload, download, copy, etc.
A file is usually composed of a series of bytes or characters. The byte sequence that makes up the file is called a byte stream, and the character sequence that makes up the file is called a character stream. Java can be divided into input streams and output streams according to the direction of the stream. Input stream is the process of loading data from files or other input devices into memory; output stream is just the opposite, saving data in memory to files or other output devices. See the figure below for details:
2. IO flow classification
2.1 Classification according to data flow direction:
Input stream: Read data. Read data from the hard disk into memory.
Output stream: write data. Write the data in the program to the hard disk.
2.2 According to data type:
Byte stream: byte input stream/byte output stream
Character stream: character input stream/character output stream
2.3 IO stream application scenarios:
Plain text files, preferentially use character streams
For binary files such as pictures, videos, and audios, byte streams are preferred.
If you are not sure about the file type, use byte stream first. Byte stream is a universal stream.
2.4 InputStream (byte input stream), OutputStream (byte output stream), Reader (character input stream), Writer (character output stream)
2.4.1 InputStream (byte input stream)
InputStream is a byte input stream. InputStream is an abstract class. All classes that inherit InputStream are byte input streams. You can mainly understand the following subclasses:
Main method introduction:
void |
close() |
abstract int |
read() |
int |
read(byte[] b) |
int |
read(byte[] b, int off, int len) |
2.4.2 OutputStream (byte output stream)
Main method introduction:
void |
close() |
void |
flush() |
void |
write(byte[] b) |
void |
write(byte[] b, int off, int len) |
abstract void |
write(int b) |
2.4.3 Reader (character input stream)
All inherited Reader are character input streams
Main method introduction:
abstract void |
close() |
int |
read() |
int |
read(char[] cbuf) |
abstract int |
read(char[] cbuf, int off, int len) |
2.4.4 Writer (character output stream)
All inherited Writer are character output streams
Main method introduction:
Writer |
append(char c) |
abstract void |
close() |
abstract void |
flush() |
void |
write(char[] cbuf) |
abstract void |
write(char[] cbuf, int off, int len) |
void |
write(int c) |
void |
write(String str) |
void |
write(String str, int off, int len) |
3. File flow
3.1 FileInputStream (file byte input stream)
FileInputStream: Get input bytes from a file in the file system;
FileInputStream(String name): Creates a FileInputStream by opening a connection to the actual file, which is named by the path name name in the file system;
step:
1. Create a byte input stream object
2. Call the read data method of the byte input stream object
3. Release resources
Read data from byte stream:
method name |
illustrate |
int read() |
Read one byte of data from the input stream. When the return value is -1, it indicates that the file has been read (multiple calls will read in sequence) |
int |
read(byte[] b) |
int |
read(byte[] b, int off, int len) |
InputStream in = new FileInputStream("d:/a.txt");
int c = 0;
while((c = in.read()) != -1){
System.out.println(c);
}
in.close();
上述代码在执行时:如果在执行in.read()
时没有读取到末尾,即文件还有可读取的数据,in.read()
方法会返回下一个可用字节的整数值(0-255之间)。如果已经读取到了文件末尾,in.read()
方法会返回-1。
3.2 FileOutputStream(文件字节输出流)
字节流写入数据常用的三种方式:
方法名称 |
说明 |
void write(int b) |
将指定的字节写入此文件输出流 一次写一个字节数据 |
void write(byte[] b) |
将 b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据 |
void write(byte[] b, int off, int len) |
将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据 |
void write(byte[] b, int off, int len)
是Java中OutputStream
类的一个方法,用于将指定字节数组中的一部分数据写入输出流。
参数解释:
b
:要写入的字节数组。off
:写入的起始偏移量,即从数组的第off
个位置开始写入数据。len
:要写入的字节数,即写入b
数组中从off
位置开始的连续len
个字节。
如何追加写入数据:
The byte stream writes data through new FileOutputStream(new File("mayikt.txt"), true); to indicate additional written data. If the second parameter is true, the byte stream is written to the end of the file. This method implements append writing FileOutputStream
by setting the second parameter to when constructing the object.true
InputStream in = new FileInputStream("d:/a.txt");
OutputStream out = new FileOutputStream("d:/aa.txt");
int c = 0;
while((c = in.read()) != -1){
out.write(c);
}
in.close();
out.close();
Read 1024 bytes at a time, one kb:
import java.io.*;
public class Demo03 {
public static void main(String[] args) throws IOException {
InputStream is = new FileInputStream("d:/apache-tomcat-8.5.75.zip");
OutputStream os = new FileOutputStream("d:/tomcat.zip",true);//append:true 追加
byte[] b = new byte[1024];
int len = 0;
while ( (len = is.read(b)) != -1 ){
os.write(b,0,len);
}
//关闭IO流管道 关闭的时候会有刷新作用
is.close();
os.close();
}
}
3.3 FileReader (file character input stream)
FileReader reads files in units of one character, that is, reads two bytes at a time, such as:
Reader r = new FileReader("E:/a.txt");
int c = 0;
while((c = r.read()) != -1){
char ch = (char)c;
System.out.println(ch);
}
r.close();
3.4 FileWriter (file character output stream)
Reader r = new FileReader("d:/a.txt");
Writer w = new FileWriter("d:/aaa.txt",true);
int c = 0;
while((c = r.read()) != -1){
char ch = (char)c;
w.write(ch);
}
r.close();
w.close();
4. Buffer stream
The traditional way of reading or writing data byte by byte will cause frequent system kernel calls (user mode → kernel mode switching), which is very inefficient.
We can use a byte buffer stream. The buffer is a concept of a memory area, similar to a pool, which writes or reads data in a "fast" manner to reduce the frequency of system calls.
The constructor passes a byte stream object, not a file path. The buffer stream provides a buffer that encapsulates data for reading and writing in blocks. Reading and writing data still depends on the byte stream object.
Note: The default buffer size of byte buffered stream is 8K, that is: 8192 bytes
Buffered streams mainly exist to improve efficiency and reduce the number of physical reads. Buffered streams mainly include: BufferedInputStream, BufferedOutputStream, BufferedReader, and BufferedWriter. BufferedReader provides a practical method readLine(), which can directly read a line. BufferWriter provides newLine () can write newlines.
4.1 Use byte buffer stream to transform file copy code
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:/SOFT/CentOS-7-x86_64-Minimal-2009.zip"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:/centos.zip"));
byte[] arr = new byte[1024];
int len = 0;
while ( (len = bis.read(arr)) != -1 ){
bos.write(arr,0,len);//将 arr 数组中的内容从0的位置到len的位置 放到bos中
}
bis.close();
bos.close();
You can call flush explicitly. The meaning of flush is to refresh the buffer, that is, to write the data in the buffer to the disk and no longer put it in the memory. When executing os.close(), os is actually executed by default. flush(), we can call it without explicit call here
4.2 Use character buffer stream to transform file copy code
BufferedReader r = new BufferedReader(new FileReader("d:/abc/a.txt"));
BufferedWriter w = new BufferedWriter(new FileWriter("d:/abc/b.txt"));
String line = null;
while( (line = r.readLine()) != null ){
w.write(line+"\n");
}
r.close();
w.close();
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Example {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
String line; // 用于存储读取的每一行内容的变量
// 循环读取input.txt文件中的每一行内容,直到读取到文件末尾为止
while ((line = reader.readLine()) != null) {
writer.write(line); // 将读取到的内容写入output.txt文件
writer.newLine(); // 写入换行符
}
} catch (IOException e) {
e.printStackTrace(); // 异常处理,打印出错信息
}
}
}