Stream

什么是流(Stream),流就是一系列的数据

字节流

  1. InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。FileInputStream 是InputStream子类,以FileInputStream 为例进行文件读取

    package stream;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    
    public class TestStream {
    
     public static void main(String[] args) {
         try {
             //准备文件lol.txt其中的内容是AB,对应的ASCII分别是65 66
             File f =new File("d:/lol.txt");
             //创建基于文件的输入流
             FileInputStream fis =new FileInputStream(f);
             //创建字节数组,其长度就是文件的长度
             byte[] all =new byte[(int) f.length()];
             //以字节流的形式读取文件所有内容
             fis.read(all);
             for (byte b : all) {
                 //打印出来是65 66
                 System.out.println(b);
             }
    
             //每次使用完流,都应该进行关闭
             fis.close();
    
         } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
             }
           }
           }

字符流

  1. FileReader 是Reader子类,以FileReader 为例进行文件读取

    package stream;
    
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    
    public class TestStream {
    
     public static void main(String[] args) {
         // 准备文件lol.txt其中的内容是AB
         File f = new File("d:/lol.txt");
         // 创建基于文件的Reader
         //jdk7新特性,可在try后括号内定义流,此流在执行完try-catch命令后自动释放,故可省去finally代码
         try (FileReader fr = new FileReader(f)) { 
             // 创建字符数组,其长度就是文件的长度
             char[] all = new char[(int) f.length()];
             // 以字符流的形式读取文件所有内容
             fr.read(all);
             for (char b : all) {
                 // 打印出来是A B
                 System.out.println(b);
             }
         } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
             }
             }
             }        
  2. FileWriter 是Writer的子类,以FileWriter 为例把字符串写入到文件

    需要注意的是使用FileWriter中的write,先把数据写入内存缓冲区(字符串转化为字节的过程),使用FileWriter中的方法flush将内存缓冲区的数据刷新到文件中

    package stream;
    
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class TestStream {
        public static void main(String[] args) {
             // 准备文件lol2.txt
             File f = new File("d:/lol2.txt");
             // 创建基于文件的Writer
             try (FileWriter fr = new FileWriter(f)) {
                 // 以字符流的形式把数据写入到文件中
                 String data="abcdefg1234567890";
                 char[] cs = data.toCharArray();
                 fr.write(cs);
                 } catch (IOException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                     }
                 }
     }

中文问题

  1. 使用字节读取中文字符时,GBK占用2个字节,utf-8占用3个字节。所以最好用字符流读取。
     public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException {
         File f = new File("E:\\project\\j2se\\src\\test.txt");
         System.out.println("默认编码方式:"+Charset.defaultCharset());
         //FileReader得到的是字符,所以一定是已经把字节根据某种编码识别成了字符了
         //而FileReader使用的编码方式是Charset.defaultCharset()的返回值,如果是中文的操作系统,就是GBK
         try (FileReader fr = new FileReader(f)) {
             char[] cs = new char[(int) f.length()];
             fr.read(cs);
             System.out.printf("FileReader会使用默认的编码方式%s,识别出来的字符是:%n",Charset.defaultCharset());
             System.out.println(new String(cs));
         } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }