IO流概述:IO流是用来处理设备之间的数据传输(内存、硬盘)
输入流(读数据): 硬盘-->内存
输出流(存数据): 内存-->硬盘
记忆小技巧:以内存(程序)为基准,从内存(程序)中出去【输出流】,进入内存(程序)【输入流】。
IO流的按照读写数据分类
字节流: 读写任何类型的文件
字节输出流(写字节)
OutputStream(抽象类)
--FileOutputStream :往文件中写字节数据
字节输入流(读字节)
InputStream(抽象类)
--FileInputStream : 读取文件中字节数据
字符流: 专门用于读写文本文件(用记事本打开,能看懂就是文本文件)
字符输出流(写字符)
Writer(抽象类)
--FileWriter : 往文件中写字符数据
字符输入流(读字符)
Reader(抽象类)
--FileReader : 读取文件中的字符数据
字节流:
------------------------------------------------------------------------------------
IO流的操作步骤:
1. 创建流对象(搭桥)
2. 读写数据(过桥)
3. 释放资源(拆桥)
字节流的读和写
/*
使用FileOutputStream字节流,往文件中写入字节数据
*/
public class Demo1 {
public static void main(String[] args) throws IOException {
//1. 创建流对象(搭桥),指定文件路径
//如果文件不存在,会自动创建
//如果文件存在,会把原来的文件覆盖掉
FileOutputStream fos=new FileOutputStream("day09-code\\a.txt");
//2.写数据(过桥)
fos.write(97);
fos.write(98);
fos.write(99);
fos.write(100);
fos.write("19997".getBytes()); //把字符串转换为byte[],再写到文件中
fos.write("\r\n".getBytes()); //换行
//写字节数组
byte[] bs={65,66,67,68};
fos.write(bs);
//"\r\n"表示换行,需要转换为byte[]再写入文件
fos.write("\r\n".getBytes());
//写字节数组的一部分
byte[] bs2={65,66,67,68};
fos.write(bs2,1,2); //从bs2数组中的1索引开始,写2个字节
//"中" 在 UTF-8编码表中 占三个字节 {-28,-72,-83}
byte[] bs3={-28,-72,-83};
fos.write(bs3);
//3. 释放资源(拆桥)
fos.close();
}
}
/*
使用FileInputStream字节流,读取文件中的字节数据
*/
public class Demo2 {
public static void main(String[] args) throws IOException {
//1. 创建流对象(搭桥)
FileInputStream fis=new FileInputStream("day09-code\\a.txt");
//2. 读取文件中的字节(一次读多个)
byte[] bs=new byte[1024]; //存储每次读取到的1024个字节
int len;//记录每次读取的有效【字节个数】
while((len=fis.read(bs))!=-1){
//把读取到的有效字节,转换为String
String str = new String(bs,0,len);
System.out.println(str);
}
//3. 释放资源
fis.close();
}
//一个字节一个字节的读
private static void method1() throws IOException {
//1. 创建流对象(搭桥)
FileInputStream fis=new FileInputStream("day09-code\\a.txt");
//2. 读取数据
int b;//记录每次读取的字节
while((b=fis.read())!=-1){
System.out.println();
}
//3. 释放资源(拆桥)
fis.close();
}
}
字节流复制文件:把"C:\\abca.png"图片复制到"D:\\abc\\b.png"中
/*
需求: 把"C:\\abc\\a.png"图片复制到"D:\\abc\\b.png"中
数据源: "C:\\abc\\a.png"
使用FileInputStream,关联"C:\\abc\\a.png"文件
数据目的:"D:\\abc\\b.png"
使用FileOutputStream,关联"D:\\abc\\b.png"文件
*/
public class CopyDemo1 {
public static void main(String[] args) throws IOException {
//使用FileInputStream,关联"C:\\abc\\a.png"文件
FileInputStream fis=new FileInputStream("C:\\abc\\a.jpg");
//使用FileOutputStream,关联"D:\\abc\\a.png"文件
FileOutputStream fos=new FileOutputStream("C:\\bbb\\b.jpg");
//一边读,一边写
byte[] bs=new byte[1024];
int len;//记录每次读取的个数
while((len=fis.read(bs))!=-1){
//写入有效的字节个数 len
fos.write(bs,0,len);
}
//释放资源
fis.close();
fos.close();
}
}
背景:由于字节流读取中文是有可能出现乱码问题。Java的设计者为我们提供了字符流,专门用于读取文本文件。
字符流:
专门用于读写文本文件(用记事本打开,能看懂就是文本文件)
字符输出流(写字符)
Writer(抽象类)
--FileWriter : 往文件中写字符数据
字符输入流(读字符)
Reader(抽象类)
--FileReader : 读取文件中的字符数据
字符流写如文件
public class Demo1 {
public static void main(String[] args) throws IOException {
//1. 创建流对象(搭桥),指定文件路径
//如果文件不存在,会自动创建
//如果文件存在,会把原来的文件覆盖掉
FileWriter fw=new FileWriter("day09-code\\a.txt");
//2.写数据(过桥)
fw.write("abc");
fw.write("\r\n");
fw.write("中文");
fw.write("\r\n");
char[] chs={'a','b','c','f','g','h','w','z'};
//写入数组的全部元素
fw.write(chs);
fw.write("\r\n");
//写入数组的一部分
fw.write(chs,3,5);
fw.write("\r\n");
//写入字符串的一部分
fw.write("helloworld",0,5);
//3. 释放资源(拆桥)
fw.close();
}
}
字符流读取文件
public class Demo2 {
public static void main(String[] args) throws IOException {
//1. 创建流对象
FileReader fr=new FileReader("day09-code\\a.txt");
//2. 一次读取多个字符
char[] chs=new char[1024];
int len; //记录每次读取到的字符个数
while((len=fr.read(chs))!=-1){
System.out.println(new String(chs,0,len));
}
//3. 释放资源
fr.close();
}
//一个字节一个字节的读
private static void method1() throws IOException {
FileReader fr=new FileReader("day09-code\\a.txt");
//一次读取一个字符
int ch; //记录每次读取到的字符
while((ch=fr.read())!=-1){
System.out.print((char)ch);
}
fr.close();
}
}
字符流复制文件:把a.txt文件中的内容,复制到b.txt文件中
public class CopyDemo1 {
public static void main(String[] args) throws IOException {
//1. 创建流对象
FileReader fr=new FileReader("day09-code\\a.txt");
FileWriter fw=new FileWriter("day09-code\\b.txt");
//2. 读写数据
int len;
char[] ch=new char[1024];
while ((len=fr.read(ch))!=-1){
//fw.write(new String(ch,0,len));
fw.write(ch,0,len);
}
//释放资源
fr.close();
fw.close();
}
}
今日重点知识总结:
1. 字节流复制文件
public class CopyDemo1 {
public static void main(String[] args) throws IOException {
//使用FileInputStream,关联"C:\\abc\\a.png"文件
FileInputStream fis=new FileInputStream("C:\\abc\\a.jpg");
//使用FileOutputStream,关联"D:\\abc\\a.png"文件
FileOutputStream fos=new FileOutputStream("C:\\bbb\\b.jpg");
//一边读,一边写
byte[] bs=new byte[1024];
int len;//记录每次读取的个数
while((len=fis.read(bs))!=-1){
//写入有效的字节个数 len
fos.write(bs,0,len);
}
//释放资源
fis.close();
fos.close();
}
}
2. 字符流复制文件
public class CopyDemo1 {
public static void main(String[] args) throws IOException {
//1. 创建流对象
FileReader fr=new FileReader("day09-code\\a.txt");
FileWriter fw=new FileWriter("day09-code\\b.txt");
//2. 读写数据
int len;
char[] ch=new char[1024];
while ((len=fr.read(ch))!=-1){
//fw.write(new String(ch,0,len));
fw.write(ch,0,len);
}
//释放资源
fr.close();
fw.close();
}
}
3. 综合练习
/*
IO流练习1:有一个a.txt文件,内容如下:
吉利-白色-鄂A61QP1
长安-黑色-鄂A87SB9
奇瑞-蓝色-鄂A78T87
哈佛-橙色-鄂A1080P
要求:读取文件中的每一行数据,并且使用"-"进行切割,把元素封装成一个Car对象。
把car对象,存储到集合里
*/
public class Test {
public static void main(String[] args) throws IOException {
//1. 先读取car.txt中的所有数据,保存到StringBuiler中
StringBuilder sb=new StringBuilder();
//2. 创建FileReader对象,读取car.txt文件
FileReader fr=new FileReader("day09-code\\car.txt");
char[] chs=new char[1024];
int len;
while((len=fr.read(chs))!=-1){
//把有效的字符个数,添加到sb中
sb.append(chs,0,len);
}
//3. 释放资源
fr.close();
ArrayList<Car> list=new ArrayList<>();
//对StringBuiler中的内容使用"\r\n"进行切割
String[] lines = sb.toString().split("\r\n");
//遍历每一行字符串
for (String line : lines) {
//对每一行用"-"进行切割,得到每一个汽车的品牌、颜色、车牌号
String[] arr = line.split("-");
Car car=new Car(arr[0],arr[1],arr[2]);
list.add(car);
}
for (Car car : list) {
System.out.println(car);
}
}
}
I/O流处理异常的代码(try..catch..finally)
public class IOExceptionDemo {
public static void main(String[] args) {
FileWriter fw=null;
try {
fw=new FileWriter("day09-code\\d.txt");
fw.write("java");
fw.write("hello");
} catch (IOException e) {
e.printStackTrace();
}finally {
//释放资源的操作,必须执行。
try {
if(fw!=null){
fw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}