IO流(一. 字节流)
1. IO
IO流概述
在内存的角度
I 表示input,内存从硬盘读取数据
O 表示output,内存往硬盘中存储数据
IO流分流
分为字节流和字符流
- 字节流:一般用于拷贝文件
- InputStream:输入流
- OutputStream:输出流
- 字符流:一般用于读取纯文本文件,比如中文
- Reader:输入流
- Writer:输出流
1. 字节流
-
字节输入流
public class FileIpStream {
public static void main(String[] args) throws IOException {
//如果文件不存在,会报错,不会自动创建
//创建字节输入流对象
FileInputStream fis = new FileInputStream("day10\\a.txt");
int b = 0;
//read() 返回对应字节的码表值,如果到文件末尾则会打印-1
while ((b= fis.read())!=-1){
//读取到的值都会转换成ASCII的码表值,需要强转成char类型才能正确展示
System.out.println((char) b);
}
//关流
fis.close();
}
}
-
字节输出流
public class FileOpStream {
public static void main(String[] args) throws IOException {
/*如果文件不存在,则会自动创建,前提是上级路径存在
如果文件存在则会清空原本的文件
如果需要续写,则使用双参构造,打开续写开关,默认为false
*/
//字节输出流
FileOutputStream fos = new FileOutputStream("day10\\a.txt",true);
/**
* 为当前文件写入ASCII码表对应的字符
*/
fos.write(97);
/**
* 换行符
* Windows:\r\n
* Linux:\n
* Mac:\r
*/
/**
*第二种换行方式,要从System中获取换行的字符串
*String huanhang = System.getProperty("line.separator");
*fos.write(huanhang.getBytes());
*/
byte[] bytes = "\r\n".getBytes();
fos.write(bytes);
//写入字节数组,第二个参数是索引位,第三个参数是从索引位往后输出多少位,默认可不写
fos.write(new byte[]{98, 99, 100},1,2);
//关流
fos.close();
}
}
注意事项:一般需要用try...catch...finally中的 finally把close() 关起来,这样保证无论程序是否发生异常,都能保证资源关流,这样就可以节省内存。
2.字节流(数组传输)
字节流实质上是内存和硬盘直接进行数据交互,因此如果每次读写单个字节速度会非常慢,可以改用数组作为容器进行传递
方法 | 说明 |
---|---|
public int read(byte[] b) throws IOException | 从输入流读取最多b.length 个字节的数据放入数组中 |
public void write(byte b[], int off, int len) throws IOException | 从字节数组下标off开始,将其中len个数据写入到文件的输出流中 |
public class OutputDemo10 {
public static void main(String[] args) throws IOException {
//a.txt中的内容是:abcde
FileInputStream fis = new FileInputStream("C:\\a.txt");
FileOutputStream fos = new FileOutputStream("bytestream\\b.txt");
//byte [] bytes = new byte[1024];一般数组设置为1024的整数倍,这里使用length=2举例
//设置一个容器代大小为2的数组
byte [] bytes = new byte[2];
//本次读到的有效字节个数 --- 这次读了几个字节
int len;
//第1次循环,从文件中读取了len=2长度的字节,ab
//第2次循环,从文件中读取了len=2长度的字节,cd
//第3次循环,从文件中读取了len=1长度的字节,e
while((len = fis.read(bytes))!=-1){
//从元素bytes[0]开始,每次往b.txt中写入len大小的字节数
//第1次循环写入ab
//第2次循环写入cd
//第3次循环写入e
fos.write(bytes,0,len);
}
fis.close();
fos.close();
}
}
3.字节缓冲流
字节缓冲流就相当于官方为我们提供的 字节输入流(每次输入输出一个数组)字节缓冲流和字节流的主要区别在于,字节流是单个字节进行传输的,字节缓冲输入流是一次性读取缓冲输入流数组长度的字节,然后把输入流的缓冲数组每次转移一个字节到缓冲输出流数组中,数组满后,一次性写出所有的数组值。
字节缓冲流实现拷贝功能
public class OutputDemo11 {
public static void main(String[] args) throws IOException {
//就要利用缓冲流去拷贝文件
//创建一个字节缓冲输入流
//在底层创建了一个默认长度为8192的字节数组。
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bytestream\\a.avi"));
//创建一个字节缓冲输出流
//在底层也创建了一个默认长度为8192的字节数组。
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bytestream\\copy.avi"));
int b;
while((b = bis.read()) != -1){
bos.write(b);
}
//方法的底层会把字节流给关闭。
bis.close();
bos.close();
}
}
3.字节缓冲流(数组传输)
单纯只用字节缓冲流还不够快,并没有减少内存与硬盘的交互次数,因此使用字节缓冲流传输数组
public class BufferedIODemo {
public static void main(String[] args) throws Exception{
//在内存中创建一个长度为8192的字节缓冲输入流数组
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\a.txt"));
//在内存中创建一个长度为8192的字节缓冲输出流数组
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("a.txt"));
//数组长度最好是1024的整数倍
byte[] bytes = new byte[1024];
//read() 一次读取1024个字节,如果读不满则读取到len个字节
int len;
//死循环,直到读取到文件末尾为止
while ((len=bis.read(bytes))!=-1){
//从输入流数组一次读取一个字节,读取满数组后,一次性写入文件中
bos.write(bytes,0,len);
}
//先开后关
bos.close();
bis.close();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律