一、IO流概述
1.IO:输入(Input读取数据)/输出(Output写数据)
2.流:是一种抽象概念,是对数据传输的总称,也就是说数据在设备间的传输称为流,流的本质是数据传输,IO流就是用来处理设备间数据传输问题的。
3.常见的应用:文件上传、下载、复制等。
文件通常是由一连串的字节或字符构成,组成文件的字节序列称为字节流,组成文件的字符序列称为字符流。Java中根据流的方向可以分为输入流和输出流。输入流是将文件或其它输入设备的数据加载到内存的过程;输出流恰恰相反,是将内存中的数据保存到文件或其他输出设备,详见下图:
二、IO流分类
2.1 根据数据流向分类:
输入流:读数据 将硬盘中的数据读取到内存中
输出流:写数据 将程序中的数据写入到硬盘中
2.2 按照数据类型来分:
字节流: 字节输入流/字节输出流
字符流: 字符输入流/字符输出流
2.3 IO流应用场景:
纯文本文件,优先使用字符流
图片、视频、音频等二进制文件,优先使用字节流
不确定文件类型,优先使用字节流,字节流是万能的流
2.4 InputStream(字节输入流)、OutputStream(字节输出流)、Reader(字符输入流)、Writer(字符输出流)
2.4.1 InputStream(字节输入流)
InputStream是字节输入流,InputStream是一个抽象类,所有继承了InputStream的类都是字节输入流,主要了解以下子类即可:
主要方法介绍:
void |
close() |
abstract int |
read() |
int |
read(byte[] b) |
int |
read(byte[] b, int off, int len) |
2.4.2 OutputStream(字节输出流)
主要方法介绍:
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(字符输入流)
所有继承了Reader都是字符输入流
主要方法介绍:
abstract void |
close() |
int |
read() |
int |
read(char[] cbuf) |
abstract int |
read(char[] cbuf, int off, int len) |
2.4.4 Writer(字符输出流)
所有继承了Writer都是字符输出流
主要方法介绍:
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.1 FileInputStream(文件字节输入流)
FileInputStream:从文件系统中的文件获取输入字节;
FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件有文件系统中的路径名name命名;
步骤:
1.创建字节输入流对象
2.调用字节输入流对象的读数据方法
3.释放资源
字节流读取数据:
方法名称 |
说明 |
int read() |
从该输入流读取一个字节数据,返回值为-1时说明文件读取完毕(多次调用会按顺序依次读取) |
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
个字节。
如何追加写入数据:
字节流写入数据通过 new FileOutputStream(new File("mayikt.txt"), true); 表示追加写入数据。 如果第二个参数为true,则字节流写入文件的末尾。此方法通过在构造FileOutputStream
对象时将第二个参数设置为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();
一次读取1024个byte,一个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(文件字符输入流)
FileReader是一字符为单位读取文件,也就是一次读取两个字节,如:
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(文件字符输出流)
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();
四、缓冲流
传统方式一个字节一个字节读取或者写入数据,会频繁的发生系统内核调用(用户态→内核态切换)效率非常低。
我们可以使用字节缓冲流,缓冲区是一个内存区域的概念,类似于池子 以“快”的形似写入或者读取数据 减少系统调用频率。
构造函数传递字节流对象,不是文件路径,缓冲流提供了一个缓冲区 做了封装以块的形式读写数据,读写数据还是依赖于字节流对象。
注意:字节缓冲流的缓冲区大小默认是8K,即:8192字节
缓冲流主要是为了提高效率而存在的,减少物理读取次数,缓冲流主要有:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter,并且BufferedReader提供了实用方法readLine(),可以直接读取一行,BufferWriter提供了newLine()可以写换行符。
4.1 采用字节缓冲流改造文件复制代码
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();
可以显示的调用flush,flush的含义是刷新缓冲区,也就是将缓存区中的数据写到磁盘上,不再放到内存里了,在执行os.close()时,其实默认执行了os.flush(),我们在这里可以不用显示的调用文章来源:https://www.toymoban.com/news/detail-656728.html
4.2 采用字符缓冲流改造文件复制代码
文章来源地址https://www.toymoban.com/news/detail-656728.html
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(); // 异常处理,打印出错信息
}
}
}
到了这里,关于IO流 详细介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!