IO流
**
1输入输出流分类
按数据流的方向不同可以分为 输入流和输出流
按照处理数据单位不同可以分为 字节流和字符流
按照功能不同可以分为 节点流和处理流
**
字节流:最原始的一个流,读出来的数据就是010101这种最底层的数据表示形式,只不过它是按
照字节来读的,一个字节(Byte)是8位(bit)读的时候不是一个位一个位的来读,而是一个字节
一个字节来读。
字符流:字符流是一个字符一个字符地往外读取数据。一个字符是2个字节
输入输出流是相对于内存而言的。当你写文件时实际上是从内存到磁盘,就相当于从内存输出了。当你读文件时实际上是从磁盘读入到内存,就是从磁盘向内存输入了
输入流
输出流
一 字节流
文件输入流读取ABC.txt 一次读一个字节
// 1 一次读取一个字节
FileInputStream f=new FileInputStream("src\\a.txt");
int len=f.read();// FileInputStream的 int read()方法读取文件第一个字返回
System.out.println(len);// int,A==65
System.out.println(f.read());//66
System.out.println(f.read());//67
System.out.println(f.read());//读到文件末尾返回-1
f.close();//关闭此文件输入流并释放与流相关联的任何系统资源。
输出语句太多了,优化
FileInputStream f=new FileInputStream("src\\a.txt");
int len=0;//记录读取的字节
while ((len=f.read())!=-1){
System.out.println((char) len);//输出ABC
}
一次读多个字节ABCD.txt
FileInputStream f2=new FileInputStream("src\\b.txt");
byte[] bytes=new byte[4];//4个
int len = f2.read(bytes);
System.out.println(len);//4
System.out.println(Arrays.toString(bytes));
// String(char[] value)字符数组转换为字符串
System.out.println(new String(bytes));// 字节数组转为字符串 ABCD
f2.close();
## 文件输出流写入
一次写入一个字节
FileOutputStream fos=new FileOutputStream("src\\a.txt");//默认相对路径:JAVAse文件夹
fos.write(97);//写入
fos.close();//关闭
一次写入多个字节
FileOutputStream fos2=new FileOutputStream(new File("src\\b.txt"));//默认相对路径:JAVAse文件夹
byte[] b={65,66,67,68};//ABCD
// public void write(byte[] b,int off,int len) off数组开始,len写几个字节
fos2.write(b,1,2);//BC
fos2.close();
在文件后 你好1 续写,不覆盖
FileOutputStream fos3=new FileOutputStream("src\\c.txt",true);//不覆盖重写,续写
for (int i=0;i<2;i++){
//一个字符串转化为一个字节数组byte[]的方法
String a="你好2";
fos3.write(a.getBytes());//使用默认字符编码为 byte 序列,并将结果存储到一个新的byte数组中。
fos3.write("\r\n".getBytes());// \r--输入光标回到行的开头,\n-换行
}
fos3.close();
输出
你好1
你好2
你好2
二 字符流
FileWriter字符输出流
FileWriter fw=new FileWriter("src\\d.txt");
fw.write(97);
//使用FileWrite中flush方法,把内存缓冲区数据 刷新到磁盘文件
// fw.flush();
fw.close();//close()方法也可以flush()刷新。 不过close()之后,不能再写
FileReader字符输出流
读取单字符
FileReader fr=new FileReader("src\\c.txt");
int len=0;
while ((len=fr.read())!=-1){
System.out.print((char)len);
}
一次读取多个字符,字符读入数组 读出
你好1
你好2
你好2
char[] cs=new char[1024];
int len=0;
while ((len=fr.read(cs))!=-1){
/* String类构造方法
String(char[] value)字符数组转换为字符串
String(char[] value,int offset,int count)字符数组转换为字符串,开始索引,总数
* */
System.out.println(new String(cs,0,len));
}
//释放资源
fr.close();
三 文件复制
将c盘下ph中a.txt复制到jv里
FileInputStream f1=new FileInputStream("c:\\ph\\w.jpg");//输入流,读取数据源
FileOutputStream f2=new FileOutputStream("c:\\jv\\w.jpg");//输出流,写入数据源。
int len=0;
while ((len=f1.read())!=-1){
f2.write(len);//写入
}
//释放资源(先关写,后关读)写完了肯定读完了。
f2.close();
f1.close();
四 Object流 序列化,反序列化
对象的序列化:把对象写入文件
对象的反序列化流 把文件中保存的对象,流的方式读取出来
例:将Person的对象序列化到txt文件,再用反序列化读出来输出。
@Data
public class Person implements Serializable {
/**序列化为编译后Person.class生成序列号。修改类定义,生成新的序列号
* 解决:手动添加序列号static final long serialVersionUID */
private static final long serialVersionUID=1L;//常量,序列号不会随着类变而变
private String name;
public int age;}
测试
public static void main(String[] args) throws IOException, ClassNotFoundException {
ArrayList<Person> list=new ArrayList<>();
list.add(new Person("王",18));
list.add(new Person("李",19));
list.add(new Person("张",20));
//序列化流对象
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("src\\list.txt"));
oos.writeObject(list);//序列化
//反序列化对象
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("src\\list.txt"));
Object o=ois.readObject();//读取到集合
ArrayList<Person> list2= (ArrayList<Person>) o;
for (Person p:list2) {
System.out.println(p);
}
oos.close();
ois.close();
}
输出