黑马程序员_Java_IO流_字符流

来源:互联网 发布:优化发展环境的讲话 编辑:程序博客网 时间:2024/06/06 02:24

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
一、IO流概述
1、 IO,即Input、Output的缩写。
2、 IO 流的特点:
(1)用来处理设备之间的数据传输。
(2)Java 对数据的操作是通过流的方式。
(3)Java 用于操作流的对象都在IO 包中。
(4)流只能操作数据。
3、 流的划分:
(1)流按操作数据分两种:字节流、字符流。
(2)流按流向分为:输入流、输出流。
4、 字符流、字节流的用处:
字符流融合了编码表,用于处理文字。字节流用于处理图片、文字。通用的是字节流。
5、 IO 流常用基类:
字节流的抽象基类:InputStream、OutputStream
字符流的抽象基类:Reader、Writer
字符流:FileWriter、FileReader (缓冲区:BufferedWriter、BufferedReader)
字节流:FileOutputStream、FileInputStream (缓冲区:BufferedOutputStream、BufferedInputStream)
转换流:InputStreamReader(字节转字符)、OutputStreamWriter(字符转字节),转换流是字符和字节之间的桥梁,通常,涉及到字符编码转换时,需要用到转换流。
6、 流对象的基本规律:
通过三个明确来完成。确定使用哪个体系、使用哪个对象。
1) 明确源和目的
源:输入流 InputStream、 Reader
目的:输出流 OutputStream、 Writer
2) 明确操作的数据是否为纯文本
纯文本: 字符流
非纯文本: 字节流
3) 当体系明确后,在明确要使用的那个具体对象
通过设备来进行区分:
源设备:内存(简写:ArrayStream)、硬盘(简写:FileStream)、键盘(System.in)
目的设备:内存(简写:ArrayStream)、硬盘(简写:FileStream)、控制台(System.out)
二、字符流
2.1 Writer
1、 概述
(1)写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。
(2)直接已知子类7 个:BufferedWriter,CharArrayWriter, FilterWriter,OutputStreamWriter,PipedWriter,PrintWriter,StringWriter,后缀名是父类名,前缀名是该流对象的功能。
(3)IO 流用于操作数据,数据的最常见体现形式是:文件。专门用于操作文件的Writer 子类对象:FileWriter。
2、 构造函数
protected Writer(); //创建一个新的字符流writer,其关键部分将同步writer 自身。
protected Writer(Object lock);//创建一个新的字符流writer,其关键部分将同步给定的对象。
3、 方法
append(); //添加
void write(); //写入单个字符、字符数组、字符串、字符串的某一部分
需要子类去做不同实现的方法:
abstract void write(char[] , int , int); //写入字符数组的某一部分
abstract void flush(); //刷新该流的缓冲
abstract void close(); //关闭此流,但要先刷新它
2.2 FileWriter
1、 FileWriter:用来写入字符文件的便捷类,继承OutputStreamWriter类。
2、 使用步骤:
(1)创建文件。创建一个FileWriter对象,该对象一初始化就必须要明确被操作的文件。而且该文件会被创建到指定的目录下。如果该目录下已有同名文件,已有文件将被覆盖。明确数据要存放的目的地(文件)。创建时,一定要做异常处理或者抛异常,否则报错。在windows中目录分隔符用\。
FileWriter fw=new FileWriter(“d:\demo.txt”);
(2)调用Writer方法,将字符写入流中。
fw.write(“abc”);
(3)刷新流对象中的缓冲器数据。将数据刷新到目的地(文件)。在流关闭之前,流一直存在,可以反复写入数据,但每次写入后,都需要进行刷新操作。
fw.flush();
(4)关闭流资源(必须有的步骤)。但关闭之前会刷新一次内部缓冲区的数据,将数据刷新懂啊目的地(文件)。
fw.close();
3、flush与close的区别:
flush刷新后,流一直存在,可以继续写入数据。
colse将关闭流,不能再继续写入数据。关闭流资源需要单独做try处理。
4、 构造函数
FileWriter(String file,boolean append)://根据给定的文件名以及指示是否附加写入数据的boolean值来构造FileWriter对象。如果append为true,则将数据写入文件末尾处。
FileWriter fw=new FileWriter(“demo.txt”,true);//传递一个ture参数,代表不覆盖已有文件,并在已有文件的末尾处进行数据续写。若没有文件,则创建。
程序示例:

