IO技术概述

  • Output 把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作
  • Input 把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作
  • 把上面的这种输入和输出动作称为IO操作

编码表

  • ascii: 一个字节中的7位就可以表示。对应的字节都是正数。0-xxxxxxx
  • iso-8859-1:拉丁码表 latin,用了一个字节用的8位。1-xxxxxxx 负数。
  • GB2312:简体中文码表。包含6000-7000中文和符号。用两个字节表示。两个字节第一个字节是负数,第二个字节可能是正数
  • GBK:目前最常用的中文码表,2万的中文和符号。用两个字节表示,其中的一部分文字,第一个字节开头是1,第二字节开头是0
  • GB18030:最新的中文码表,目前还没有正式使用。
  • unicode:国际标准码表:无论是什么文字,都用两个字节存储。
  • Java中的char类型用的就是这个码表。char c = 'a';占两个字节。
  • Java中的字符串是按照系统默认码表来解析的。简体中文版 字符串默认的码表是GBK。
  • UTF-8:基于unicode,一个字节就可以存储数据,不要用两个字节存储,而且这个码表更加的标准化,在每一个字节头加入了编码信息(后期到api中查找)。

IO中的异常处理

如果不使用try catch 可以添加抛出声明

public static void main(String[] args) throws IOException{

}
  • 保证流对象变量,作用域足够
  • catch里面,怎么处理异常
    • 输出异常的信息,目的看到哪里出现了问题
    • 停下程序,从新尝试
  • 如果流对象建立失败了,需要关闭资源吗
    • new 对象的时候,失败了,没有占用系统资源
    • 释放资源的时候,对流对象判断null
    • 变量不是null,对象建立成功,需要关闭资源
FileOutputStream fos = null;
// 注意变量的作用域问题
// try 外面声明变量,try 里面建立对象
try{
    fos = new FileOutputStream("s:\\a.txt");
    fos.write(100);
}catch(IOException ex){
    System.out.println(ex);
    throw new RuntimeException("文件写入失败,重试");
}finally{
    try{
        if(fos!=null)
          fos.close();
    }catch(IOException ex){
        throw new RuntimeException("关闭资源失败");
    }
}

转换流概述

  • OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节
  • 将字符串按照指定的编码表转成字节,在使用字节流将这些字节写出去
  • 继承关系

FileWriter extends OutputStreamWriter

FileReader extends InputStreamReader

  • 区别

  • OutputStreamWriter和InputStreamReader是字符和字节的桥梁:也可以称之为字符转换流。字符转换流原理:字节流+编码表。

  • FileWriter和FileReader:作为子类,仅作为操作字符文件的便捷类存在。当操作的字符文件,使用的是默认编码表时可以不用父类,而直接用子类就完成操作了,简化了代码。

  • 以下三句话功能相同

    • InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));//默认字符集。
    • InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"GBK");//指定GBK字符集。
    • FileReader fr = new FileReader("a.txt");

字节转换流OutputStreamWriter类

  • 构造方法
Constructor and Description
OutputStreamWriter(OutputStream out)
创建一个使用默认字符编码的OutputStreamWriter。
OutputStreamWriter(OutputStream out, Charset cs)
创建一个使用给定字符集的OutputStreamWriter。
OutputStreamWriter(OutputStream out, CharsetEncoder enc)
创建一个使用给定字符集编码器的OutputStreamWriter。
OutputStreamWriter(OutputStream out, String charsetName)
创建一个使用命名字符集的OutputStreamWriter。
  • 常规方法
Modifier and Type Method and Description
void close()
关闭流,先刷新。
void flush()
刷新流。
String getEncoding()
返回此流使用的字符编码的名称。
void write(char[] cbuf, int off, int len)
写入字符数组的一部分。
void write(int c)
写一个字符
void write(String str, int off, int len)
写一个字符串的一部分。

输出文本文件

// utf-8
//创建字节输出流,绑定文件
FileOutputStream fos1 = new FileOutputStream("c:\\utf.txt");
//创建转换流对象,构造方法保证字节输出流,并指定编码表是UTF-8
OutputStreamWriter osw1 = new OutputStreamWriter(fos1,"UTF-8");
osw1.write("你好");
osw1.close();

// gbk
//创建字节输出流,绑定数据文件
FileOutputStream fos2 = new FileOutputStream("c:\\gbk.txt");
//创建转换流对象,构造方法,绑定字节输出流,使用GBK编码表
OutputStreamWriter osw2 = new OutputStreamWriter(fos2);
//转换流写数据
osw2.write("你好");
osw2.close();

字节转换流InputStreamReader类

  • 构造方法
Constructor and Description
InputStreamReader(InputStream in)
创建一个使用默认字符集的InputStreamReader。
InputStreamReader(InputStream in, Charset cs)
创建一个使用给定字符集的InputStreamReader。
InputStreamReader(InputStream in, CharsetDecoder dec)
创建一个使用给定字符集解码器的InputStreamReader。
InputStreamReader(InputStream in, String charsetName)
创建一个使用命名字符集的InputStreamReader。
  • 常规方法
Modifier and Type Method and Description
void close()
关闭流并释放与之相关联的任何系统资源。
String getEncoding()
返回此流使用的字符编码的名称。
int read()
读一个字符
int read(char[] cbuf, int offset, int length)
将字符读入数组的一部分。
boolean ready()
告诉这个流是否准备好被读取。

字节流输入文本文件

// utf-8
//创建自己输入流,传递文本文件
FileInputStream fis1 = new FileInputStream("c:\\utf.txt");
//创建转换流对象,构造方法中,包装字节输入流,同时写编码表名
InputStreamReader isr1 = new InputStreamReader(fis1,"UTF-8");
char[] arr1 = new char[2];
int len1;
while((len1 = isr1.read(arr1)) != -1)
{
    System.out.print(new String(arr1,0,len1));
}

