21IO流 和缓冲流 和处理流

IO流本质就是数据传输的一套机制 Input OutPut Stream 输入输出流

根据数据传输的方向:1.往内存传输数据----输入流

                                    2.内存往外面传数据------输出流

 按照流的角色分,可以分节点流和处理流

 

 

 

根据数据传输的方式分为:1.字节流2.字符流

javaIO流的四大基本流

  字符流 字节流
输出流 字符输出流(Writer) 字节输出流(OutputStream)
输入流 字符输入流(Reader) 字节输入流(InputStream)

四大基本流对应的类都是抽象类

数据存储位置(数据传输的场景):硬盘、内存、网络、IO设备(键盘,鼠标。。。)

硬盘:

往硬盘上一个txt文件写入数据:字符输出流

采用其中的子类:FlieWriter

public static void main(String[] args) throws IOException {
    //创建一个FileWriter对象
    //检测路径正确与否
    //如果路径正确但是没有具体的文件就会创建一个空文件
    //如果文件已经存在就会再创建一个空文件覆盖之前的文件内容
    //保证再写数据之前有一个空文件
    FileWriter fw=new FileWriter("D:\\1.txt");
    
    //写数据
    //底层是基于缓冲区进行数据传输的
    //默认要求缓冲区数据装满才能进行传输
    //下面的数据没有装满,缓冲区就没有进行传输
    fw.write("您好");
    //冲刷缓冲区
    //不管缓冲区数据有没有存满都要进行传输
    //防止数据滞留在缓冲区产生数据丢失的问题
    fw.flush();
    //关闭连接通道 ----关流
    //在关闭通道之前会自动冲刷缓冲区的操作
    fw.close();
    
    //强制对象值为null
    //把对象置为无用对象,在某个时间进行垃圾回收
    fw=null;
}

 捕获IO流输出异常处理

1.在try catch外进行声明对象,在try块里进行对象的初始化

2.保证对象已经进行正常的初始化,才能进行关流操作

3.不管你有没有关流成功与否,都要对我们的对象置为无用对象,等待回收

4.流关闭失败有可能是在自动冲刷缓冲区之前,保证数据不能滞留在缓冲区,所以我们需要手动冲刷缓冲区

    public static void main(String[] args) {
        //1.声明FileWriter对象
        FileWriter fw=null; //保证有值 不能保证try块里一定能赋值
        try {
            //对象真实赋值
            fw=new FileWriter("D:\\2.txt");
            //写入数据
            fw.write("123");
            //4.手动冲刷缓存区
            fw.flush();
        }catch (IOException e) {
            e.printStackTrace();
        }
        finally {//不管try块里代码正确与否都要关流
            if(fw!=null)//2.保证对象初始化成功,不为Null,这样才能正确调用关流方法
            {
                try {
                    fw.close(); //关流有可能失败
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                finally {
                    //3.对象置为无用对象----垃圾回收
                    fw=null;
                }
            }


    }
}

从一个硬盘的txt文件读取数据  字符输入流 文件 FileReader

public static void main(String[] args) throws IOException {
    //创建FileReader对象
    FileReader rd=new FileReader("D:\\2.txt");
    //读取数据
    //返回的是读取到的字符的编码值
    //读取结束的标志是返回一个-1
    int len=-1; //提供一个变量共给读取数据覆盖
    while((len=rd.read())!=-1) //避免读取两次情况
    System.out.println((char)len);
//关流---输入流没有缓冲区
rd.close(); }

 

因为FileReader没有缓冲区,所以读取的时候是一个个读取的读取效率低下,所以我们需要自己创建一个缓冲区进行读取

    public static void main(String[] args) throws IOException {
        // 创建FileReader对象
        FileReader rd=new FileReader("D:\\3.txt");
        //读取数据
        //自建缓冲区--数组---字符流---字符数组
        char[] cs=new char[5];
        int len=-1;
        while((len=rd.read(cs))!=-1) {//读到的内容存放在数组中
            System.out.println(new String(cs,0,len));//将字符数组转成字符串做输出
        }
         //关流
        rd.close();
    }

}

结果:

