美文网首页
Java-IO流(四)-字符流(FileReader、FileW

Java-IO流(四)-字符流(FileReader、FileW

作者: 码农随想录 | 来源:发表于2018-07-21 12:40 被阅读14次

    字节流读取字符的问题

    一次读一个字节。这样对中文是无法判断。怎么解决呢?一个中文默认是两个字节

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.IOException;
    
    public class CharStreamDemo {
    
        /**
         * @param args
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
            
            /*
             * 需求1:通过流写一个篇文章,里面有中文。"你好你好"。indexOf('好');
             */
    //      writeCNText();
            
            
            /*
             * 需求2:一篇文章中出现了多少个好字。读取数据。判断好字并计数。
             * 思路:读取一个文本,获取内容判断好字。
             */
            
             readCNText();
        }
    
        public static void readCNText() throws IOException {
            FileInputStream fis = new FileInputStream("tempfile/cn.txt");
            
            //一次读一个字节。这样对中文是无法判断。怎么解决呢?一个中文默认是两个字节。
            //读取所有的字节,存储起来(字节数组),变成字符串。然后找指定的字符。
            
    //      byte[] buf = new byte[4];
    //      int len = 0;
    //      while((len=fis.read(buf))!=-1){
    //          String str = new String(buf,0,len);
    //          System.out.println(str);
    //      }
            
    //      int ch = 0;
    //      while((ch=fis.read())!=-1){
    //          System.out.println(ch);
    //      }
            
            int ch = fis.read();
            System.out.println("读取一个字节:"+ch);
            int ch1 = fis.read();
            System.out.println("读取一个字节:"+ch1);
            fis.close();
            
        }
    
        public static void writeCNText() throws FileNotFoundException, IOException {
            FileOutputStream fos = new FileOutputStream("tempfile/cn.txt");
            
            fos.write("你好你好".getBytes());
            
            fos.close();
        }
    
    }
    

    编码表

    编码表:其实就是生活中文件和计算机二进制的对应关系表。
    1,ascii: 一个字节中的7位就可以表示。对应的字节都是正数。0-xxxxxxx
    2,iso8859-1:拉丁码表 latin,用了一个字节用的8位。1-xxxxxxx  负数。
    3,GB2312:简体中文码表。6,7仟的中文和符号。用两个字节表示。两个字节都是开头为1 两个字节都是负数。
        GBK:目前最常用的中文码表,2万的中文和符号。用两个字节表示,一部分文字,第一个字节开头是1,第二字节开头是0
        GB18030:
    4, unicode:国际标准码表:无论是什么文字,都用两个字节存储。Java中的char类型用的就是这个码表。char c = 'a';占两个字节。
        在Java中,字符串是按照系统默认码表来解析的。简体中文版 字符串默认的码表是GBK。
    5,UTF-8:基于unicode,一个字节就可以存储数据,不要用两个字节存储,而且这个码表更加的标准化,在每一个字节头加入了编码信息(后期到api中查找)。
                    
        能识别中文的码表:GBK  UTF-8  正因为识别中文码表不唯一,涉及到了编码解码问题。
        对于我们开发而言;常见的编码 GBK  UTF-8  ISO8859-1
        文字--->二进制(数字) :编码。
        二进制(数字)--->文字  : 解码。
    

    FileReader读取字符流

    之前都是FileInputStream 用于读取字节流,FileInputStream 用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader。
    
    查阅FileInputStream api说明中是否有相关的提示呢?发现一个新名词。
    字符流:之前用的都是字节流,用于操作的都是字节数据,字符流,专门用于操作字符数据的流对象。
    
    索引了api中的提到的 FileReader对象。发现这个对象是一个操作字符文件的便捷类,内部类使用默认的字符集解码+默认的字节缓冲区。
        其中,提到了一个如果需要修改这些值(指定码表,或者缓冲区等)需要查阅InputStreamReader。
        目前为了解决当前问题,不需要,只需要使用默认即可。
        
        使用FileReader时,了解它的功能,看它所属的体系顶层。Reader。
        Reader:读取字符流的抽象超类。read():读取单个字符并返回, read(char[]):将数据读取到数组中,并返回读取的个数。
        
    FileReader : 字节读取流+默认编码表。
    
    字符流:为了便于操作数据中的字符数据。原理: 字节流+编码表。
    字符流的两个基类。
    
        Reader:read()读取字符。
            |-
        
        Writer(Reader的另请参见):写入字符。
            |-
        
    字节流操作的是字节数组(byte[]);字符流操作的是字符数组(char[])。
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.IOException;
    
    public class CharStreamDemo {
    
        /**
         * @param args
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
           
            /*
             * 解决需求2问题:
             * 使用FileReader。
             * 
             */
             System.out.println("-----------读取字符-------------");
            readCNTextByReader();
            
        }
    
        public static void readCNTextByReader() throws IOException {
    
            //创建一个读取字符文件的读取流对象。FileReader。
            FileReader fr = new FileReader("tempfile/cn.txt");//这个流的底层使用的是FileInputStream
            
    //      int ch = fr.read();
    //      System.out.println("读取一个字符:"+ch);
    //      int ch1 = fr.read();//一次读取一个中文,读取多个字节查表转成中文。
    //      System.out.println("读取一个字符:"+(char)ch1);
            int ch = 0;
            int count = 0;
            while((ch=fr.read())!=-1){
                if(ch=='好'){
                    count++;
                }
            }
            System.out.println("count="+count);
            fr.close();
        }
    }
    

    FileWriter写入字符文件

    import java.io.FileWriter;
    import java.io.IOException;
    
    public class FileWriterDemo {
    
        /**
         * @param args
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
            //演示FileWriter 用于操作文件的便捷类。
            FileWriter fw = new FileWriter("tempfile/fw.txt");
            
            fw.write("你好谢谢再见");//这些文字都要先编码。都写入到了流的缓冲区中。
            
            fw.flush();
            
            fw.close();
            
            /*
             * flush()和close()的区别?
             * 
             * flush():将流中的缓冲区缓冲的数据刷新到目的地中,刷新后,流还可以继续使用。
             * close():关闭资源,但在关闭前会将缓冲区中的数据先刷新到目的地,否则丢失数据,然后在关闭流。流不可以使用。
             * 
             * 如果写入数据多,一定要一边写一边刷新,最后一次可以不刷新,由close完成刷新并关闭。
             * 
             * 
             */
        }
    
    }
    

    相关文章

      网友评论

          本文标题:Java-IO流(四)-字符流(FileReader、FileW

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