黑马程序员---java基础-Java之IO

 

一、概念

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(系统找不到指定的路径) 异常。

  FileNotFoundExceptionIOException的子类。

<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)

   内置缓冲区的BufferedReaderBufferedWriter

  Java提供了带缓冲功能的ReaderWriter类:BufferedReaderBufferedWriter

 这两个类都是提供包装功能,需要提供其他流来使用,给其他流增加缓冲功能

 当我们调用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)

当我们需要对一个类的功能进行改进、增强的时候会使用装饰设计模式.

格式:

含有被装饰类的引用

通过构造函数传入被装饰类对象

和被装饰类含有同样的方法,其中调用被装饰类的方法,对其进行改进、增强

和被装饰类继承同一个类或实现同一个接口,可以当做被装饰类来使用

BufferedReaderBufferedWriter都是装饰类,他们可以装饰一个ReaderWriter,给被装饰的ReaderWriter提供缓冲的功能。

就像我们用BufferedReaderBufferedWriter装饰FileReaderFileWriter,使用的读写功能还是FileReaderFileWriter的,但给这两个类的读写添加了缓冲功能

 

四、字节流

 

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 }

五、字节流缓冲区文件读写

自定义缓冲区读写

原理和字符流相同,都是为了提高效率

定义数组缓冲数据,一次读取一个数组,一次写出一个数组,减少操作文件的次数

BufferedInputStreamBufferedOutputStream

BufferedReaderBufferedWriter原理相同,都是包装类

BufferedInputStreamBufferedOutputStream包装InputStreamOutputStream提供缓冲功能

 

读取键盘输入:

  <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 }

原文地址:https://www.cnblogs.com/ZkSnug/p/4457584.html