美文网首页
Java中的IO框架流二

Java中的IO框架流二

作者: 征程_Journey | 来源:发表于2017-05-21 11:06 被阅读0次

    1      IO(二)No19

    缓冲流:内置了缓冲区,对现有的流对象进行了封装,实现了高效的读写操作并增强了功能

    字节缓冲流

    BufferedInputStream

    BufferedOutputStream

    字符缓冲流

    BufferedReader

    特有方法:readLine():第一行(以换行符为标记,读到换行符代表是一行,不包含换行符)

    BufferedWriter

    特有方法:newLine():输出一个换行符(根据本地系统相关)

    设计模式:

    【简单工厂、静态工厂、抽象工厂、单利模式、迭代器模式、观察者模式(接口回调)】

    装饰者设计模式:

    1.1    处理流

    昨天的FileStream系列、FileReader、Writer都是节点流,直接和文件这个节点打交道的。节点流对应的是处理流,它们不直接和文件、网络等终端节点打交道,而是对其他流进行装饰、给其他流添加功能

    处理流本身也是InputStream、OutputStream、Reader、Writer的子类,如:

    BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter,它们可以给对应的体系中的流进行装饰,添加缓冲功能

    1.2    BufferedInputStream

    字节输入缓冲流:

    FileInputStream fis = newFileInputStream("g:/output.txt");

    //创建一个缓冲字节输入流,装饰了参数中的fis文件输入流,给它添加了缓冲功能

    BufferedInputStream  bis = new BufferedInputStream(fis);

    //读一个字节,但不是直接操作磁盘读,而是从内置的缓存中去读

    intn = bis.read();

    System.out.println(n);

    bis.close();      //关闭bis会自动关闭被装饰着的流

    BufferedInputStream bis = new BufferedInputStream(newFileInputStream(

    "g:/output.zip"));

    intn =0;

    while((n=bis.read())!=-1){

    //不作任何处理,纯粹为演示效率问题

    //效率高,因为不是直接从磁盘上一个个读,而是从缓冲区中一个个读

    }

    bis.close();//关闭缓存流,里面所装饰着的流也会关闭

    BufferedInputStream 带缓冲的字节输入流

    构造方法:BufferedInputStream(InputStream is)参数是要进行装饰的另一个字节输入流

    方法和InputStream基本一致

    int read()从缓冲中读一个字节(缓冲空了话就读信息填充)

    close()关闭处理流时,会自动关闭被装饰的流

    1.3    BufferedOutputStream

    字节输出缓冲流:

    //用缓存字节输出流装饰文件输出流,添加缓存功能

    BufferedOutputStreambos = new BufferedOutputStream(

    newFileOutputStream("g:/output.txt"));

    bos.write(97);//将数据写到内置缓存中,这里没有实际写到文件中

    bos.flush();  //强制刷缓存,刷到文件中

    //关闭缓存流,会先刷缓存(97这时候才写到文件里),所装饰的流也会被自动关闭

    bos.close();

    BufferedInputStream bis = new BufferedInputStream(newFileInputStream(

    "g:/output.zip"));

    BufferedOutputStreambos = new BufferedOutputStream(

    newFileOutputStream("g:/AAoutput.zip"));

    intn =0;

    while((n=bis.read())!=-1){

    bos.write(n);    //写到目标文件的缓存输出流中去

    //                        bos.flush();     //每次都直接操作磁盘,效率极低

    }

    //               bos.flush();         //手动flush

    bos.close();         //自动flush

    bis.close();

    BufferedOutputStream 带缓冲的字节输出流

    构造方法:BufferedOutputStream(OutputStream os)参数是要进行装饰的另一个字节输出流

    方法和OutputStream基本一致

    write(int b)向缓冲中写一个字节(缓冲满了话就将缓冲中的所有字节数据一下子刷到被装饰的流中)

    flush()刷缓存,强制将缓存中的字节数据刷到被装饰得流中

    close()在关闭之前会先隐式调用flush,然后再关闭

    关闭处理流时,会自动关闭被装饰的流

    1.4    BufferedReader

    字符缓冲流:

    BufferedReader br =new BufferedReader(new FileReader("g:/output.txt"));

    //从缓存中读取一个字符并打印

    System.out.println((char)br.read());

    br.close();

    BufferedReader br =new BufferedReader(new FileReader("g:/output.txt"));

    String line  = br.readLine();    //读取一行信息,用line指向

    System.out.println(line);

    //读下一行,打印,也就是第二行

    System.out.println(br.readLine());

    //读下一行,打印,也就是第三行

    System.out.println(br.readLine());

    System.out.println(br.readLine());

    System.out.println(br.readLine());

    //读完返回null;

    System.out.println(br.readLine());

    br.close();   //关闭处理流及其装饰的流

    BufferedReader br =new BufferedReader(new FileReader("g:/output.txt"));

    String line = null; //存储每次readLine的结果及判断文件尾部

    while (true) {

    line =br.readLine();//循环读行并赋给line

    if (line == null){//如果到达文件尾部

    break; //退出循环

    }

    System.out.println(line);//打印

    }

    br.close();//关闭处理流和节点流

    //制作一个自动批改器,一题一分,最终打印出试卷的成绩

    BufferedReaderreader1 = new BufferedReader(new FileReader("g:/answer.txt"));

    BufferedReader reader2 = newBufferedReader(new FileReader("g:/tom.txt"));

    int count = 0;

    while(true){

    String line1 =reader1.readLine();

    String line2 =reader2.readLine();

    if(line1 == null ||line2 ==null){

    break;

    }

    if(line1.trim().equalsIgnoreCase(line2.trim())){

    count ++;

    }

    }

    System.out.println(count);

    reader1.close();

    reader2.close();

    BufferedReader 带缓冲的字符输入流

    构造方法:BufferReader(Reader r)参数是要进行装饰的另一个字符输入流

    int read()从缓存中读一个字符,读完的话返回-1,没读完就返回读到的那个字符

    String readLine()从缓存中读一行,如果没有读完,返回表示的下一行的字符串,如果读完,返回null

    1.5    BufferedWriter

    BufferedWriter 带缓冲的字符输出流

    构造方法:BufferedWriter(Writer w)参数是要进行装饰的另一个字符输出流

    write(int c)往缓存中写一个字符(缓冲满了会自动刷出去)

    write(String s)将参数字符串拆成一组字符写到缓存中去

    newLine()往缓存中写换行符(windows中换行\r\n,linux\n)

    flush()把缓存中的字节信息一下子强制刷到所装饰的流中

    close()关闭缓冲流及其装饰的流,并隐式flush()

    1.6    转换流

    在System类中定义了三个静态字段,分别是三个流对象

    1)System.err“标准”错误输出流,可将错误数据输出到屏幕(控制台)

    2)System.out“标准”输出流,可将数据输出到屏幕(控制台)

    3)System.in“标准”输入流,可获取从键盘录入的数据

    转换流

    从键盘录入数据所用的流是一个系统提供的标准流,而系统提供的标准路都是字节流

    如果直接使用字节流来操作字符数据的话,会出现很多问题,需要做很多额外的操作

    我们可以通过转换流将字节流转换成字符流,JDK中一共提供了两个转换流

    InputStreamReader:是字节流通向字符流的桥梁

    OutputStreamWriter:是字符流通向字节流的桥梁

    实际上:字符流=字节流+编码表

    //系统提供三个标准流不要手动关闭,一旦关闭就使用不来了了。

    1.6.1  InputStreamReader

    转换流:将字节流转换成字符流,使其能够输入汉字:

    FileInputStream fis = newFileInputStream("g:/output.txt");

    //使用转换流对其装换

    InputStreamReaderisr = new InputStreamReader(fis);

    intn=0;

    while((n=isr.read())!=-1){

    System.out.println((char)n);

    }

    isr.close();

    用转换流指定字符集:

    //               FileReaderisr = new FileReader("g:/answer.txt");

    FileInputStreamfis = new FileInputStream("g:/answer.txt");

    //装换为字符流

    InputStreamReaderisr = new InputStreamReader(fis,"GBK");

    //用缓冲流装饰装换出来的字符流,添加了缓冲的功能

    BufferedReaderbr = new BufferedReader(isr);

    Stringline = br.readLine();    //读行

    System.out.println(line);       //打印

    br.close();

    FileOutputStream fos = newFileOutputStream("g:/answer.txt");

    Stringstr = "安卓";

    byte[]bytes = str.getBytes("utf-8");

    for(byte b : bytes) {

    System.out.println(b);

    fos.write(b);//将两个汉字对应的4个字节写到文件中去

    }

    fos.close();

    FileInputStream fis = newFileInputStream("g:/output.txt");

    //用utf-8的形式将字节转换为字符

    InputStreamReaderisr = new InputStreamReader(fis,"utf-8");

    System.out.print((char)isr.read());

    System.out.print((char)isr.read());

    isr.close();

    //有时候我们获取到的输入流就是字节流,无法改变,如:System.in

    //这时,可以使用InputStreamReader转换为字符流

    BufferedReaderbr = new BufferedReader(new InputStreamReader(System.in));

    Stringline = null;

    //从系统输入读取一行

    while((line= br.readLine())!=null){

    if(line.equals("exit")){

    break;

    }

    System.out.println(line);

    }

    /***

    *

    *获取用户键盘录入的小写数据,并将数据变成大写显示在控制台上,

    *如果用户输入的是exit,则结束键盘录入

    *

    */

    public class TransferDemo {

    /*

    *从键盘录入数据所用的流是一个系统提供的标准流,而系统提供的标准路都是字节流

    *如果直接使用字节流来操作字符数据的话,会出现很多问题,需要做很多额外的操作

    *我们可以通过转换流将字节流转换成字符流,JDK中一共提供了两个转换流

    * InputStreamReader:是字节流通向字符流的桥梁

    * OutputStreamWriter:是字符流通向字节流的桥梁

    */

    publicstatic void main(String[] args) throws IOException {

    //InputStreamReader:是字节流通向字符流的桥梁

    BufferedReaderbr = new BufferedReader(new InputStreamReader(System.in));

    //OutputStreamWriter:是字符流通向字节流的桥梁

    BufferedWriterbw = new BufferedWriter(new OutputStreamWriter(System.out));

    Stringline = null;

    //从键盘录入一行数据,以换行符为标记

    while((line= br.readLine()) != null){

    if("exit".equalsIgnoreCase(line)){

    break;

    }

    bw.write(line.toUpperCase());

    bw.newLine();

    bw.flush();

    }

    bw.close();

    br.close();

    }

    }

    转换流可以用来将字节流转换为字符流

    InputStreamReader将字节输入流转换为字符输入流

    构造方法:InputStreamReader(InputStream is)参数就是要转换为字符流的字节流,构造方法调用后转换即成功,接下来就可以对构造出来的字符流进行操作

    (有另一个重载构造方法,可以在new的时候指定字符集)

    1.6.2  OutputStreamWriter

    //已经有一个字节输出流,想往里写utf-8格式的中文

    FileOutputStream fos= new FileOutputStream("g:/answer.txt");

    //用转换流装饰节点流,得到一个字符流,转换过程中使用utf-8编码格式

    OutputStreamWriter osw = newOutputStreamWriter(fos,"utf-8");

    osw.write('征');//这个字符会先以utf-8格式转换为3个字节,再写到底层的流中

    osw.write('程');

    osw.close();

    OutputStreamWriter将字节数出流转换为字符输出流

    构造方法:OutputStreamWriter(OutputStream os)参数就是要转换为字符流的字节流

    (可以在双参重载构造方法中指定字符集)

    实例:

    public class Demo3 {

    publicstatic void main(String[] args) throws IOException {

    //               test1();

    //按照指定的字符写数据

    BufferedWriterbw = new BufferedWriter(new OutputStreamWriter(

    newFileOutputStream("trans.txt"), "UTF-8"));

    bw.write("钱今凡vjdjb12521");

    bw.newLine();

    bw.write("小强......");

    bw.close();

    BufferedReaderbr = new BufferedReader(new InputStreamReader(

    newFileInputStream("trans.txt"), "UTF-8"));

    System.out.println(br.readLine());

    System.out.println(br.readLine());

    br.close();

    }

    privatestatic void test1() throws IOException {

    /*

    * FileReader是InputStreamReader的子类,是一个便捷类 这个类使用了默认的编码和字节缓冲区

    */

    /*

    * 如果编码不统一会出现乱码情况 FileReader fr = newFileReader("e:\\testabc.txt");

    * char[] cbuf = new char[1024]; int len =fr.read(cbuf);

    * System.out.println(new String(cbuf, 0,len));

    */

    //使用指定的编码来读取指定文本文件中的数据

    FileInputStreamfis = new FileInputStream("E:\\testabc.txt");

    //将字节流转换为字符流 实际上:字符流 = 字节流 + 字符编码

    InputStreamReaderosr = new InputStreamReader(fis, "UTF-8");

    char[]cbuf = new char[1024];

    intlen = osr.read(cbuf);

    System.out.println(newString(cbuf, 0, len));

    }

    }

    相关文章

      网友评论

          本文标题: Java中的IO框架流二

          本文链接:https://www.haomeiwen.com/subject/tsvmxxtx.html