// gbk
//创建自己输入流,传递文本文件
FileInputStream fis2 = new FileInputStream("c:\\utf.txt");
//创建转换流对象,构造方法中,包装字节输入流,同时写编码表名
InputStreamReader isr2 = new InputStreamReader(fis2,"UTF-8");
char[] arr2 = new char[2];
int len2;
while((len2 = isr2.read(arr2)) != -1)
{
    System.out.print(new String(arr2,0,len2));
}

缓冲流概述

  • 可提高IO流的读写速度
  • 分为字节缓冲流与字符缓冲流

字节缓冲流BufferedOutputStream类

  • 构造方法
Constructor and Description
BufferedOutputStream(OutputStream out)
创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
BufferedOutputStream(OutputStream out, int size)
创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流。
  • 常规方法
Modifier and Type Method and Description
void flush()
刷新缓冲输出流。
void write(byte[] b, int off, int len)
从指定的字节数组写入 len个字节,从偏移 off开始到缓冲的输出流。
void write(int b)
将指定的字节写入缓冲的输出流。

字节缓冲流输出文本文件

//创建字节输出流,绑定文件
FileOutputStream fos = new FileOutputStream("c:\\buffer.txt");
//创建字节输出流缓冲流的对象,构造方法中,传递字节输出流
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(55);
byte[] bytes = "HelloWorld".getBytes();
bos.write(bytes);
bos.write(bytes, 3, 2);
bos.close();

字节缓冲流BufferedInputStream类

  • 构造方法
Constructor and Description
BufferedInputStream(InputStream in)
创建一个 BufferedInputStream并保存其参数,输入流 in ,供以后使用。
BufferedInputStream(InputStream in, int size)
创建 BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 in ,供以后使用。
  • 常规方法
Modifier and Type Method and Description
int available()
返回从该输入流中可以读取(或跳过)的字节数的估计值,而不会被下一次调用此输入流的方法阻塞。
void close()
关闭此输入流并释放与流相关联的任何系统资源。
void mark(int readlimit)
见的总承包 mark的方法 InputStream
boolean markSupported()
测试这个输入流是否支持 markreset方法。
int read()
readInputStream的一般合同。
int read(byte[] b, int off, int len)
从给定的偏移开始,将字节输入流中的字节读入指定的字节数组。
void reset()
resetInputStream的一般合同。
long skip(long n)
skipInputStream的一般合同。

字节缓冲流输入文本文件

//创建字节输入流,绑定文件
FileInputStream fis = new FileInputStream("c:\\buffer.txt");
//创建字节输入流的缓冲流对象,构造方法中包装字节输入流,包装文件
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] bytes = new byte[10];
int len = 0 ;
while((len = bis.read(bytes))!=-1){
    System.out.print(new String(bytes,0,len));
}
bis.close();

字符缓冲流BufferedWriter类

  • 构造方法
Constructor and Description
BufferedWriter(Writer out)
创建使用默认大小的输出缓冲区的缓冲字符输出流。
BufferedWriter(Writer out, int sz)
创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。
  • 常规方法
Modifier and Type Method and Description
void close()
关闭流,先刷新。
void flush()
刷新流。
void newLine()
写一行行分隔符。
void write(char[] cbuf, int off, int len)
写入字符数组的一部分。
void write(int c)
写一个字符
void write(String s, int off, int len)
写一个字符串的一部分。

字符缓冲流输出文本文件

//创建字符输出流,封装文件
FileWriter fw = new FileWriter("c:\\buffer.txt");
BufferedWriter bfw = new BufferedWriter(fw);

bfw.write(100);
bfw.flush();
bfw.write("你好".toCharArray());
bfw.flush();
bfw.write("你好");
bfw.flush();
bfw.close();

newLine()方法BufferedWriter类

/*   
 * newLine()运行结果,和操作系统是相互关系
 * JVM: 安装的是Windows版本,newLine()写的就是\r\n
 * 安装的是Linux版本,newLine()写的就是\n
 */

FileWriter fw = new FileWriter("c:\\buffer.txt");
BufferedWriter bfw = new BufferedWriter(fw);

bfw.write(100);
bfw.newLine();
bfw.flush();
bfw.write("你好".toCharArray());
bfw.newLine();
bfw.flush();
bfw.write("你好");
bfw.newLine();
bfw.flush();
bfw.close();

字符缓冲流BufferedReader类

  • 构造方法
Constructor and Description
BufferedReader(Reader in)
创建使用默认大小的输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz)
创建使用指定大小的输入缓冲区的缓冲字符输入流。
  • 常规方法
Modifier and Type Method and Description
void close()
关闭流并释放与之相关联的任何系统资源。
Stream lines()
返回一个 Stream ,其元素是从这个 BufferedReader读取的行。
void mark(int readAheadLimit)
标记流中的当前位置。
boolean markSupported()
告诉这个流是否支持mark()操作。
int read()
读一个字符
int read(char[] cbuf, int off, int len)
将字符读入数组的一部分。
String readLine()
读一行文字。
boolean ready()
告诉这个流是否准备好被读取。
void reset()
将流重置为最近的标记。
long skip(long n)
跳过字符

字符缓冲流输入文本文件

int lineNumber = 0;

FileReader fr = new FileReader("c:\\a.txt");
//创建字符输入流缓冲流对象,构造方法传递字符输入流,包装数据源文件
BufferedReader bfr = new BufferedReader(fr);
//调用缓冲流的方法 readLine()读取文本行
//循环读取文本行, 结束条件 readLine()返回null
String line = null;
while((line = bfr.readLine())!=null){
    lineNumber++;
    System.out.println(lineNumber+"  "+line);
}
bfr.close();