------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、概念
1、概念
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
流按流向分为两种:输入流,输出流。
流按操作类型分为两种:字节流与字符流。 字节流可以操作任何数据,字符流只能操作纯字符数据,比较方便。
2、常用基类
字节流的抽象基类:
InputStream ,OutputStream
字符流的抽象基类:
Reader , Writer
由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。
注意: InputStreamReader 是字符流, 可以从字节流中读取字符
IO流使用步骤:
使用前,导入IO包中的类
使用时,进行IO异常处理
使用后,释放资源
3、异常处理
<1.凡是能和设备上的数据发生关联的,调用底层资源的都会发生IOException。
<2."K:\\demo.txt"没有K盘,会抛出出FileNotFoundException(系统找不到指定的路径) 异常。
FileNotFoundException是IOException的子类。
<3.初始化抛出异常,说明初始化失败,fw还为空,故不可调用对象的close()方法,
所以抛出NullPointerException异常,finally中一定要对关闭的流对象进行不等于 空的判断。
二、字符流文件读写
1、字符流读写文件
<1.读取文件
定义字符流关联指定文件
FileReader reader = new FileReader("Test.txt");
读取一个字符,返回int,该字符的码表值
int ch = reader.read();
关闭流,释放资源
reader.close();
<2.写出文件
定义字符输出流关联指定文件
FileWriter writer = new FileWriter("Test.txt");
写出一个字符,接收int码表值
writer.write(97);
关闭流,释放资源
writer.close();
注意事项
<1.文件路径
定义文件路径时Windows中的目录符号为“\”,但这个符号在Java中是特殊字符,需 要转义。
可以用“\\”或“/”表示。
<2.读取文件
读取文件时必须保证文件存在,否则将抛出FileNotFoundException。
<3.写出文件
写出时文件如不存在时程序会创建新文件,如文件已存在则会清空原文件内容重新写入。
如需追加内容可调用FileWriter构造函数FileWriter(String fileName, boolean append),传入true之后则不会清空原有文件
2、字符流缓冲区读写文件
自定义缓冲区读写
为什么定义缓冲区
由于单个字符读写需要频繁操作文件,所以效率非常低。
我们可以定义缓冲区将要读取或写出的数据缓存,减少操作文件次数。
<1.缓冲区读取
先定义一个数组,然后调用FileReader读取一个数组的方法。
int read(char[] cbuf)
<2.缓冲区写出
将要写出的数据存放在数组中,调用FileWriter方法,一次写出一个数组。
void write(char[] cbuf,int off, int len)
内置缓冲区的BufferedReader和BufferedWriter
Java提供了带缓冲功能的Reader和Writer类:BufferedReader,BufferedWriter
这两个类都是提供包装功能,需要提供其他流来使用,给其他流增加缓冲功能
当我们调用BufferedReader读取数据时,程序会从文件中一次读取8192个字符用来缓冲
当我们调用BufferedWriter写出数据时,程序会先将数据写出到缓冲数组,直到写满8192个才一次性刷出到文件中
例:
1 //现有一个程序是一个试用程序, 2 //每次启动提示剩余次数,如果执行了10次.提示已到期. 3 import java.io.BufferedReader; 4 import java.io.FileReader; 5 import java.io.FileWriter; 6 import java.io.IOException; 7 public classExercise4{ 8 public static void main(String[] args)throws IOException { 9 BufferedReader br = new BufferedReader(newFileReader("times.txt")); //定义BufferedReader 10 String line = br.readLine(); //从times.txt读取一行文本 11 br.close(); // 关闭流, 释放资源 12 int times =Integer.parseInt(line); //把String转为int, Integer.parseInt() 13 if (times > 0) { //如果次数大于0 14 System.out.println("欢迎试用Xxx软件,剩余使用次数: " + --times +"次"); //打印次数,并且-1 15 FileWriter fw = newFileWriter("times.txt");//定义FileWriter 16 fw.write(times+ ""); //把次数转为String,写出次数. 17 fw.close(); // 关闭流 18 }else 19 System.out.println("软件已到期!"); 20 } 21 }
三、装饰设计模式(Decorator)
当我们需要对一个类的功能进行改进、增强的时候会使用装饰设计模式.
格式:
含有被装饰类的引用
通过构造函数传入被装饰类对象
和被装饰类含有同样的方法,其中调用被装饰类的方法,对其进行改进、增强
和被装饰类继承同一个类或实现同一个接口,可以当做被装饰类来使用
BufferedReader、BufferedWriter都是装饰类,他们可以装饰一个Reader或Writer,给被装饰的Reader和Writer提供缓冲的功能。
就像我们用BufferedReader、BufferedWriter装饰FileReader和FileWriter,使用的读写功能还是FileReader和FileWriter的,但给这两个类的读写添加了缓冲功能
四、字节流
1、字节流
基本操作与字符流相同
字节流可以操作任意类型数据
1 //拷贝一个Jpg文件 2 package com.itheima.io.test 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 7 public class Demo5_CopyByArray { 8 public staticvoid main(String[]args)throws IOException { 9 FileInputStream fis = new FileInputStream("ts.jpg"); 10 FileOutputStream fos = new FileOutputStream("F:/ts.jpg"); 11 // 定义一个较小的缓冲区(1KB), 提高效率又不太占内存 12 byte[] buffer =newbyte[1024]; 13 // 该变量用来记录每次拷贝的字节个数 14 int len; 15 // 从文件中读取数据到数组,len记住个数, 判断如果不是文件末尾(-1) 16 while ((len = fis.read(buffer)) != -1) { 17 //将数组中的数据写出,从0号索引写出len个 18 fos.write(buffer,0, len); 19 } 20 fis.close(); 21 fos.close(); 22 } 23 }
五、字节流缓冲区文件读写
自定义缓冲区读写
原理和字符流相同,都是为了提高效率
定义数组缓冲数据,一次读取一个数组,一次写出一个数组,减少操作文件的次数
BufferedInputStream、BufferedOutputStream
和BufferedReader、BufferedWriter原理相同,都是包装类
BufferedInputStream、BufferedOutputStream包装InputStream和OutputStream提供缓冲功能
读取键盘输入:
<1.读取键盘录入:
System.out:对应的是标准输出设备,控制台。
System.in :对应的是标准输入设备:键盘。
<2. in
public static final InputStream in
“标准”输入流。此流已打开并准备提供输入数据。
通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 public class Demo{ 6 public static void main(String[] args) throws IOException { 7 //获取键盘录入对象 8 InputStream inputStream=System.in; 9 //将字节流对象转成字符流对象,使用转换率,inputStreamReader 10 InputStreamReader inputStreamReader=new InputStreamReader(inputStream); 11 //为了提高效率,将字符流串进行缓冲区技术高效操作,使用BufferedReader 12 BufferedReader bufferedReader=new BufferedReader(inputStreamReader); 13 String lineString=null; 14 while ((lineString=bufferedReader.readLine())!=null) { 15 if ("over".equals(lineString)) { 16 break; 17 } 18 System.out.println(lineString.toUpperCase()); 19 } 20 bufferedReader.close(); 21 } 22 }