黑马程序员——Java基础---IO流<实例>

来源:互联网 发布:java并发框架支持锁 编辑:程序博客网 时间:2024/06/06 12:48

——- android培训、java培训、期待与您交流! ———-

概述

流用于处理设备上数据。
流:可以理解数据的流动,就是一个数据流。IO流最终要以对象来体现,对象都存在IO包中。
流也进行分类:
1:按照数据流的方向不同可以分为:输入流和输出流。
2:按照处理数据单位不同可以分为:字节流和字符流。
3:按照实现功能不同可以分为:节点流和处理流。
具体请看 上一个blog《Java IO流<总览>》

http://blog.csdn.net/mu_se/article/details/46418875

补充

IO中的使用到的设计模式:装饰设计模式。

装饰设计模式解决:对一组类进行功能的增强。
包装:写一个类(包装类)对被包装对象进行包装;
* 1、包装类和被包装对象要实现同样的接口;
* 2、包装类要持有一个被包装对象;
* 3、包装类在实现接口时,大部分方法是靠调用被包装对象来实现的,对于需要修改的方法我们自己实现;

流的操作规律:

1,明确源和目的。
数据源:就是需要读取,可以使用两个体系:InputStream、Reader;
数据汇:就是需要写入,可以使用两个体系:OutputStream、Writer;
2,操作的数据是否是纯文本数据?
如果是:数据源:Reader
数据汇:Writer
如果不是:数据源:InputStream
数据汇:OutputStream
3,虽然确定了一个体系,但是该体系中有太多的对象,到底用哪个呢?
明确操作的数据设备。
数据源对应的设备:硬盘(File),内存(数组),键盘(System.in)
数据汇对应的设备:硬盘(File),内存(数组),控制台(System.out)。
4,需要在基本操作上附加其他功能吗?
比如缓冲。 如果需要就进行装饰。

转换流

转换流特有功能:
转换流可以将字节转成字符,原因在于,将获取到的字节通过查编码表获取到指定对应字符。

转换流的最强功能就是基于 字节流 + 编码表 。没有转换,没有字符流。

发现转换流有一个子类就是操作文件的字符流对象:
InputStreamReader
|–FileReader
OutputStreamWriter
|–FileWrier

想要操作文本文件,必须要进行编码转换,而编码转换动作转换流都完成了。所以操作文件的流对象只要继承自转换流就可以读取一个字符了。

但是子类有一个局限性,就是子类中使用的编码是固定的,是本机默认的编码表,对于简体中文版的系统默认码表是GBK。

PrintStream:打印流

1:提供了更多的功能,比如打印方法。可以直接打印任意类型的数据。
2:它有一个自动刷新机制,创建该对象,指定参数,对于指定方法可以自动刷新。
3:它使用的本机默认的字符编码.
4:该流的print方法不抛出IOException。

该对象的构造函数。
PrintStream(File file) :创建具有指定文件且不带自动行刷新的新打印流。
PrintStream(File file, String csn) :创建具有指定文件名称和字符集且不带自动行刷新的新打印流。
PrintStream(OutputStream out) :创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush) :创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush, String encoding) :创建新的打印流。
PrintStream(String fileName) :创建具有指定文件名称且不带自动行刷新的新打印流。
PrintStream(String fileName, String csn)

PrintStream可以操作目的:
1:File对象。2:字符串路径。3:字节输出流。
前两个都JDK1.5版本才出现。而且在操作文本文件时,可指定字符编码了。

当目的是一个字节输出流时,如果使用的println方法,可以在printStream对象上加入一个true参数。这样对于println方法可以进行自动的刷新,而不是等待缓冲区满了再刷新。最终print方法都将具体的数据转成字符串,而且都对IO异常进行了内部处理。

既然操作的数据都转成了字符串,那么使用PrintWriter更好一些。因为PrintWrite是字符流的子类,可以直接操作字符数据,同时也可以指定具体的编码。

PrintWriter具备了PrintStream的特点同时,还有自身特点:
该对象的目的地有四个:1:File对象。2:字符串路径。3:字节输出流。4:字符输出流。

开发时尽量使用PrintWriter。

方法中直接操作文件的第二参数是编码表。
直接操作输出流的,第二参数是自动刷新。

//读取键盘录入将数据转成大写显示在控制台.

BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//源:键盘输入//目的:把数据写到文件中,还想自动刷新。PrintWriter out = new PrintWriter(new FileWriter("out.txt"),true);//设置true后自动刷新String line = null;while((line=bufr.readLine())!=null){    if("over".equals(line))        break;    out.println(line.toUpperCase());//转大写输出}

