隐藏

java IO流(字节&字符流)
2022年 03月 01 日

Calvin

流的分类:



  1. 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)

  2. 按数据流的流向不同分为:输入流,输出流

  3. 按流的角色的不同分为:节点流,处理流


● 输入流input::读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。

● 输出流output:将程序(内存)数据输出到磁盘、光盘等存储设 备中。


二、流的体系
抽象的基类 节点流(文件流) 处理流
InputStream FileInputStream BufferedInputStream
OutputStream FileOutputStream BufferedOutputStream
Reader FileReader BufferedReader
Writer FileWriter BufferedWriter



字符流和字节流的选择



  • 对于文本文件(.txt,.java,.c,.cpp),使用字符流处理

  • 对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,...),使用字节流处理


字符输入流:


@Test //读取文本类文件的内容并输出到控制台

public void testReadPlus(){
    FileReader fr=null;
    try {
        File file=new File("hello.txt");
        fr=new FileReader(file);
        //读入操作  read(char cbuf[]):每次读入 cbuf数组中的字符个数,若读到尾部,返回-1
        char[] charArr=new char[5];
        int len;
        while ((len=fr.read(charArr))!=-1){
            
            //正确写法
            for (int i = 0; i <len ; i++) {
                System.out.print(charArr[i]);
            }
            //将字符数组按照指定位置转化为String字符串
            String s=new String(charArr,0,len);
            //len=fr.read(charArr);

        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        //关闭资源
        if (fr!=null){
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1
    1. 异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理
    1. 读入的文件一定要存在,否则就会报FileNotFoundException。




字符输出流



  1. 输出操作:对应的File可以不存在。且不会报异常



    • File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件。

      ==>File对应的硬盘中的文件如果存在:

      • 如果流使用的构造器是:FileWriter(file,false) / FileWriter(file):对原有文件的覆盖

      • 如果流使用的构造器是:FileWriter(file,true):不会对原有文件覆盖,而是在原有文件末尾追加内容






public void testWriter(){

    FileWriter fw=null;
    try{
        File file=new File("hello.txt");
        fw=new FileWriter(file,true);//此处参数填入true,不会对原有文件覆盖,而是将文本添加到文件末尾  
        fw.write("今天天气不错!");   
        fw.write("人要有梦想。");
        fw.write("我的梦想是搞钱");
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if (fw!=null){
            try {
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}




字符输入输出流结合:

File file=new File("hello.txt");

    File file1=new File("hi.txt");
    FileWriter fw=new FileWriter(file1,true);
    char[] chars=new char[5];
    FileReader fr=new FileReader(file);
    int len;
    while ((len=fr.read(chars))!=-1){
        for (int i = 0; i <len ; i++) {
            fw.write(chars[i]);
        }
    }
    fw.close();
    fr.close();




字节流输入输出结合:


public void testInputAndOutputStream(){

     long start = System.currentTimeMillis();//获取运行开始时间戳
   
        FileInputStream fin=null;
        FileOutputStream fos=null;
    
        try{
        File srcfile = new File("C:\\Users\\19358\\Desktop\\io_1.mp4");
        File descfile = new File("C:\\Users\\19358\\Desktop\\io_copy.mp4");
        //1、造文件
        
        fin=new FileInputStream(srcfile);
        fos=new FileOutputStream(descfile);
         //2、造流
         
        byte[] bytes=new byte[1024];
        int len;
        while ((len=fin.read(bytes))!=-1){
            fos.write(bytes,0,len);
            //4、复制文件,读写操作 }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        fos.close();}
    long end=System.currentTimeMillis();//获取运行结束时间戳
    System.out.println(end-start);//计算运行时间(ms)
}


缓冲流:



  • 为了提高数据读写的速度,Java API提供了带缓冲(缓存)功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,默认使用8192个字节(8Kb)的缓冲区。


缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:

BufferedInputStream BufferedReader
BufferedOutputStream BufferedWriter



  • 关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也会相应关闭内层节点流


public void testWordCount(){

    FileReader fr=null;//读取文件
    BufferedWriter br=null; //获取的结果放进一个文件中
    try{
        //1、创建map集合
        Map<Character,Integer> map=new HashMap<>();
        //2、遍历读取的每一个字符,和出现次数放在map中
        fr=new FileReader("D:\\java2112\\src\\com\\day14\\ex\\PicTest.java");
        int c=0;
        while ((c=fr.read())!=-1){
            //还原为原来的字符
            char ch= (char) c;
            //判断ch在map结合在是否出现
            if (map.get(ch)==null){
                map.put(ch,1);
            }else {
                map.put(ch,map.get(ch)+1);
            }
        }
        //将map内容写在count.txt文本
        br=new BufferedWriter(new FileWriter("count.txt"));
        //遍历map,将map的key和value写在文件
        Set<Map.Entry<Character, Integer>> entries =
                map.entrySet();
        Iterator<Map.Entry<Character, Integer>> iterator =
                entries.iterator();
        while (iterator.hasNext()){
            Map.Entry<Character, Integer> entry = iterator.next();
            switch (entry.getKey()){
                case ' ':
                    br.write("空格:"+ entry.getValue());
                    break;
                case '\t':
                    br.write("tab键:"+ entry.getValue());
                    break;
                case '\n':
                    br.write("换行:"+ entry.getValue());
                    break;
                case '\r':
                    br.write("回车:"+ entry.getValue());
                    break;
                default:
                    br.write(entry.getKey()+":"+ entry.getValue());
                    break;
            }
            br.newLine();//换行
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if (br!=null){
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

java IO流(字节&字符流)

流的分类:



  1. 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)

  2. 按数据流的流向不同分为:输入流,输出流

  3. 按流的角色的不同分为:节点流,处理流


● 输入流input::读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。

● 输出流output:将程序(内存)数据输出到磁盘、光盘等存储设 备中。


二、流的体系
抽象的基类 节点流(文件流) 处理流
InputStream FileInputStream BufferedInputStream
OutputStream FileOutputStream BufferedOutputStream
Reader FileReader BufferedReader
Writer FileWriter BufferedWriter



字符流和字节流的选择



  • 对于文本文件(.txt,.java,.c,.cpp),使用字符流处理

  • 对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,...),使用字节流处理


字符输入流:


@Test //读取文本类文件的内容并输出到控制台

public void testReadPlus(){
    FileReader fr=null;
    try {
        File file=new File("hello.txt");
        fr=new FileReader(file);
        //读入操作  read(char cbuf[]):每次读入 cbuf数组中的字符个数,若读到尾部,返回-1
        char[] charArr=new char[5];
        int len;
        while ((len=fr.read(charArr))!=-1){
            
            //正确写法
            for (int i = 0; i <len ; i++) {
                System.out.print(charArr[i]);
            }
            //将字符数组按照指定位置转化为String字符串
            String s=new String(charArr,0,len);
            //len=fr.read(charArr);

        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        //关闭资源
        if (fr!=null){
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1
    1. 异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理
    1. 读入的文件一定要存在,否则就会报FileNotFoundException。




字符输出流



  1. 输出操作:对应的File可以不存在。且不会报异常



    • File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件。

      ==>File对应的硬盘中的文件如果存在:

      • 如果流使用的构造器是:FileWriter(file,false) / FileWriter(file):对原有文件的覆盖

      • 如果流使用的构造器是:FileWriter(file,true):不会对原有文件覆盖,而是在原有文件末尾追加内容






public void testWriter(){

    FileWriter fw=null;
    try{
        File file=new File("hello.txt");
        fw=new FileWriter(file,true);//此处参数填入true,不会对原有文件覆盖,而是将文本添加到文件末尾  
        fw.write("今天天气不错!");   
        fw.write("人要有梦想。");
        fw.write("我的梦想是搞钱");
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if (fw!=null){
            try {
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}




字符输入输出流结合:

File file=new File("hello.txt");

    File file1=new File("hi.txt");
    FileWriter fw=new FileWriter(file1,true);
    char[] chars=new char[5];
    FileReader fr=new FileReader(file);
    int len;
    while ((len=fr.read(chars))!=-1){
        for (int i = 0; i <len ; i++) {
            fw.write(chars[i]);
        }
    }
    fw.close();
    fr.close();




字节流输入输出结合:


public void testInputAndOutputStream(){

     long start = System.currentTimeMillis();//获取运行开始时间戳
   
        FileInputStream fin=null;
        FileOutputStream fos=null;
    
        try{
        File srcfile = new File("C:\\Users\\19358\\Desktop\\io_1.mp4");
        File descfile = new File("C:\\Users\\19358\\Desktop\\io_copy.mp4");
        //1、造文件
        
        fin=new FileInputStream(srcfile);
        fos=new FileOutputStream(descfile);
         //2、造流
         
        byte[] bytes=new byte[1024];
        int len;
        while ((len=fin.read(bytes))!=-1){
            fos.write(bytes,0,len);
            //4、复制文件,读写操作 }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        fos.close();}
    long end=System.currentTimeMillis();//获取运行结束时间戳
    System.out.println(end-start);//计算运行时间(ms)
}


缓冲流:



  • 为了提高数据读写的速度,Java API提供了带缓冲(缓存)功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,默认使用8192个字节(8Kb)的缓冲区。


缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:

BufferedInputStream BufferedReader
BufferedOutputStream BufferedWriter



  • 关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也会相应关闭内层节点流


public void testWordCount(){

    FileReader fr=null;//读取文件
    BufferedWriter br=null; //获取的结果放进一个文件中
    try{
        //1、创建map集合
        Map<Character,Integer> map=new HashMap<>();
        //2、遍历读取的每一个字符,和出现次数放在map中
        fr=new FileReader("D:\\java2112\\src\\com\\day14\\ex\\PicTest.java");
        int c=0;
        while ((c=fr.read())!=-1){
            //还原为原来的字符
            char ch= (char) c;
            //判断ch在map结合在是否出现
            if (map.get(ch)==null){
                map.put(ch,1);
            }else {
                map.put(ch,map.get(ch)+1);
            }
        }
        //将map内容写在count.txt文本
        br=new BufferedWriter(new FileWriter("count.txt"));
        //遍历map,将map的key和value写在文件
        Set<Map.Entry<Character, Integer>> entries =
                map.entrySet();
        Iterator<Map.Entry<Character, Integer>> iterator =
                entries.iterator();
        while (iterator.hasNext()){
            Map.Entry<Character, Integer> entry = iterator.next();
            switch (entry.getKey()){
                case ' ':
                    br.write("空格:"+ entry.getValue());
                    break;
                case '\t':
                    br.write("tab键:"+ entry.getValue());
                    break;
                case '\n':
                    br.write("换行:"+ entry.getValue());
                    break;
                case '\r':
                    br.write("回车:"+ entry.getValue());
                    break;
                default:
                    br.write(entry.getKey()+":"+ entry.getValue());
                    break;
            }
            br.newLine();//换行
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if (br!=null){
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

上一篇
JAVA IO 流
下一篇
MYSQL 笔记汇总

评论区(暂无评论)

这里空空如也,快来评论吧~

我要评论