45656
46584
89849
848

    public static void main(String[] args) throws IOException {
        // 创建FileReader对象
        FileReader rd=new FileReader("D:\\3.txt");
        //读取数据
        //自建缓冲区--数组---字符流---字符数组
        char[] cs=new char[5];
        int len=-1;
        while((len=rd.read(cs))!=-1) {//读到的内容存放在数组中
            System.out.println(new String (cs)); 
          
        }
         //关流
        rd.close();
    }

45656
46584
89849
84849

rd.read(cs)返回的是放进到cs数组中的元素个数和读到的字符,rd.read()把读到的字符做返回。

复制文件实例

 

//通过字符流实现文件复制
public class FileCopyText1 {
    public static void main(String[] args) {
        //
        long start=System.currentTimeMillis();
        //声明IO流对象
        FileReader reader=null;
        FileWriter writer=null;
        try {
            //对象的初始化---指明两个文件的路径
            reader=new FileReader("E:\\a1.txt");
            writer=new FileWriter("D:\\javase\\a1.txt");
            
            //读取数据
            //自建数组---缓冲区
            char[] cs=new char[1024*1024*10];//读取1M
            int len=-1;//接收每次返回的字符个数
            while((len=reader.read(cs))!=-1){
                //写出数据
                writer.write(cs, 0, len);
            }
            //冲刷缓冲区
            writer.flush();
        } catch (Exception e) {
            // TODO: handle exception
        }finally {
            //保证流对象不能为null1去关流
            if(reader!=null)
                try {
                    reader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }finally {
                    //置为无用对象
                    reader=null;
                }
            
            if(writer!=null)
                try {
                    writer.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }finally {
                    //无用对象·
                    writer=null;
                }
        }
        //
        long end=System.currentTimeMillis();
        System.out.println(end-start);
    }
}

缓冲流(用于提供缓冲区):这个提供的的缓冲区不同于输出流自带的缓冲区,我们自己写的缓冲区大小,效率不太好,所以我们想让java给我们提供一个缓冲区

 BufferedReader: 给字符输入流提供一个强大的缓冲区  有一个好的方法  readLine();

public static void main(String[] args) throws IOException {
    //创建缓冲流对象
    //真正读取内容的流对象是FileReader,字符输入流
    //缓冲流对象只是给字符输入流提供一个缓冲区
    BufferedReader br=new BufferedReader(new FileReader("D:\\3.txt"));
  //读取一行(只要没有换行符那么就是一行)结束标志是null
    String s="";
    while((s=br.readLine())!=null)
    System.out.println(s);
}

 统计工作空间.java文件中有多少行代码

 

public class CountCodeLine {
    //统计数
    static int count;
    public static void main(String[] args) throws IOException {
        //文件对象---指定工作空间
        File file=new File("D:\\workspace");
        //调用方法
        countLine(file);
        //
        System.out.println(count);
    }
    
    //获取到所有.java文件并统计有多少行
    public static void countLine(File file) throws IOException{
        //判断是否是文件夹
        if(file.isDirectory()){
            //获取当前目录下的所有信息
            File[] fs=file.listFiles();
            //遍历数组---递归调用
            for (File f : fs) {
                countLine(f);
            }
        }else if(file.getName().endsWith(".java")){//文件
            //一定都是.java文件
            //读取文件
            BufferedReader br=new BufferedReader
                    (new FileReader(file));
            //进入循环---统计有多行
            while(br.readLine()!=null){//走一次循环有一行代码
                count++;
            }
        }
    }

}

BufferedWriter:给字符输出流提供一个更大的缓存区

 

public class BufferedWriterDemo {
    public static void main(String[] args) throws IOException {
        //
        BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\b.txt"));
        //写出数据
        bw.write("abc");
        //换行---不管具体什么的操作系统
        //不同操作系统的换行符不一样
        //Windows---\r\n  linux---\n
        bw.newLine();
        bw.write("123");
        
        //关流--冲刷缓冲区
        bw.close();
    }
}

 

处理流

1.处理流的用法

 

posted @ 2019-07-23 09:59  三十六烦恼风x  阅读(327)  评论(0编辑  收藏  举报