• 黑马程序员


    IO流
    用于处理设备间的数据传输
    按操作数据分:字节流和字符流
    按流向分:输入流和输出流
    IO流常用基类:
    字节流的抽象基类:
    InputStream OutputStream
    字节流的抽象基类:
    Reader Writer
    注意:这4个类派生出的子类名称均以其父类名作为子类名的后缀。
    数据的最常见体现形式是:文件
    下面代码演示常用的写入,读取操作。

    import java.io.*;
    class  FWDemo{                       //输出流演示
        public static void main(String[] args)throws IOException{ //只使用try时,可以不抛出异常
            fw1show();                   //演示文件创建及写入数据
            fw2show();
            fw3show();
        }
        //文件的创建及操作
        public static void fw1show() throws IOException{    
            //创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。
            //而且该文件会被创建到指定目录下。如果该目录下已经有同名文件,原文件将会被覆盖。
            FileWriter fw1 = new FileWriter ("d:\demo1.txt");
            fw1.write("abcde");//将字符串写入内存中的流对象中。
            fw1.flush();       //刷新该流的缓存,将数据写入文件,后面可以继续操作流。
            fw1.close();       //关闭流资源,但是关闭之前会刷新一次内部缓冲的数据。
                               //close()不能再调用 fw.write 。
        }
        //IO异常的处理方式
        public static void fw2show(){
            //注意变量在代码块中的作用域,所以在外部定义变量,在代码块中初始化    
            FileWriter fw2 = null;    
            try{
                fw2 = new FileWriter ("d:\demo2.txt");
                fw2.write("aaaaa");        
            }
            catch (IOException e){
                System.out.println(e.toString()); //打印异常信息
            }
            finally {                              //放入必须执行的数据
                try{
                    if(fw2!=null)
                        fw2.close();
                }
                catch (IOException e){
                    System.out.println(e.toString());
                }
            }
        }
        //续写已有文件
        public static void fw3show(){
            FileWriter fw3 = null;
            try{
                //传递一个true参数,代表不覆盖已有文件,在文件末尾处添加数据。
                fw3 = new FileWriter ("d:\demo1.txt",true);
                fw3.write("+aa
    aaa");        //在demo1.txt 文件末尾添加字符串。
            }    //注意,在windows中换行符是两个组成的是: 
       
            catch (IOException e){
                System.out.println(e.toString());
            }
            finally{  //放入必须执行的数据    
                try{
                    if(fw3!=null)
                        fw3.close();
                }
                catch (IOException e){
                    System.out.println(e.toString());
                }
            }
        }
    }
    class FRDemo{    //输入流演示
        public static void main(String[] args){
            fr1show();       //读取文件并打印
        }
        public static void fr1show(){
            //创建一个文件读取流对象,和指定名称的文件相关联
            //必须确保读取的文件存在,否则会发生异常
            FileReader fr1 = null ;
            FileReader fr2 = null ;
            try{
                fr1 = new FileReader("d:\demo1.txt");
                fr2 = new FileReader("d:\demo1.txt");
                while (true){
                    //read():一次读一个字符,而且会自动往下读取。
                    //read()读取的是字符的字码表数值。
                    int ch = fr1.read();         
                    if(ch==-1)              //判断是否已经读取到文件末尾
                        break;
                    System.out.println((char)ch);
                }
                System.out.println("------------");
                //定义一个字符数组
                //read(char[]) 将字符串存入字符数组返回的是读取到的字符个数
                char [] buf = new char [3]; //一般char[]数组长度取1024,一个字节。
                int num = 0;
                while ((num = fr2.read(buf))!= -1){
                    System.out.println("ch="+(new String(buf,0,num)));
                }    
            }
            catch (IOException e){
                System.out.println("fr1:"+e);
            }
            finally{
                try{
                    if(fr1!=null)
                        fr1.close();
                    if(fr2!=null)
                        fr2.close();
                }
                catch (IOException e){
                    System.out.println(e.toString());
                }
            }
        }
    }

    输入流与输出流的应用演示

    需求:将d盘的一个文件复制到d盘并重命名

    步骤:
    1.在d盘创建一个文件,用于存储d盘源文件的数据。
    2.定义读取流和d盘源文件关联。
    3.通过不断的读写完成数据存储。
    4.关闭资源。

    class CopyDemo{
        public static void main(String[] args){
            copy();                  //调用复制函数
        }
        public static void copy(){
            FileWriter fw = null;    //定义输出流
            FileReader fr = null;     //定义输入流
            try{
                fr = new FileReader("d:\demo1.txt");//将输入流与需创建文件相关联
                fw = new FileWriter("d:\demo3.txt");//将输出流与需复制文件相关联
                char[] buf = new char [1024];         //定义一个中转数组用于存储输入流读取的数据
                int len = 0;                         //定义实数用于记录读取的字符串长度
                while ((len = fr.read(buf))!=-1){    //将输入流读取的数据传给中转数组,并将字符长度传给len
                    fw.write(new String(buf,0,len)); //将数据写入输出流
                }
            }
            catch (IOException e){
                throw new RuntimeException("读写失败");//定义IO异常处理办法
            }
            finally{
                try{
                    if (fw!=null)                       //关闭资源
                        fw.close();
                    if (fr!=null)
                        fr.close();
                }
                catch (IOException e){
                    throw new RuntimeException("读写失败");//定义IO异常处理办法
                }            
            }
        }
    }

    装饰设计模式:
    当想要对已有的对象进行功能增强时,
    可以定义类,将已有对象传入,给予已有的功能,并提供加强功能
    那么自定义的该类称为装饰类

    装饰模式比继承要灵活,避免流体系的臃肿
    而且降低流类与类之间的关系。
    装饰类因为增强流已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。
    所以装饰类和被装饰类通常都是属于一个体系中。

    字符流的缓冲区
    缓冲区就是装饰设计模式的一种应用。
    缓冲区提高了对数据的读写效率.
    所以在创建缓冲区之前,必须现有流对象。
    对应类
    BufferedWriter BufferedReader

    import java.io.*;
    class BufferedDemo{
        public static void main(String[] args) throws IOException{
            bwshow();           //演示输出缓冲区
            brshow();            //演示输入缓冲区
        }
        public static void bwshow() throws IOException{
            //创建一个流对象,并将目标文件与其关联
            FileWriter fw =new FileWriter("d:\buffered.txt");
            //为提高写入效率,加入缓冲技术
            //将需要提高效率的流对象作为参数传递给缓冲区
            BufferedWriter bw = new BufferedWriter (fw);
            bw.write("abcde");
            bw.newLine(); //缓冲区的换行方法
            bw.write("aa");
            bw.flush();
            //缓冲区的关闭,其实是关闭的是其缓冲的流对象,所以不需要单独在关闭流对象
            bw.close(); 
        }
        public static void brshow() throws IOException{
            FileReader fr1 =new FileReader("d:\buffered.txt");
            FileReader fr2 =new FileReader("d:\buffered.txt");
            //为提高写入效率,加入缓冲技术
            //将需要提高效率的流对象作为参数传递给缓冲区
            BufferedReader br = new BufferedReader (fr1);    
            while (true){
                String s1 = br.readLine(); //按照行读取,但是不包含行终止符。
                if (s1 == null)
                    break;
                System.out.println(s1);
            }
            System.out.println("-------------------");
            //缓冲区的关闭,其实是关闭的是其缓冲的流对象,所以不需要单独在关闭流对象
            //传入自定义的buff对象
            MyBuffReader mybuff = new MyBuffReader (fr2);  //定义自定义的缓冲区,并将去与fr2输入流关联
            while (true)
            {
                String s2 = mybuff.myreadline(); //按照行读取,但是不包含行终止符。
                if (s2 == null)
                    break;
                System.out.println(s2);
            }
            br.close(); 
            mybuff.myclose();
        }
    }
    //自定义缓存区,实现readLine()方法代码
    class MyBuffReader{
        private FileReader r;                //定义输入流
        MyBuffReader(FileReader r){            //将输入流传入    
            this.r = r;
        }
        public String myreadline() throws IOException{    //定义自定义的readLine()函数
            //定义一个临时容器,原bufferReader封装的是字符数组
            StringBuilder sb = new StringBuilder ();    
            int ch = 0;
            while ((ch=r.read())!=-1){                    //判断输入流是否读取到文件末尾
                //判断字符串运行到回车符,就返回字符串,否则就继续向sb对象中存储字符。
                if(ch=='
    ')                            //判断是否是回车符的第一个字符,是就结束本次循环
                    continue;
                if(ch=='
    ')                            //判断是否是回车符的第二个字符,是就返回现在StringBuilder中的数据
                    return sb.toString();
                else                                    //如果读取的字符不属于回车符,就将字符存入StringBuilder
                    sb.append((char)ch);
            }
            //当源字符串最后没有回车符时,就不能在循环中返回字符串,
            //此时字符串已经存储在sb对象中,需要添加判断返回字符串。
            if(sb.length()!=0)        
                return sb.toString();
            return null;
        }
        public void myclose() throws IOException{
            r.close();
        }
    }

    字节流
    InputStream OutputStream

    字节流可以操作字符和字节数据,但是在操作字符数据时没有字符流方便。

    import java.io.*;
    class  FODemo{
        public static void main(String[] args)  throws IOException{
            long start = System.currentTimeMillis();
            //fw1show();
            //fr1show();
            copy();
            long end = System.currentTimeMillis();
            System.out.println((end-start)+"ms");
        }
        public static void fw1show()  throws IOException{
            FileOutputStream fo = new FileOutputStream("d:\demo1.txt");//将需写入文件与输出流相关联
            fo.write("aabcde".getBytes());                                //写入数据,注意,当前为字节流,所以写入的应为字符的字节数据。
            fo.close();
        }    
        public static void fr1show() throws IOException{                //演示字节输入流的3种读取方法
            FileInputStream fi1 = new FileInputStream ("d:\demo1.txt");
            FileInputStream fi2 = new FileInputStream ("d:\demo1.txt");
            FileInputStream fi3 = new FileInputStream ("d:\demo1.txt");
            int ch = 0;
            //每次读取一个字符
            while ((ch=fi1.read())!=-1){
                System.out.println((char)ch);
            }
            fi1.close();
            //每次读取一个字符串
            byte [] cha1 = new byte [1024];                                //因为是字节流,所以定义一个字节数组
            int len = 0;
            while((len=fi2.read(cha1))!=-1){                            //讲数据写入字节数组并判断是否已读取到文件末尾
                System.out.println(new String(cha1,0,len));                //将读取的数据转换成字符串并打印
            }
            fi2.close();
            //available方法返回的是可最大连续读取的字节数。
            //注意所使用的内存是否够用
            int num = fi3.available();
            byte [] cha2 = new byte [num];
            int len2 = fi3.read(cha2);
            System.out.println(new String (cha2,0,len2));
        }
        public static void copy(){                                        //字节流可对非文本文件进行复制
            FileOutputStream fo = null;                                    //定义输出流    
            FileInputStream fi = null;                                    //定义输入流
            byte [] cha1 = new byte [1024];
            int len = 0;
            try{
                fo = new FileOutputStream("d:\demo4.jpg");                //将需写入文件与输出流关联
                fi = new FileInputStream ("d:\demo1.jpg");                //将需读取文件与输入流关联
                while((len=fi.read(cha1))!=-1){                            //将数据写入字节数组并判断是否已在文件末尾
                    fo.write(cha1);                                        //将字节数组写入输出流
                }
            }
            catch (IOException e){                                        //定义IO异常处理办法
                System.out.println(e);
            }
            finally{
                try{
                    fi.close();                                            //关闭资源
                    fo.close();
                }
                catch (IOException e){
                    System.out.println(e);
                }
            }
        }
    }

    键盘录入数据
    System.out:标准输出设备 控制台
    System.in:标准输入设备 键盘

    流操作的基本规律:
    1.明确源和目的
    源:输入流
    目的:输出流
    2.操作的数据是否是纯文本
    是:字符流
    否:字节流
    3.明确使用那些具体对象
    源设备:内存,硬盘,键盘
    目的设备:内存,硬盘,控制台


    需求:使用键盘输入数据,并用控制台打出,然后保存为一个文本文件

    扩展:想要把录入的数据按照指定编码表(utf-8)存入文件。

    class TransInDemo{
        public static void main(String[] args) throws IOException{
            //回去键盘录入对象
            InputStream in = System.in;
            //将字节流转换成字符流
            InputStreamReader isr = new InputStreamReader (in);
            //为了提高效率 将字符串进行缓冲区技术
            BufferedReader buf = new BufferedReader (isr);
            //同理设置使用了缓冲技术的字节流转字符流输出
            BufferedWriter bufw =        //将输出流与控制台关联
                new BufferedWriter (new OutputStreamWriter(System.out));
            BufferedWriter bufw1=        //将输出流与写入文件相关联,并定义其编码为utf-8        
                new BufferedWriter (new OutputStreamWriter(new FileOutputStream("d:\demo05.txt",true),"utf-8"));
    
            String line = null;                        //定义空字符串line
            while ((line=buf.readLine())!=null){    //将输入流种数据按行读取写入字符串line,并判断是否读取至数据末尾
                if ("over".equals(line))            //定义关闭命令
                    break;
                bufw.write(line);                    //向控制台写入line中的数据
                bufw1.write(line);                    //向关联的文件中写入line的数据
                bufw.newLine();                        //换行
                bufw1.newLine();    
                bufw.flush();                        //刷新内存,将输出缓冲区中的数据写入目的地
                bufw1.flush();
            }
            buf.close();                            //关闭缓冲区
            bufw1.close();
            bufw.close();
        }
    }
  • 相关阅读:
    "ERR unknown command 'cluster'"
    shell-url-decode
    mac-ppt-auto-open-recovery-files
    gorm-Duplicate-entry
    mac 终端光标在单词之间移动
    seelog 文件输出格式
    nginx-port-Permission-denied
    浏览器-网络
    浏览器-兼容性
    浏览器-浏览器知识
  • 原文地址:https://www.cnblogs.com/myblog-cl/p/4746414.html
Copyright © 2020-2023  润新知