IO流

IO流

I是指Input(输入),O是指Output(输出)

在Java中,文件的输入和输出都是通过流(Stream)来实现的,流的概念源于Unix中pipe(管道)的概念。在Unix系统中,管道是一条不间断的字节流,用来实现程序或者进程间的通信,或读写外围设备、外部文件等。

一个流,必须有源端和目的端,他们可以是计算机内存的某些区域,也可以是磁盘文件,甚至可以是Internet上的某个URL。对于流而言,我们不用关心数据是如何传输的,只需要向源端输入数据,向目的端获取数据即可。

流按照处理数据的单位,可以分为字节流和字符流;按照流向分为输入流和输出流(输入流和输出流都是站在程序的角度思考的)

字节流

字节流用于处理以字节为单位的二进制文件(如音乐、图片等);

InputStream抽象类是所有输入字节流类的直接或间接父类,FileInputStream是其重要的子类
OutputStream抽象类是所有输出字节流类的直接或间接父类,FileOutputStream是其重要的子类

FileInputStream

常用构造方法:

  • FileInputStream(File file); 通过file对象创建FileInputStream对象
  • FileInputStream(String name); 通过文件(非目录)路径来创建FileInputStream对象。

常用方法:

  • int read();从输入流中读取单个字节的数据;如果已经达到文件末尾,则返回-1。
  • int read(byte[] b);从输入流中将最多b.length个字节的数据读入一个byte数组中,以整数形式返回存入数组中的实际字节个数;如果已经达到文件末尾则返回-1
  • void close():关闭此文件输入流并释放与此流有关的所有系统资源

FileOutputStream

常用构造方法:

  • FileOutputStream(File file);通过File对象创建FileOutputStream对象
  • FileOutputStream(String name);通过文件路径来创建FileOutputStream对象。

常用方法:

  • void write(int b);将指定的单个字节数据写入此文件输出流。
  • void write(byte[] b, int off, int len);将byte数组中从off开始的len个字节写入此文件输出流
  • void flush();刷新字节输出流,并强制写出缓冲内所有字节数据
  • void close();关闭此文件输出流,并释放所有与此流有关的系统资源

我们将FileOutputStream与FileInputStream综合起来叙述这两个类的各种方法。

传输示意图:
在这里插入图片描述

  1. 每次传输单个字节:
