IO流(First edition):
IO流:用于读入写出文件中的数据
流的方向(输入指拿出来,输出指写进去)
输入流:读取
输出流:写出
操作文件类型
字节流:所有类型文件
字符流:纯文本
字节流:
InputStream的子类:FileInputStream:操作本地文件的字节输入流
OutputStream的子类:FileOutputStream:操作本地文件的字节输出流
//1.创建字节输出流对象
//细节1:参数是字符串表示的路径或者是File对象都是可以的
//细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的。
//细节3:如果文件存在,会清空文件的内容
FileOutputStream fos = new FileOutputStream("C:\\Users\\35303\\Desktop\\a.txt");
//2.写入
//细节:write方法的参数是整数,但是实际上写到本地文件中的是整数在ASCII上对应的字符
//fos.write(67);
//3.释放资源
//fos.close();
FileOutputStream写数据的3种方式
方法名称 说明
void write(int b) 一次写一个字节数据
void write(byte[]b) 一次写一个字节数组数据
void write(byte[lb,int off,int len) (参数1:数组,参数2:起始索引,参数3:个数) 一次写一个字节数组的部分数据
//void write(byte[]b)
byte a[] = new byte[]{97,98,99,100,101};
fos.write(a);
//fos.close();
//void write(byte[lb,int off,int len)
byte b[] = new byte[]{65,66,67,68,69};
fos.write(b,1,3); //从1号索引写三个
fos.close();
//续写:在打开时后面写个true
FileOutputStream fos1 = new FileOutputStream("C:\\Users\\35303\\Desktop\\b.txt",true);
//方便转字符
String s = "djaofjawsfja";
byte[] bytes = s.getBytes();
fos1.write(bytes);
//fos1.close();
//换行: \r\n(单写\r或\n也可以)
String s1 ="\r\n";
String s2 = "666";
byte[] bytes1 = s1.getBytes();
byte[] bytes2 = s2.getBytes();
fos1.write(bytes1);
fos1.write(bytes2);
fos1.close();
FileInputStream:
//FileInputStream
//1.创建对象
FileInputStream fis = new FileInputStream("C:\\Users\\35303\\Desktop\\b.txt");
//2.读取数据(如果没数据了read会返回-1)
//read:表示读取数据,而且是读取一个数据就移动一次指针
int a1 = fis.read();
System.out.println((char)a1);
//3.释放资源
//fis.close();
//字节输入流循环读取
int a2;
while((a2=fis.read())!=-1){
System.out.print((char)a2);
}
fis.close();
//方法名称 说明
//public int read() 一次读一个字节数据
//public int read(byte[] buffer) (返回值为获取的长度) 一次读一个字节数组数据
字符流:字符流的底层其实就是字节流
//字符流=字节流+字符集
特点:
输入流:一次读一个字节,遇到中文时,一次读多个字节
输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中
Reader的子类:FileReader
Writer的子类:FileWriter
FileReader:
构造方法 (1.创建字符输入流对象) 说明
public FileReader(File file) 创建字符输入流关联本地文件
public FileReader(string pathname) 创建字符输入流关联本地文件
细节1:如果文件不存在就直接报错
2.读取数据
成员方法 说明
public int read() 读取数据,读到末尾返回-1
public int read(char[] buffer) 读取多个数据,读到末尾返回-1
细节1:按字节进行读取遇到中文,一次读多个字节,读取后解码,返回一个整数
细节2:读到文件末尾了,read方法返回-1。
3.释放资源
close();
//read无参
//1.创建对象并关联本地文件
FileReader fr = new FileReader("C:\\Users\\35303\\Desktop\\b.txt");
//2.读取数据
//字符流的底层也是字节流,默认也是一个字节一个字节的读取的。
//如果遇到中文就会一次读取多个,GBK一次读两个字节,UTF-8一次读三个字节(IDEA默认UTF-8)
int ch;
while((ch=fr.read())!=-1){ //空参是传出的ch是字符的二进制
System.out.print((char)ch);
}
System.out.println();
read()细节:
1.read():默认也是一个字节一个字节的读取的,如果遇到中文就会一次读取多个
2.在读取之后,方法的底层还会进行解码并转成十进制。
最终把这个十进制作为返回值
这个十进制的数据也表示在字符集上的数字
英文:文件里面二进制数据 0110 0001
read方法进行读取,解码并转成十进制97
中文:文件里面的二进制数据 11100110 10110001 10001001
read方法进行读取,解码并转成十进制27721
// 我想看到中文汉字,就是把这些十进制数据,再进行强转就可以了
//read有参
//1.创建对象
FileReader fr1 = new FileReader("C:\\Users\\35303\\Desktop\\b.txt");
//2.读取数据
char []chars = new char[2]; //表示一次读两个数据
int len;
while((len=fr1.read(chars))!=-1){ //有参时传出来的是长度
//把数组中的数据变成字符串再去打印
System.out.print(new String(chars,0,len)); //读几个就转几个
}
//3.释放资源
fr1.close();
FileWriter:
构造方法 说明
public FileWriter(File file) 创建字符输出流关联本地文件
public FileWriter(String pathname) 创建字符输出流关联本地文件
public FileWriter(File file,boolean append) (append:续写开关,为true是续写) 创建字符输出流关联本地文件,续写
public FileWriter(String pathname,boolean append) 创建字符输出流关联本地文件,续写
成员方法 说明
void write(int c) 写出一个字符
void write(string str) 写出一个字符串
void write(String str,int off,int len) 写出一个字符串的一部分
void write(char[] cbuf) 写出一个字符数组
void write(char[] cbuf,int off,int len) 写出字符数组的一部分
FileWriter书写细节
1.创建字符输出流对象
//细节1:参数是字符串表示的路径或者File对象都是可以的
//细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的
//细节3:如果文件已经存在,则会清空文件,如果不想清空可以打开续写开关
2.写数据
细节: 如果write方法的参数是整数,但是实际上写到本地文件中的是整数在字符集上对应的字符
3.释放资源
细节:每次使用完流之后都要释放资源
//方法write(int c) 写出一个字符
FileWriter fw = new FileWriter("C:\\Users\\35303\\Desktop\\b.txt",true);
fw.write(25105);//(25105:我)//根据字符集的编码方式进行编码,把编码之后的数据写到文件中去
//fw.close();
//方法FileWriter(String pathname) 写出一个字符串
fw.write("\n你好hello位");
fw.close();
//write(String str,int off,int len) 写出一个字符串的一部分
//fw.write("\n你好hello位",0,3);
//方法void write(char[] cbuf) 写出一个字符数组
//char s[]= new char[]{'a','b','c'};
//fw.write(char);
//fw.close();
前面学的都是基本流,下面的是高级流
缓冲流:BufferedInputStream(字节缓存输入流)、BufferedOutputStream(字节缓存输出流)
BufferedReader(字符缓存输入流)、BufferedWriter(字符缓冲输出流)
字节缓存流原理:底层自带了长度为8192的缓冲区提高性能
方法名称 说明
public BufferedInputStream(InputStream is) 把基本流包装成高级流,提高读取数据的性能
public BufferedOutputStream(OutputStream os) 把基本流包装成高级流,提高写出数据的性能
//字节缓冲流
//一次操作一个字节
//1.创建缓冲流的对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\Users\\35303\\Desktop\\b.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Users\\35303\\Desktop\\c.txt"));
//2.循环读取并写到目的地
int b;
while((b=bis.read())!=-1){
bos.write((char)b);
}
//3.释放资源
bos.close();
bis.close();
//一次操作多个字节
byte [] bytes = new byte[1024];
int len;
while((len=bis.read(bytes))!=-1){
bos.write(bytes,0,len);
}
bos.close();
bis.close();
字符缓存流原理:底层自带了长度为8192的缓冲区提高性能
方法名称 说明
public BufferedReader(Reader r) 把基本流变成高级流
public BufferedWriter(Writer r) 把基本流变成高级流
字符缓冲流特有方法
字符缓冲输入流特有方法 说明
public String readLine() 读取一行数据,如果没有数据可读了,会返回null
字符缓冲输出流特有方法 说明
public void newLine() 跨平台的换行
//1.创建字符缓冲输入流的对象
BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\35303\\Desktop\\b.txt"));
//2.读取数据
String line;
while ((line=(br.readLine()))!=null) { //获取文件中一行的数据
System.out.println(line);
}
//3.释放资源
br.close();
//1.创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\35303\\Desktop\\c.txt",true));
//2.写出数据
bw.write("你嘴角上扬的样子");
bw.newLine(); //因为不同平台的换行不一样,所以可以用跨平台换行newLine
bw.write("hello world");
//3.释放资源
bw.close();
转换流(不需要掌握,看看懂懂意思)
转换流属于字符流
InputStreamReader(转换输入流),OutputStreamWriter(转换输出流)
转换流是字符流和字节流之间的桥梁
输入时把字节流转换成字符流,然后就拥有了字符流的特性,输出又转换为字节流
作用:字节流想使用字符流中的方法了那就可以使用转换流转一下
//1.创建对象并指定字符编码
InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\Users\\35303\\Desktop\\b.txt"),"GBK");
//第二个参数不写默认UTF-8,写了就是转换为什么编码
//2.读取数据
int ch;
while((ch=isr.read())!=-1){
System.out.print((char)ch);
}
//3.释放资源
isr.close();
//1.创建转换流的对象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\Users\\35303\\Desktop\\b.txt"),"GBK");
//2.写出数据
osw.write("nihao");
//3.释放资源
osw.close();
序列化流(又叫对象操作输出流):可以把java中的对象写到本地文件中
序列化流属于字节流(输出outputStream),反序列化流(输入inputStream)
ObjectInputStream(反序列化流),ObjectOutputStream(序列化流)
构造方法 说明
public ObjectOutputStream(OutputStream out) 把基本流包装成高级流
成员方法 说明
public final void writeObject(object obi) 把对象序列化(写出)到文件中去
需求:利用序列化流/对象操作输出流,把一个对象写到本地文件中
序列化流的小细节
使用对象输出流将对象保存到文件时会出现NotSerializableException异常
解决方案:
需要让Javabean类实现Serializable接口
//1.创建对象
Demo10two stu = new Demo10two("张三",12,"da");
//2.创建序列化流的对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\35303\\Desktop\\d.txt"));
//3.写出数据
oos.writeObject(stu);
//4.释放资源
oos.close();
反序列化流(又叫对象操作输入流)
可以把序列化到本地文件中的对象,读取到程序中来
构造方法 说明
public ObjectInputStream(InputStream out) 把基本流变成高级流
成员方法 说明
public object readObject() 把序列化到本地文件中的对象,读取到程序中来
//1.创建反序列化流的对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\35303\\Desktop\\d.txt"));
//2.读取数据
Object o = ois.readObject();
//3.打印对象
System.out.println(o);
//3.释放资源
ois.close();
javabean类:
package com.itheima.demo14IO流;
import java.io.Serializable;
public class Demo10two implements Serializable {
private static final long serialVersionUID = -8462176507494611942L;
//反序列化流要定义版本号,在IDEA里设置了,所以只要点黄色的那段类名然后alt+回车添加版本号就行了
//序列化流的小细节
//使用对象输出流将对象保存到文件时会出现NotSerializableException异常
//解决方案:
//需要让Javabean类实现Serializable接口
//Serializable接口里面是没有抽象方法,标记型接
//一旦实现了这个接口,那么就表示当前的student类可以被序列化
private String name;
private int age;
//transient:瞬态关键字
//作用:不会把当前属性序列化到本地文件当中
private transient String a;
public Demo10two(String dawda, int age, String da) {
}
public Demo10two(long serialVersionUID, String name, int age, String a) {
this.name = name;
this.age = age;
this.a = a;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
/**
* 获取
* @return a
*/
public String getA() {
return a;
}
/**
* 设置
* @param a
*/
public void setA(String a) {
this.a = a;
}
public String toString() {
return "Demo10two{name = " + name + ", age = " + age + ", a = " + a + "}";
}
}