注意:System.in,System.out这两个标准的输入输出流,在jvm启动时已经存在了。随时可以使用。当jvm结束了,这两个流就结束了。但是,当使用了显示的close方法关闭时,这两个流在提前结束了。

out.close();bufr.close();

应用:

package XianChen;import java.io.*;import java.util.*;public class LiZi {    public static void main(String[] args) throws Exception {        fuzhi_1();        fuzhi_2();        fuzhi_3();    }//  FileReader()、FileWriter();//  创建文本文件    public static void fuzhi_1() {        /*        1:创建一个字符输出流对象,用于操作文件。该对象一建立,就必须明确数据存储位置,是一个文件。        2:对象产生后,会在堆内存中有一个实体,同时也调用了系统底层资源,在指定的位置创建了一个存储数据的文件。        3:如果指定位置,出现了同名文件,文件会被覆盖。        4: 流操作因为涉及外界数据,需要处理各种异常        *///      创建一个字符输入流对象             FileReader fr=null;//      创建一个字符输出流对象             FileWriter fw=null;//      将字符串写入文本        try {//          初始化//          创建一个文件对象    打印是否存在同名文件            System.out.println(!(new File("yuan.txt").createNewFile()));//          文件必须存在,否则报异常            fr = new FileReader("yuan.txt");            fw = new FileWriter("yuan.txt");//          定义要存入文本的字符串            String str = "ABCDEF\r\n123456\r\n";//          存入指定文本            fw.write(str);//          读取刚才的文本//          定义简单缓冲区            int num;        //          读取单个字符,如果已到达流的末尾,则返回 -1                         while((num=fr.read())!=-1){//              将文本内容打印到控制台//              输出结果://              ABCDEF//              123456                System.out.print((char)num);                }        } catch (Exception e1) {            e1.printStackTrace();//          最终动作关流//          关闭流,其实关闭的就是java调用的系统底层资源。在关闭前,会先刷新该流。//          close()和flush()的区别://          flush():将缓冲区的数据刷到目的地中后,流可以使用。//          close():将缓冲区的数据刷到目的地中后,流就关闭了,该方法主要用于结束调用的底层资源。这个动作一定做。        }finally{//          流需要单独关,分别try            try {                fr.close();            } catch (IOException e) {                e.printStackTrace();            }            try {                fw.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }//  FileInputStream、FileOutputStream(); //  复制一个 图片    public static void fuzhi_2() {//      创建一个字节输入流对象        FileInputStream fi = null;//      创建一个字节输出流对象        FileOutputStream fo = null;        try {            String name_yu = "yuan.jpg";            String name_fu = "fuben.jpg";            fi = new FileInputStream(name_yu);            fo = new FileOutputStream(name_fu);//          定义简单缓冲区            int num;//          读取单个字符,如果已到达流的末尾,则返回 -1             while((num=fi.read())!=-1){                fo.write(num);            }               } catch (IOException e) {               e.printStackTrace();        }    }//  录入键盘数据,并保存在文本文件中    public static void fuzhi_3() {//      从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读写。        BufferedReader br=null;        BufferedWriter bw=null;//转换流       //是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。//它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。//每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。//要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。         InputStreamReader isr = null;        OutputStreamWriter osw= null;//      字节输出流,输出到文件        FileOutputStream fos;        PrintWriter pr =null;        try{//      建立键盘读取流        br = new BufferedReader(new InputStreamReader(System.in));//  ==> isr = new InputStreamReader(System.in);//      br  = new BufferedReader(isr);              //      建立文件输出流   1        bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("键盘录入.txt")));//      建立文件输出流   2 (开发推荐)        pr = new PrintWriter("PrintDemo.txt");//      定义简单缓冲变量        String line;        int num =0;//      读取一个文本行。通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行。//      readLine方法返回的时候是不带换行符的。        while((line=br.readLine())!=null){//          判断输入终止,双空行            if(line.length()==0){                num++;                if(num==2)                    break;            }else{//              重置判断标志                num=0;//              写入流中                bw.write(line);//              打印流的特有方法、 自动换行                pr.println(line);//              换行                bw.newLine();//              刷新                bw.flush();                pr.flush();            }        }                   }catch(IOException e){            System.out.println("wrong");        }        finally{            try {                if(br!=null)                    br.close();            } catch (IOException e) {                e.printStackTrace();            }            try {                if(bw!=null)                    bw.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}

——- android培训、java培训、期待与您交流! ———-

0 0
原创粉丝点击