大家好我是小羽!
一、基本概念
- IO流用来处理设备之间的数据传输
- java对数据的操作都是通过流的方式
- java用于操作流的类都在IO包中
二、IO流分类
三、字节流
字节流可以操作任何数据,因为计算机中任何数据都是以字节的形式存储的
话不多说直接上例子:
1.FileInputStream(用java.io包下的)输入流(读)
//创建流对象
FileInputStream fis=new FileInputStream("xxx.txt");
//从硬盘上读取一个字节
int x=fis.read();
System.out.println(x);
int y=fis.read();
System.out.println(y);
int z=fis.read();
System.out.println(z);
//读取文件的结束标记是-1
int a=fis.read();
System.out.println(a);
//关流释放资源
fis.close();
读取一个文件中的所有字节
FileInputStream fis=new FileInputStream("xxx.txt");
int t;
while((t=fis.read()) !=-1){
System.out.println(t);
}
fis.close();
2.FileOutputStream输出(写)
//输出流创建字节输出流对象,如果没有,就自动创建一个文件
FileOutputStream fos=new FileOutputStream("yyy.txt");
//添加的AsCll码表的值
fos.write(97);
fos.write(98);
fos.close();
3.文件续写
//FileOutputStream创建对象的时候如果没有这个文件就会创建出来,如果有这个文件,就先将这个文件清空,再写
//输出流创建字节输出流对象,如果没有,就自动创建一个文件
FileOutputStream fos=new FileOutputStream("yyy.txt",true);//如果想续写,就在第二个参数传True
//添加的AsCll码表的值
fos.write(100);
fos.close();
字节流缓冲区
如果我们传递文件时一个字节一个字节的传递的话,效率就很低,所以要用到缓冲区.
缓冲区BufferedInputStream内置了缓冲区,从BufferedInputStream读取一个字节时,BufferedInputStream会从文件中获取8192个字节(2^13),
存在缓冲区中,然后返回一个程序,等下去获取数据时直接到缓冲区获取,直到8192个字节全部取完,BufferedInputStream会再次从文件中获取8192个字节。
接下来看个例子:
4.拷贝图片文件
//创建输入输出流对象
FileInputStream fis=new FileInputStream("copy.png");
FileOutputStream fos=new FileOutputStream("copy2.png");
//创建缓冲区对象,包装输入输出流,让其变得更加强大
BufferedInputStream bis=new BufferedInputStream(fis);
BufferedOutputStream bos=new BufferedOutputStream(fos);
int b;
while((b=bis.read())!=-1){
bos.write(b);
}
bis.close();
bos.close();
1.flush和close方法的区别
/**
* @param args
* @throws IOException
* close方法
* 具备刷新的功能,在关闭流之前,就会先刷新一次缓冲区,将缓冲区的字节全部刷新到文件上,在关闭。
* close刷新完就不能写了
* flush方法
* 具备刷新功能,刷新完还可以继续写
*/
public static void main(String[] args) throws IOException {
//demo();
//flush和close方法的区别
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("Copy.png"));
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("Copy3.png"));
int b;
while((b=bis.read())!=-1){
bos.write(b);
}
bos.close();
}
四、字符流
只能操作纯文本文件,比较方便
直接上代码例子:
1.字符流读取
FileReader fr=new FileReader("xxx.txt");
int c;
while((c=fr.read())!=-1){//通过项目默认的码表一次读取一个字符
char s=(char)c;
System.out.print(s);
}
fr.close();
2.字符流拷贝
FileReader fr=new FileReader("xxx.txt");
FileWriter fw=new FileWriter("zzz.txt");
int c;
while((c=fr.read())!=-1){
fw.write(c);
}
fr.close();
fw.close();//write类中有一个2k的小缓冲区,如果不关流,就会将内容写到缓冲区。
![file](http://image.openwrite.cn/27912_4C25FBE7BD9E4D6688E0F6AE58219354)
字符流缓冲区
BufferedReader类从字符输入流中读取文本并缓冲字符,以便有效地读取字符,数组和行
1.带缓冲的字符流
/**
* @param args
* @throws IOException
* 带缓冲区的流的特殊方法
* readLine()获取一行的文本
* newLine()换行的作用
*
* newLine()\r\n的区别
* newLine()是跨平台的方法
* \r\n只支持windows系统
*/
public static void main(String[] args) throws IOException {
//demo1();
BufferedReader br=new BufferedReader(new FileReader("xxx.txt"));
BufferedWriter bw=new BufferedWriter(new FileWriter("yyy.txt"));
String line;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();//换行的作用
System.out.println(line);
}
br.close();
bw.close();
}
2.实现拷贝一个文件,到另一个文件为倒序排列。
/**
* @param args
* @throws IOException
* 流对象尽量晚开早关
*
* 实现拷贝一个文件,到另一个文件为倒序排列。
*/
public static void main(String[] args) throws IOException {
//1.创建流对象
BufferedReader br=new BufferedReader(new FileReader("xxx.txt"));
//2.创建集合对象
ArrayList list=new ArrayList();
//3.读取到的数据存储到集合中
String line;
while((line=br.readLine())!=null){
list.add(line);
}
br.close();
//4.倒着遍历集合数据到文件上
BufferedWriter bw=new BufferedWriter(new FileWriter("zzz.txt"));
for (int i =list.size(); i >0; i--) {
bw.write(list.get(i));
bw.newLine();
}
//5.关流
bw.close();
}
![file](http://image.openwrite.cn/27912_6B0E16632B1944199BCB91880DADB11A)
五、其他流
1.SequenceInputStream(将两个输入流,整合成一个流)序列流
FileInputStream fis1=new FileInputStream("a.txt");
FileInputStream fis2=new FileInputStream("b.txt");
SequenceInputStream sis=new SequenceInputStream(fis1,fis2);
FileOutputStream fos=new FileOutputStream("c.txt");
int b1;
while((b1=sis.read())!=-1){//不断读取a.txt上读取字节
//读到的字节写到c.txt上
fos.write(b1);
}
sis.close();//sis关闭的时候,会将构造方法传入的流对象也都关闭
fos.close();
2.ByteArrayOutputStream内存输出流
FileInputStream fis=new FileInputStream("a.txt");
//在内存中创建了可以增长的内存数组
ByteArrayOutputStream bos=new ByteArrayOutputStream();
int b;
while((b=fis.read())!=-1){
bos.write(b);
}
//将缓冲区的数据全部获取出来,并赋值给arr数组
byte[] arr=bos.toByteArray();
System.out.println(new String(arr));
//将缓冲区的内容转换为了字符串,在输出语句中可以省略调整。
System.out.println(bos.toString());
fis.close();
3.随机访问流RandomAccessFile
RandomAccessFile类不属于流,它是Object的子类,融合了InputStream和OutputStream的功能,可以随机对文件进行读写操作。
RandomAccessFile raf=new RandomAccessFile("g.txt", "rw"); //rw是读和写的权限
raf.seek(10);//指定位置设置指针
raf.write(97);
raf.close();
4.操作对象的流
该流是将一个对象读取,或者写入到一个程序中,相当于执行了序列化(存档)和反序列化(读档)。
例子:1.对象输出流ObjectOutputStream序列化(相对于存档)
Person p1=new Person("张三",23);
Person p2=new Person("李四",23);
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("a.txt"));
oos.writeObject(p1);
oos.writeObject(p2);
2.对象输入流反序列化(相当于读档)
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("a.txt"));
Person p1=(Person)ois.readObject();
Person p2=(Person)ois.readObject();
System.out.println(p1);
System.out.println(p2);
ois.close();
完整对象写入,读取(优化版)
3.完整对象写入,读取(优化版)
//写入
Person p1=new Person("张三",23);
Person p2=new Person("李四",23);
Person p3=new Person("王五",23);
ArrayList list=new ArrayList();
list.add(p1);
list.add(p2);
list.add(p3);
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("a.txt"));
oos.writeObject(list);
oos.close();
//读出
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("a.txt"));
ArrayList arrlist=(ArrayList)ois.readObject();
for (Person person : arrlist) {
System.out.println(person);
}
ois.close();