public class Test{	
	public static void main(String[] args){
		FileInputStream fileInputStream = null;
		FileOutputStream fileOutputStream = null;
		try{
			fileInputStream = new FileInputStream("D:\\hello.jpg");//相当于java与输入字节流接通了一根管道
			fileOutputStream = new FileOutputStream("D:\\world.jpg");//相当于java与输出字节流接通了一根管道
			int data = 0;
			while((data=fileInputStream.read())!=-1){//每次读取一个字节的数据,把读出来的数据存到data中,直到没数据data为-1
				fileOutputStream.write(data);//将data写入目标文件路径
			}
			fileOutputStream.flush();//强制写出缓冲内所有字节数据,防止数据停留在缓冲中
		} catch (Exception e) {
			e.printStackTrace();
		}finally{//释放资源
			if(fileInputStream!=null) {
    				try {
     					fileInputStream.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
   			if(fileOutputStream!=null) {
    				try {
     					fileOutputStream.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
		}
	}
}
  1. 每次传入多个字节
public class Test{	
	public static void main(String[] args){
		FileInputStream fileInputStream = null;
		FileOutputStream fileOutputStream = null;
		try{
			fileInputStream = new FileInputStream("D:\\hello.jpg");//相当于java与输入字节流接通了一根管道
			fileOutputStream = new FileOutputStream("D:\\world.jpg");//相当于java与输出字节流接通了一根管道
			byte[] car = new byte[1024];//定义一个缓冲数组car,类似与运货的车,一下可以装1024个货
			int length= 0;
			while((length=fileInputStream.read(car))!=-1){//每次读取length个字节,最多读取1024个字节的数据,把读出来的数据存到data中,直到没数据data为-1
				fileOutputStream.write(car,0,length);//从car数组的第0位开始,将length长度的car写入目标文件路径
			}
			fileOutputStream.flush();//强制写出缓冲内所有字节数据,防止数据停留在缓冲中
		} catch (Exception e) {
			e.printStackTrace();
		}finally{//释放资源
			if(fileInputStream!=null) {
    				try {
     					fileInputStream.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
   			if(fileOutputStream!=null) {
    				try {
     					fileOutputStream.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
		}
	}
}

字符流

Java虚拟机将字节转化为了两个字节的Unicode字符就形成了字符流,字符流用于处理以Unicode字符为单位的文本文件(如记事本文件)

Reader抽象类是所有输入字符流类的直接或者间接父类,FileReader是其重要子类
Writer抽象类是所有输出字符流类的直接或者间接父类,FileWriter是其重要子类

FileReader

常用构造方法

  • FileReader(File file);通过File对象创建FileReader对象
  • FileReader(String fileName);通过文件路径来创建FileReader对象。

常用方法

  • int read();从输入流中读取单个字符的数据;如果已经达到文件末尾,则返回-1。
  • int read(char[] c);从输入流中将最多c.length个字符的数据读入一个char数组中,以整数形式返回存入数组中的实际字符个数;如果已经达到文件末尾则返回-1
  • void close():关闭此文件输入流并释放与此流有关的所有系统资源

FileWriter

常用构造方法

  • FileWriter(File file);通过File对象创建FileWriter对象
  • FileWriter(String fileName);通过文件路径来创建FileWriter对象。

常用方法

  • void write(int c);将指定的单个字符数据写入此文件输出流。
  • void write(char[] c, int off, int len);将char数组中从off开始的len个字符写入此文件输出流
  • void flush();刷新字符输出流,并强制写出缓冲内所有字符数据
  • void close():关闭此文件输出流并释放与此流有关的所有系统资源

我们将FileReader与FileWriter综合起来叙述这两个类的各种方法。

  1. 每次传输单个字符:
public class Test{	
	public static void main(String[] args){
		FileReader fileReader= null;
		FileWriter fileWriter= null;
		try{
			fileReader= new FileReader ("D:\\hi.txt");//相当于java与输入字符流接通了一根管道
			fileWriter= new FileWriter ("D:\\hey.txt");//相当于java与输出字符流接通了一根管道
			int data = 0;
			while((data=fileReader.read())!=-1){//每次读取一个字符的数据,把读出来的数据存到data中,直到没数据data为-1
				fileWriter.write(data);//将data写入目标文件路径
			}
			fileWriter.flush();//强制写出缓冲内所有字符数据,防止数据停留在缓冲中
		} catch (Exception e) {
			e.printStackTrace();
		}finally{//释放资源
			if(fileReader!=null) {
    				try {
     					fileReader.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
   			if(fileWriter!=null) {
    				try {
     					fileWriter.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
		}
	}
}

  1. 每次传输多个字符
public class Test{	
	public static void main(String[] args){
		FileReader fileReader= null;
		FileWriter fileWriter= null;
		try{
			fileReader= new FileReader ("D:\\hi.txt");//相当于java与输入字符流接通了一根管道
			fileWriter= new FileWriter ("D:\\hey.txt");//相当于java与输出字符流接通了一根管道
			char[] car = new char[1024];//定义一个缓冲数组car,类似与运货的车,一下可以装1024个货
			int length = 0;
			while((length = fileReader.read(car))!=-1){//每次读取length个字符的数据,直到没数据length为-1
				fileWriter.write(car,0,length);//从0开始将length长度的car写入目标文件路径
			}
			fileWriter.flush();//强制写出缓冲内所有字符数据,防止数据停留在缓冲中
		} catch (Exception e) {
			e.printStackTrace();
		}finally{//释放资源
			if(fileReader!=null) {
    				try {
     					fileReader.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
   			if(fileWriter!=null) {
    				try {
     					fileWriter.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
		}
	}
}

缓冲流

上面说到的IO流都是直接访问硬盘,进行文件的读写操作,虽然我们通过改变一次传输的量的方式,使效率提高,但我们可以使效率更高一些

缓冲流是一种装饰器类,目的是让原字节流、字符流新增缓冲的功能以提高读取或写入。简单的说,通过缓存存取,间接输入输出

示意图:
在这里插入图片描述

用于字节流:
缓冲流是一种装饰器,目的是让原字节流、字符流新增缓冲的功能以提高读取或写入。
缓冲字节输入流:BufferedInputStream(InputStream in)
缓冲字节输出流:BufferedOutputStream(OutputStream out)

public class Test { 
 	public static void main(String[] args) {
  		FileInputStream fileInputStream = null;
  		FileOutputStream fileOutputStream = null;
  		BufferedInputStream bufferedInputStream=null;
  		BufferedOutputStream bufferedOutputStream=null;
  		try {
   			fileInputStream = new FileInputStream("D:\\1.jpg");
   			fileOutputStream = new FileOutputStream("D:\\2.jpg");
   			bufferedInputStream=new BufferedInputStream(fileInputStream);
   			bufferedOutputStream=new BufferedOutputStream(fileOutputStream);
   			int length = 0;
   			byte[] car =new byte[1024];
   			while((length=bufferedInputStream.read(car))!=-1) {
    				bufferedOutputStream.write(car,0,length);
   			}
   			bufferedOutputStream.flush();
  		} catch (Exception e) {
   			e.printStackTrace();
  		} finally {
   			if(fileInputStream!=null) {
    				try {
     					fileInputStream.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
   			if(fileOutputStream!=null) {
    				try {
     					fileOutputStream.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
   			if(bufferedInputStream!=null) {
    				try {
     					bufferedInputStream.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
   			if(bufferedOutputStream!=null) {
    				try {
     					bufferedOutputStream.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
  		}
 	}
}

缓冲字符输入流:BufferedReader(Reader in)
缓冲字符输出流:BufferedWriter(Writer out)

public class Test { 
 	public static void main(String[] args) {
  		FileReader filereader=null;
  		FileWriter filewriter=null;
  		BufferedReader bufferedReader=null;
  		BufferedWriter bufferedWriter=null;
  		try {
   			filereader = new FileReader("D:\\1.txt");
   			filewriter = new FileWriter("D:\\2.txt");
   			bufferedReader=new BufferedReader(filereader);
   			bufferedWriter=new BufferedWriter(filewriter);
   			int length=0;
   			char[] car=new char[1024];
   			while((length=bufferedReader.read(car))!=-1) {
    				bufferedWriter.write(car,0,length);;
   			}
   			bufferedWriter.flush();
  		} catch (Exception e) {
   			e.printStackTrace();
  		} finally {
   			if(filereader!=null) {
    				try {
     					filereader.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
   			if(filewriter!=null) {
    				try {
     					filewriter.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
   			if(bufferedWriter!=null) {
    				try {
     					bufferedWriter.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
   			if(bufferedReader!=null) {
    				try {
     					bufferedReader.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
  		}
 	}
}

转换流

由于文件自身编码方式和程序运行时使用的默认编码方式不一致,致使程序读取或输出字符文件时可能会出现乱码,这时可以使用字节流操作文件,然后再将字节流转换成字符流,这一转换过程可以借助转换流实现

InputStreamReader();(字节输入流→字符输入流)

  • InputStreamReader(InputStream in);
  • InputStreamReader(InputStream in,String charsetName);

OutputStreamWriter();(字节输出流→字符输入流)

  • OutputStreamWriter(InputStream in);
  • OutputStreamWriter(InputStream in,String charsetName);
public class Test { 
 	public static void main(String[] args) {
  		InputStreamReader inputStreamReader=null;//定义转换流变量
  		OutputStreamWriter outputStreamWriter=null;
  		FileInputStream fileInputStream=null;//定义字节流变量
  		FileOutputStream fileOutputStream=null;
  		try {
   			fileInputStream=new FileInputStream("D:\\Program_Files\\1.txt");//字节流实例化
   			fileOutputStream=new FileOutputStream("D:\\Program_Files\\2.txt");
  			inputStreamReader = new InputStreamReader(fileInputStream);//转换流实例化
   			outputStreamWriter = new OutputStreamWriter(fileOutputStream);
   			int length=0;
   			char[] car=new char[1024];
   			while((length=inputStreamReader.read(car))!=-1) {
    				outputStreamWriter.write(car,0,length);;
   			}
   			outputStreamWriter.flush();
  		} catch (Exception e) {
   			e.printStackTrace();
  		} finally {//释放资源
   			if(fileInputStream!=null) {
    				try {
     					fileInputStream.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
   			if(fileOutputStream!=null) {
    				try {
     					fileOutputStream.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
   			if(inputStreamReader!=null) {
    				try {
     					inputStreamReader.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
   			if(outputStreamWriter!=null) {
   				try {
     					outputStreamWriter.close();
    				} catch (IOException e) {
     					e.printStackTrace();
    				}
   			}
  		}
 	}
}

数据流

通过DataInputStream和DataOutputStream数据流可以直接操作基本数据类型和字符串

public class Test { 
 	public static void main(String[] args) {
 		try {
   			double a=9.9;
   			DataOutputStream dateoutputstream= new DataOutputStream(new FileOutputStream("D:\\1.temp"));
   			dateoutputstream.writeDouble(a);
   			dateoutputstream.flush();
  		} catch (Exception e) {
   			e.printStackTrace();
  		}
  
  		try {
   			DataInputStream dataInputStream=new DataInputStream(new FileInputStream("D:\\1.conj"));//实例化数据流
  	 		double q=dataInputStream.readDouble();
  		} catch (Exception e) {
  		 	e.printStackTrace();
  		}
 	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值