Java IO流

340 阅读5分钟

大家好我是小羽!

一、基本概念

  • IO流用来处理设备之间的数据传输
  • java对数据的操作都是通过流的方式
  • java用于操作流的类都在IO包中

二、IO流分类

file

三、字节流

字节流可以操作任何数据,因为计算机中任何数据都是以字节的形式存储的

话不多说直接上例子:

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个字节。

直接上图: file

接下来看个例子:

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类从字符输入流中读取文本并缓冲字符,以便有效地读取字符,数组和行

我们通过一张图来理解: file

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<String> list=new ArrayList<String>();
		//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<Person> list=new ArrayList<Person>();
		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<Person> arrlist=(ArrayList<Person>)ois.readObject();
		for (Person person : arrlist) {
			System.out.println(person);
		}
		ois.close();