import java.io.FileWriter;import java.io.IOException;public class FileWriterDemo {    public static void main(String[] args) throws IOException {        //创建一个FileWriter对象,该对象一被初始化就必须要有被操作的文件。        //而且该文件会被创建到指定目录下,如果该目录已有同名文件,将被覆盖        FileWriter fw=new FileWriter("demo.txt");        fw.write("aaaa");        fw.flush();        fw.close();    }}

2.3 缓冲区_BufferedWriter
1、 缓冲区的出现:提高了流的读写效率,所以在缓冲区创建前,要先创建流对象。即先将流对象初始化到构造函数中。
2、 缓冲技术原理:此对象中封装了数组,将数据存入,再一次性取出。
3、 写入流缓冲区BufferedWriter的步骤:
(1)创建一个字符写入流对象。
FileWriter fw=newFileWriter(“buf.txt”);
(2)为了提高字符写入流效率。加入缓冲技术。只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
BufferedWriter bufw =new BufferedWriter(fw);
(3)调用write方法写入数据到指定文件
bufw.write(“adfg”);
记住,只要用到缓冲区,就要记得刷新。(关闭流同样会刷新,但为了排除意外事故,保证数据存在,建议写入一次就刷新一次)
bufw.flush();
(4)其实关闭缓冲区,就是在关闭缓冲区中的流对象。
bufw.close();
小知识:BufferedWriter缓冲区中提供了一个跨平台的换行符:newLine();可以在不同操作系统上调用,用作数据换行。
代码示例:

/*缓冲区的出现是为了提高流的操作效率而出现的所以在创建缓冲区之前,必须先有流对象 */import java.io.*;public class BufferedWriterDemo {    public static void main(String[] args) throws IOException {        //创建一个字符写入流对象        FileWriter fw=new FileWriter("buf.txt");        //为了提高字符写入流效率,加入了缓冲技术,只需要将需要被提高效率的流对象传递给缓冲区的构造函数即可。        BufferedWriter bw=new BufferedWriter(fw);        bw.write("abac");        bw.newLine();        bw.write("abac");        //其实关闭缓冲区就是在关闭缓冲区中的流对象。        bw.close();    }}

2.4 OutputStreamWriter
OutputStreamWriter: 是字符通向字节流的桥梁。本身是字符流。都是有参构造函数。主要操作在控制台。
为获取最高效率,可将OutputStreamWriter 包装到BufferedWriter 中,避免频繁调用转换器。
例:BufferedWriter out=new BuffereWriter(new OutputStreamWriter(System.out));
程序示例:

/*读取键盘录入System.out:对应的是标准的输出设备,控制台System.in:对应的是标准输入设备,键盘需求:通过键盘录入数据当录入一行数据后,就将该数据进行打印如果录入的数据时over,那么停止打印。 */import java.io.*;public class ReadIn {    public static void main(String[] args) throws IOException {        InputStream in=System.in;        InputStreamReader isr=new InputStreamReader(in);        BufferedReader br=new BufferedReader(isr);        BufferedWriter out=new BuffereadWriter(new OutputStreamWriter(System.out);        String line=null;        while((line=br.readLine())!=null){            if("over".equals(line))                break;            out.wirte(line.toUpperCase());            out.newLine();out.flush();        }        br.close();out.close();    }}

2.5 Reader
1、 Reader: 用于读取字符流的抽象类。子类必须实现的方法只有read(char[] , int , int )和close()。
2、 已知直接子类:BufferedReader、CharArrayReader、FilterReader、InputStreamReader、PipedReader、StringReader。
3、 方法
read(); //读取的是单个字符
boolean ready(); //判断是否准备读取此流。
void reset(); //重置该流
long skip(long n);//跳过字符,返回实际跳过的字符数;若n 为负数,发生异常IllegalArgumentException
void mark(); //标记流中的当前位置
boolean markSupported(); //判断此流是否支持mark()操作
2.6 FileReader
1、 FileReader: 用来读取字符文件的便捷类。此类构造方法假定默认字符编码和默认字节缓冲区大小适当。
2、 方法
close(); //关闭该流并释放与之关联的所有资源。
int read(); //读取。
3、 步骤:
(1)创建一个文件读取流对象,与指定名称的文件相关联。必须保证该文件存在,若不存在则发生异常FileNotFoundException。
FileReader fr=new FileReader(“demo.txt”);
(2)调用读取流对象的read()方法。
fr.read();
fr.read(buf);//存入缓冲区buf;
一次只读取一个字符,而且会自动往下读。 如果已达到流末尾,则返回-1.
(3)关闭资源。
fr.close();
程序示例:

import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.util.Arrays;public class FileReaderDemo {    public static void main(String[] args) throws IOException {        FileReader fr=new FileReader("demo.txt");        char[] buf=new char[1024];        int num=0;        while((num=fr.read(buf))!=-1)        sop(num+"..."+new String(buf,0,num));        fr.close();//      int ch;//      while((ch=fr.read())!=-1){//          sop((char)ch);//      }    }    public static void sop(Object obj){        System.out.println(obj);    }}

2.7 BufferedReader(缓冲区)
1、 BufferedReader : 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
2、 方法
String readLine(); //读取一个文本行。该缓冲区提供了一个一次读一行的方法 readLine,方便于对文本数据的获取。当返回null 时,表示读到文件末尾(即:若内容不含任何行终止符,已达到流末尾,则返回null)。readLine 方法返回的时候只返回回车符之前的数据内容。并不返回回车符。
readLine()原理:无论是读一行,或者读取多个字符。其实最终都是在硬盘上一个一个读取。所以最终使用的还是read 方法一次读一个方法。
3、 步骤:
(1)创建一个读取流对象和文件相关联。
FileReader fr=new FileReader(“buf.txt”);
(2)为了提高效率,加入缓冲技术。将字符读取流对象作为参数传递给缓冲对象函数的构造函数。
BufferedReader bufr=new BufferedReader(fr);
(3)读取缓冲区。
String line=null; //记录读取的数据
while((line=bufr.readLine())!=null) //按行读取文本内容
{
System.out.println(line);
}
(4)关闭缓冲区资源
bufr.close();
程序示例:

import java.io.*;/*字符读取流缓冲区该缓冲区提供了一个一次读一行的方法readline,方便于对数据的读取当返回null时,表示读到文件末尾readLine方法返回的时候只返回回车符之前的数据内容,并不返回回车符 */public class BufferedReaderDemo {    public static void main(String[] args) throws IOException  {        FileReader fr=new FileReader("buf.txt");        BufferedReader br=new BufferedReader(fr);        String line=null;        while((line=br.readLine())!=null)        System.out.println(line);        br.close();    }}

2.8 LineNumberReader(BufferedReader 子类)
1、 LineNumberReader: 是BufferedReader 的子类。跟踪行号缓冲字符输入流。默认情况下,行编号从0 开始。该行号随数据读取在每个行结束符处递增,并可以通过调用
setLineNumber(int)更改行号,但并不会实际更改流中的当前位置;它只更改将由getLineNumber()返回的值。
2、 方法
setLineNumber(int); //设置当前行号,可以设置行号的起点
getLineNumber(); //获取当前行号
程序示例:

import java.io.*;//练习:模拟一个带行号的缓冲区对象public class LineNumberReaderDemo {    public static void main(String[] args) throws IOException {        FileReader fr=new FileReader("FileReaderDemo_1.java");        LineNumberReader lnr=new LineNumberReader(fr);        String line=null;//      lnr.setLineNumber(5);        while((line=lnr.readLine())!=null){            System.out.println(lnr.getLineNumber()+":"+line);        }        lnr.close();    }}

2.9 InputStreamReader
1、 InputStreamReader : 是字节流通向字符流的桥梁。本身是字符流。使用指定的charset读取字节并将其解码为字符。它使用的字符集可以由名称指定或显示给定,或者接受平台默认的字符集。为提高效率,可以在BufferedReader 内包装InputStreamReader。
2、 构造方法:
InputStreamReader(InputStream out,String charsetName);//创建使用字符集的InputStreamReader,主要作用:转换指定的字节,查指定的码表。InputStream out 为指定字节流。String charsetName 为指定编码表。
3、 键盘录入最常见写法
BufferedReader in = new BufferedRead(new InputStreamReader(System.in));
程序示例:

/*读取键盘录入System.out:对应的是标准的输出设备,控制台System.in:对应的是标准输入设备,键盘需求:通过键盘录入数据当录入一行数据后,就将该数据进行打印如果录入的数据时over,那么停止打印。 */import java.io.*;public class ReadIn {    public static void main(String[] args) throws IOException {        InputStream in=System.in;        InputStreamReader isr=new InputStreamReader(in);        BufferedReader br=new BufferedReader(isr);        String line=null;        while((line=br.readLine())!=null){            if("over".equals(line))                break;            System.out.println(line.toUpperCase());        }        br.close();    }}
0 0