• java流知识小结


    一、流的分类

        InputStream 抽象字节输入流类

        OuputStream 抽象字节输出流类

        Reader 抽象字符输入流类

        Writer 抽象字符输出流类

    二、字节输入流类及其子类

         

     三、字节输出的类及其子类

     

    四、字符输入,输出流类

      1.抽象字符流:   Reader                 Writer

      2.文件字符流:   FileReader            FileWriter

      3.缓冲字符流:   BufferedReader     BufferedWriter

    /**

     *凡是字符流都有缓存,写数据时一定要记得刷缓存(flush),

         否则数据不一定会及时写出去。close方法在关流之前会调一次flush

     */

    五、DataInputStream,DataOutputStream

    1.需要套接,里面可套接一个文件输入,输出流

    2.写的时候可利用溢出来控制循环结束

      如:

    1. short i=0, j=1;
    2. do{
    3. out.writeInt(i);
    4. out.writeInt(j);
    5. i = (short) (i + j);
    6. j = (short) (i + j);
    7. }while(i>0);//利用溢出来控制循环结束,i>0开始循环,总会加到溢出的时候

    3.读的时候可利用in.available判断循环结束,也可利用异常的方式判断文件结束

          如: while(in.available()>0){//利用available()来判断文件结束

    1. while(true){//方式二利用异常来判断文件结束
    2. try {
    3. int n= din2.readInt();//读到文件末尾则抛出EOFException
    4. System.out.println(n);
    5. } catch (IOException e) {
    6. break;//读到文件末尾,跳出循环----读动作结束
    7. }
    8. }

    六、FileInputStream,FileOutputStream

    1.创建一个文件流

      如:

    1. String dir2 = "D:/mycode/ioDemo/b/";
    2. String fileName = "3.jpg";
    3. File dir = new File(dir2);//注意dir2是路径不是文件夹
    4. if(!dir.exists()){
    5. dir.mkdirs();
    6. }
    7. FielOutputStream out = new FileOutputStream(dir2+fileName);

    2.可利用In.available判断循环结束

         如:

    1. byte buf[] = new byte[512];
    2. while(in.available()>0){
    3. int len = in.read(buf);
    4. out.write(buf,0,len);
    5. }

    3.文件输出流可以以追加的方式写文件,即程序运行几次就往目标文件写入几次信息

          如:

    1. String str = "门前大桥下游过一群鸭,快来快来数一数,2.4.6.7.8";
    2. FileOutputStream out = new FileOutputStream("c.txt",true);
    3. out.write(str.getBytes("gbk"));

    七、ObjectInputStream,ObjectOutputStream  

    1.输出的类对象必须实现序列化(即实现Serializabe接口) 

    2.一般也需要套接一个文件字节输入,输出流

    3.利用异常来结束文件的读取

      如:  

    1.   while(true){//objecteInputstream用异常来结束文件的读取
    2.              Person p = (Person) in.readObject();
    3.                 System.out.println(p);
    4.             }

    八、printStream,printWriter

        1)只有输出没有输入。PrintStream是字节打印流,PrintWriter是字符打印流。

        2)能够方便地打印各种数据“值表示形式”,提供了一系列的打印功能(只有它有,其它流都没有。)

       3)和其他输出流不同,它永远不会抛出IOException异常(构造方法除外),异常内部解决且设置了内部标志。

      4)可创建具有自动刷新的功能,可使用带换行符的println()方法。

        autoFlush - boolean 变量;如果为 true,则 println、printf 或 format 方法将刷新输出缓冲区。---其实是因为这几个方法中帮我们调用了out.flush()。

      5)(在构造方法中)可以指定字符集编码的。

    九、ByteArrayInputStream、ByteArrayOutputStream字节数组流

    CharArrayReader与CharArrayWriter字符数组流

    StringReader 与 StringWriter字符串流

    1、用于操作字节数组的流对象,其实它们就是对应设备为内存的流对象。

    2、该流的关闭是无效的,因为没有调用过系统资源。

    3、按照流的读写思想操作数组中元素。

    如:

      //    使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。

    1. ByteArrayInputStream baim = new ByteArrayInputStream("wozuishuai".getBytes());
    2. ByteArrayOutputStream baom = new ByteArrayOutputStream();
    3. int len = 0;
    4. while((len=baim.read())!=-1){
    5. baom.write(len);
    6. }
    7. System.out.println( baom.toString() );

    十、BufferedInputStream,BufferedOutputStream

    在使用缓冲输入输出流的时候,推荐用法:

      如:DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream("a/g.txt")));

    十一、InputStramReader,OutputStramWriter转换流

    转换流功能1:充当字节流与字符流之间的桥梁

    //InputStreamReader把字节流输入流转换为字符输入流,从键盘输入是流  //OutputStreamWriter把字符流转换为字节流,从纯文本读数据为字符流

      如:

    1. InputStreamReader in = new InputStreamReader(System.in)
    2.    BufferedWriter out =
    3.                  new BufferedWriter(
    4.                  new OutputStreamWriter(
    5.                   new FileOutputStream("a/h.txt")));

    转换流功能2:字符编码转换

      如:

    1. BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a/test3.txt"),"utf-8"));  写
    2. //BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("a/test_utf8.txt"),"utf-8") );  读

    十二、写换行符

    1.  bw.write(str+"\n");//Linux方式。该方式用记事本不是换行显示,但写字板是
    2. //bw.write(str+"\r\n");//windows方式。该方式用记事本和写字板都是换行显示
    3. out.newLine();//根据系统平台,自动添加(回车)换行

    十三、SequenceInputStream序列流

    1. 对多个流进行合并
    2. FileInputStream f2 = new FileInputStream("seq/seq2.txt");
    3. FileInputStream f3 = new FileInputStream("seq/seq3.txt");
    4. ArrayList<FileInputStream> list= new ArrayList<FileInputStream>();
    5. list.add(f2);
    6. list.add(f3);
    7. //public static <T> ArrayList<T> list(Enumeration<T> e)
    8. //返回一个指定 collection 上的枚举。
    9. Enumeration<FileInputStream> en= Collections.enumeration(list);
    10. SequenceInputStream sis = new SequenceInputStream(en);//★
    11. //以上为从源读

    十四、利用字符编码的原理 解决中文乱码

    1.     如:/*以后我们开发后台会遇到一个乱码场景:
    2.   * 1、浏览器编码并发送(str的字节数组--码值)--->
    3.  * 2、浏览器接收并解码(查iso8859-1表,得到字符串name),
    4.  * 传参给 MyServlet --->
    5.  * 3、MyServlet接收到的name参数就是乱码
    6.  */
    7.      String str = "张三";
    8.      //通过编译平台得到编码
    9.      byte buf[] = str.getBytes("utf-8");
    10.     
    11.      //模拟浏览器的处理(解码--解错了,即浏览器解码所用的码表可能与你编码所用的码表不同)
    12.      String str1 = new String(buf,"gbk");
    13.      System.out.println(str1);//浏览器解码所得的信息为乱码
    14.     
    15.      //此时,若想得到原来的信息,既要将错误的浏览器解码所得出的乱码信息,用
    16.      //浏览器的编码,从新解码,还原出正确的编码,再将正确的编码,用你自己原本
    17.      //的编译平台上的码表,进行解码
    18.     
    19.      byte buf1[] = str1.getBytes("gbk");
    20.     
    21.      String str3 = new String (buf1,"utf-8");
    22.      System.out.println(str3);

    十五、序列化

    1. private transient int num=30;//如果不想序列化某个非静态变量, 可以把它设成瞬时
    2. //如果没有transient则输出的num值为30,有则为0
    3. private int age;
    4. //只有对象中的非静态变量才会被序列化, 静态变量和方法都是不会被存入文件的。
    5. public static int count=0;//序列化时,静态变量是不会存在于对象图即静态变量是不会被存入的。
    6. public Person(String name,int age){
    7. this.name = name;
    8. this.age = age;
    9. count++;
    10. }
    11. 写: Person p = new Person("jack",18);
    12. 读:while(true){
    13. Person p = (Person) in.readObject();
    14. System.out.println(p);
    15. }
    16. 结果:jack, 18, count:0, num:0

    十六、总结

    1、流的作用

        流是用来处理数据的。

        处理数据时,一定要先明确数据源与数据目的地(数据汇)。

        数据源可以是文件、键盘或者其他流。

        数据目的地可以是文件、显示器或者其他流。

    流只是在帮助数据进行传输,并对传输的数据进行处理,比如过滤处理、转换处理等。

    2.、IO流的操作规律

        1、明确源和目的。

           源:InputStream   Reader 一定是被读取的。

           目的:OutputStream  Writer 一定是被写入的。

        2、处理的数据是否是纯文本的数据?

            是:使用字符流。Reader Writer

            否:使用字节流。 InputStream OutputStream

       3、明确数据所在的设备:

          源设备:

           键盘(System.in)

           硬盘(FileXXX)FileReader FileInputStream

           内存(数组)ByteArrayInputStream CharArrayReader StringReader

           网络(Socket)

         目的设备:

           显示器(控制台System.out)

           硬盘(FileXXX)FileWriter FileOutputStream

           内存(数组)ByteArrayOutputStream CharArrayWriter StringWriter

           网络(Socket)

       4、明确是否需要额外功能:

           1) 是否需要高效?缓冲区Buffered (字符与字节各两个)。

           2) 是否需要转换?转换流  InputStreamReader OutputStreamWriter

           3) 是否操作基本数据类型? DataInputStream  DataOutputStream

           4) 是否操作对象(对象序列化)? ObjectInputStream ObjectOutputStream

           5) 需要对多个源合并吗? SequenceInputStream

           6) 需要保证数据的表现形式到目的地吗? PrintStream 或 PrintWriter

          例子:

    1. 1.需求1:复制一个文本文件。
    2. a明确源和目的。
    3. 源:InputStream Reader
    4. 目的:OutputStream Writer
    5. b.处理的数据是否是纯文本的数据?
    6. 源:Reader
    7. 目的:Writer
    8. c.明确数据所在的设备。
    9. 源:file(硬盘)
    10. 目的:file(硬盘)
    11. FileReader fr = new FileReader("a.txt");
    12. FileWriter fw = new FileWriter("b.txt");
    13. d.明确是否需要额外功能?
    14. BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
    15. BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));

        

  • 相关阅读:
    Linux【操作系统】
    【c++提高1】数据结构之哈希表
    只要一个软件,就能满足移动数据分析的所有需求!
    Java 入门练习(16 - 20)
    MySQL中的多列子查询
    光流法详细介绍
    java8 CompletableFuture: 组合式异步编程
    JDBC快速入门和获取数据库的连接方式
    视频播放 (二) 自定义 MediaPlayer
    【用户画像】Redis_Jedis测试、将人群包存放到Redis中、挖掘类标签处理过程、决策树、用SparkMLLib实现决策树
  • 原文地址:https://blog.csdn.net/bird_tp/article/details/125460927