JavaSE(十二)之IO流的字节流(一)详解编程语言

前面我们学习的了多线程,今天开始要学习IO流了,java中IO流的知识非常重要。但是其实并不难,因为他们都有固定的套路。

一、流的概念

      流是个抽象的概念,是对输入输出设备的抽象,Java程序中,对于数据的输入/输出操作都是以”流”的方式进行。设备可以是文件,网络,内存等
      流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序为参考,如果数据的流向是程序至设备,我们成为输出流,如果数据的流向是设备至程序称为输入流
      数据以二进制的形式在程序与设备之间流动传输,就想水在管道里流动一样,所以就把这种数据传输的方式称之为输入流输出流二、流的分类

      1)按照流的方向分为输入流和输出流
      2)按照处理数据的单位不同分为字节流和字符流
          字节流读取的最小单位是一个字节(1byte=8bit),而字符流一次可以读取一个字符(1char = 2byte = 16bit)
      3)按照功能的不同分为节点流和处理流
          节点流是可以”直接”从一个数据源中读写数据的流
          处理流也可以称为功能流或者包装流,它是可以对节点流进行封装的一种流,封装后可以增加节点流的功能。
          例如:FileInputStream是一个节点流,可以直接从文件读取数据,而BufferedInputStream可以包装 FileInputStream,使得其有缓冲数据的功能。
    
      4)除了以上三种分类外,还有其他的一些类型的:对象流、缓冲流、压缩流、文件流等等,其实这些都是节点流或者处理流的子分类。当然还可以分出来其他的流类型,如果有这样需要的话。

      5)不管流的分类是多么的丰富和复杂,其根源来自于四个基本的父类
          字节输入流:InputStream  
          字节输出流:OutputStream  
          字符输入流:Reader                                 这四个父类都是抽象类
          字符输出流:Writer

二、字节流中常用节点流

注:java中常用的io流都在java.io包中

1.1、InputStream

    1)方法介绍

    public abstract int read();

    从输入流中读取数据的下一个字节;如果到达流的末尾则返回 -1

    public int read(byte[] b){..}

    把读到的字节存到字节数组b中,并返回本次读到了多少个字节

    public int read(byte[] b,int off,int len){..}

    把读到的字节存到字节数组b中,同时指定开始存的位置以及最大字节数,并返回本次读到了多少个字节

    public int available(){..}

    返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数

    public long skip(long n){..}

    跳过此输入流中数据的 n 个字节

    public void close(){..}

    关闭此输入流并释放与该流关联的所有系统资源

    public boolean markSupported(){..}

    测试此输入流是否支持 mark 和 reset 方法

    public void mark(int readlimit){..}

    在此输入流中标记当前的位置

    public void reset(){..}

    将此流重新定位到最后一次对此输入流调用mark方法时的位置

1.2、OutputStream

    1)方法介绍

    public abstract void write(int b);

    将指定的字节写入此输出流

    public void write(byte[] b){..}

    将字节数组b中的所有字节写入此输出流

    public void write(byte[] b,int off,int len){..}

    将字节数组b中的字节写入此输出流,指定开始位置及最大字节数

    public void flush(){..}

    刷新此输出流并强制写出所有缓冲的输出字节

    public void close(){..}
       关闭此输出流并释放与此流有关的所有系统资源

  注意:InputStream的子类和OutputStream的子类几乎都是成对出现的,一个负责读数据的工作,一个负责写数据的工作  

1.3、System.out和System.in

     标准输入流会默认从控制台读取数据
          标准输出流会默认把数据输出到控制台

     System.out.println(System.in.getClass());
          System.out.println(System.out.getClass());
          输出结果为:
          class java.io.BufferedInputStream
          class java.io.PrintStream

    System类的部分源码:

public final class System{ 
            //标准输入流 
            public final static InputStream in = null; 
            //标准输出流。 
            public final static PrintStream out = null; 
            //标准错误输出流 
            public final static PrintStream err = null; 
 
            public static void setIn(InputStream in){..} 
            public static void setOut(PrintStream out){..} 
            public static void setErr(PrintStream err){..} 
        }

 

  在使用流的时候一定要注意它的步骤:

         首先想清楚:1.是读是写    2.是字节是字符   3.从哪里读/写(这个非常的重要)比如在这个System.out和System.in中,in从控制台读取数据,out是把数据输出控制台

  举例:

  对输入流的操作

JavaSE(十二)之IO流的字节流(一)详解编程语言

  1 import java.io.IOException; 
  2 import java.io.InputStream; 
  3 import java.util.Arrays; 
  4  
  5 public class InAndOutTest { 
  6      
  7     /* 
  8      * 1.是读还是写 
  9      * 2.是字节还是字符 
 10      * 3.从哪读/写 
 11      */ 
 12     public static void main(String[] args) { 
 13          
 14             //1.声明流 
 15         InputStream in = null; 
 16          
 17         try { 
 18             //2.创建流 
 19             in = System.in; 
 20              
 21             //3.操作流 
 22              
 23             /*int data = in.read(); 
 24             System.out.println(data); 
 25              
 26             data = in.read(); 
 27             System.out.println(data); 
 28              
 29             data = in.read(); 
 30             System.out.println(data); 
 31              
 32             data = in.read(); 
 33             System.out.println(data);*/ 
 34              
 35              
 36             //h     e    l    l    o  
 37             //104, 101, 108, 108, 111 
 38             //104, 101, 108, 108, 111, 119, 111, 114, 108, 100 
 39             /*byte[] b = new byte[10]; 
 40             int len = in.read(b); 
 41             System.out.println(len); 
 42             System.out.println(Arrays.toString(b));*/ 
 43             //输入hello 
 44             //结果:7 
 45             //    [104, 101, 108, 108, 111, 13, 10, 0, 0, 0] 
 46              
 47              
 48             /*int data = -1; 
 49             while((data=in.read())!=-1){ 
 50                 System.out.println(data); 
 51             }*/ 
 52              
 53              
 54              
 55             /*byte[] b = new byte[10]; 
 56             int len = -1; 
 57             while((len=in.read(b))!=-1){ 
 58                 System.out.println(len+":"+Arrays.toString(b)); 
 59             }*/ 
 60              
 61              
 62              
 63             /*byte[] b = new byte[10]; 
 64             int len = -1; 
 65              
 66             len = in.read(b, 4, 5); 
 67             System.out.println(len+":"+Arrays.toString(b));*/ 
 68             //输入:helloworld 
 69             //输出:5:[0, 0, 0, 0, 104, 101, 108, 108, 111, 0] 
 70              
 71              
 72             //System.out.println(in.available()); 
 73              
 74 //            long len = in.skip(10); 
 75 //            System.out.println(len); 
 76              
 77             //h     e    l    l    o   w   o    r    l  d 
 78             //104, 101, 108, 108, 111 
 79         /*    System.out.println(in.markSupported()); 
 80             int data = -1; 
 81             while((data=in.read())!=-1){ 
 82                 if(data==101){ 
 83                     in.mark(10); 
 84                 } 
 85                 else if(data==111){ 
 86                     in.reset(); 
 87                 } 
 88                 System.out.println(data); 
 89                 Thread.sleep(1000); 
 90             }*/ 
 91              
 92              
 93         } catch (Exception e) { 
 94             e.printStackTrace(); 
 95         }finally { 
 96             //4.关闭流 
 97             try { 
 98                 if(in!=null)in.close(); 
 99             } catch (IOException e) { 
100                 e.printStackTrace(); 
101             } 
102         } 
103          
104          
105          
106          
107     } 
108      
109 }

InAndOutTest

  对输出流的操作

JavaSE(十二)之IO流的字节流(一)详解编程语言

  1 import java.io.IOException; 
  2 import java.io.InputStream; 
  3 import java.io.OutputStream; 
  4 import java.text.SimpleDateFormat; 
  5 import java.util.Date; 
  6  
  7 public class InAndOutTest2 { 
  8      
  9     /* 
 10      * 1.是读还是写 
 11      * 2.是字节还是字符 
 12      * 3.从哪读/写 
 13      */ 
 14     public static void main(String[] args) { 
 15          
 16             //1.声明流 
 17         InputStream in = null; 
 18         OutputStream out = null; 
 19          
 20         try { 
 21             //2.创建流 
 22             in = System.in; 
 23             out = System.out; 
 24              
 25             //3.操作流 
 26 //            System.out.println(out.getClass()); 
 27 //            out.write(97); 
 28 //            out.flush(); 
 29              
 30             //h     e    l    l    o  
 31             //104, 101, 108, 108, 111 
 32 //            byte[] b = {104,101,108,108,111}; 
 33 //            byte[] b = "hello".getBytes(); 
 34             /* 
 35             byte[] b1 = "你好".getBytes(); 
 36             System.out.println(Arrays.toString(b1)); 
 37              
 38             byte[] b2 = "你好".getBytes("UTF-8"); 
 39             System.out.println(Arrays.toString(b2)); 
 40              
 41             byte[] b3 = "你好".getBytes("GBK"); 
 42             System.out.println(Arrays.toString(b3)); 
 43              
 44             byte[] b4 = "你好".getBytes("unicode"); 
 45             System.out.println(Arrays.toString(b4)); 
 46              
 47             out.write(b1); 
 48             out.write(10); 
 49             out.write(b2); 
 50             out.write(10); 
 51             out.write(b3); 
 52             out.write(10); 
 53             out.write(b4); 
 54             out.flush(); 
 55             */ 
 56              
 57             /* 
 58             byte[] b = "helloworld".getBytes(); 
 59             out.write(b, 3, 5); 
 60             out.flush(); 
 61             */ 
 62              
 63             /* 
 64             int data = -1; 
 65             while((data=in.read())!=-1){ 
 66                 out.write(data); 
 67                 out.flush(); 
 68             }*/ 
 69              
 70              
 71             byte[] b = new byte[10]; 
 72             int len = -1; 
 73              
 74             //[98, 121, 101] 
 75 //            System.out.println(Arrays.toString("bye".getBytes())); 
 76             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 
 77             while((len=in.read(b))!=-1){ 
 78                 if(len==5){ 
 79                     String str = new String(b,0,3); 
 80                     if("bye".equals(str)){ 
 81                         out.write("欢迎下次再来".getBytes()); 
 82                         out.flush(); 
 83                         break; 
 84                     } 
 85                 } 
 86                 else if(len==6){ 
 87                     String str = new String(b,0,4); 
 88                     if("time".equals(str)){ 
 89                         out.write(sdf.format(new Date()).getBytes()); 
 90                         out.flush(); 
 91                         continue; 
 92                     } 
 93                 } 
 94                 out.write(b,0,len); 
 95                 out.flush(); 
 96             } 
 97              
 98         } catch (Exception e) { 
 99             e.printStackTrace(); 
100         }finally { 
101             //4.关闭流 
102             try { 
103                 if(in!=null)in.close(); 
104             } catch (IOException e) { 
105                 e.printStackTrace(); 
106             } 
107             try { 
108                 if(out!=null)in.close(); 
109             } catch (IOException e) { 
110                 e.printStackTrace(); 
111             } 
112         } 
113          
114          
115          
116          
117     } 
118      
119 }

InAndOutTest2

1.4、ByteArrayInputStream和ByteArrayOutputStream

    这个节点流非常的重要:

    ByteArrayInputStream可以从数组中读取字节
           ByteArrayOutputStream可以把字节写到对象中的缓冲区里面,其实就是一个字节数组

      相关的方法查看API

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.ByteArrayInputStream; 
 2 import java.io.ByteArrayOutputStream; 
 3 import java.io.IOException; 
 4 import java.io.InputStream; 
 5 import java.io.OutputStream; 
 6 import java.util.Arrays; 
 7  
 8 public class ByteArrayInputStreamTest { 
 9     public static void main(String[] args) { 
10          
11         InputStream in = null; 
12         OutputStream out = null; 
13          
14         try { 
15             byte[] buf = "helloworld".getBytes(); 
16             in = new ByteArrayInputStream(buf); 
17             out = new ByteArrayOutputStream(); 
18              
19              
20 //            System.out.println(Integer.toBinaryString(1000)); 
21              
22             /*int data = -1; 
23             while((data=in.read())!=-1){ 
24                 out.write(data); 
25                 out.flush(); 
26             }*/ 
27              
28             byte[] b = new byte[20]; 
29             int len = in.read(b); 
30              
31             out.write(b, 0, len); 
32             out.flush(); 
33              
34             byte[] dataBuf = ((ByteArrayOutputStream)out).toByteArray(); 
35             System.out.println(Arrays.toString(dataBuf)); 
36              
37              
38         } catch (Exception e) { 
39             e.printStackTrace(); 
40         }finally { 
41             try { 
42                 if(in!=null)in.close(); 
43             } catch (IOException e) { 
44                 e.printStackTrace(); 
45             } 
46             try { 
47                 if(out!=null)out.close(); 
48             } catch (IOException e) { 
49                 e.printStackTrace(); 
50             } 
51         } 
52          
53          
54     } 
55 }

ByteArrayInputStreamTest

1.5、FileInputStream和FileOutputStream

     FileInputStream可以读取文件中的字节

       查看api:

          long   skip(long n)  从输入流中国跳过并丢弃n个字节的数据

          int   available()  返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。
          FileOutputStream可以向文件中写进去字节

  例子:

  从文件中读写到控制台中

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.FileInputStream; 
 2 import java.io.IOException; 
 3 import java.io.InputStream; 
 4 import java.io.OutputStream; 
 5  
 6 public class FileInputStreamTest { 
 7     public static void main(String[] args) { 
 8          
 9         InputStream in = null; 
10         OutputStream out = null; 
11          
12         try { 
13              
14             String filePath = "src/com/zyh/chap11/b.txt"; 
15             in = new FileInputStream(filePath); 
16             out = System.out; 
17              
18             System.out.println("in.available() = "+in.available()); 
19             byte[] b = new byte[512]; 
20             int len = -1; 
21              
22             while((len=in.read(b))!=-1){ 
23                 out.write(b, 0, len); 
24             } 
25             out.flush(); 
26              
27         } catch (Exception e) { 
28             e.printStackTrace(); 
29         }finally { 
30             try { 
31                 if(in!=null)in.close(); 
32             } catch (IOException e) { 
33                 e.printStackTrace(); 
34             } 
35             try { 
36                 if(out!=null)out.close(); 
37             } catch (IOException e) { 
38                 e.printStackTrace(); 
39             } 
40         } 
41          
42     } 
43 }

FileInputStreamTest

   自己建立一个字节数组写到文件中去

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.FileOutputStream; 
 2 import java.io.OutputStream; 
 3  
 4 public class FileOutputStreamTest { 
 5  
 6     public static void main(String[] args) { 
 7         OutputStream out = null; 
 8          
 9         try { 
10             String file = "src/com/zyh/ioday02/b.txt"; 
11             out = new FileOutputStream(file,true); 
12              
13             byte[] b = "hello".getBytes(); 
14 //            out.write(b); 
15             out.write(b, 0, b.length); 
16             out.flush(); 
17              
18         } catch (Exception e) { 
19             e.printStackTrace(); 
20         }finally{ 
21             try { 
22                 if (out != null) 
23                     out.close(); 
24             } catch (Exception e) { 
25                 e.printStackTrace(); 
26             } 
27         } 
28     } 
29  
30 }

FileOutputStreamTest

   从控制台读写到文件中去

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.FileOutputStream; 
 2 import java.io.InputStream; 
 3 import java.io.OutputStream; 
 4  
 5 public class FileOutputStreamTest2 { 
 6  
 7     public static void main(String[] args) { 
 8         InputStream in = null; 
 9         OutputStream out = null; 
10          
11         try { 
12             in =System.in; 
13             String file = "src/com/zyh/ioday02/b.txt"; 
14             out = new FileOutputStream(file); 
15              
16             byte[] buf = new byte[1024]; 
17             int len = -1; 
18             while((len=in.read(buf))!=-1){ 
19                 out.write(buf, 0, len); 
20             } 
21             out.flush(); 
22              
23         } catch (Exception e) { 
24             e.printStackTrace(); 
25         }finally{ 
26             try { 
27                 if (in != null) 
28                     in.close(); 
29             } catch (Exception e) { 
30                 e.printStackTrace(); 
31             } 
32             try { 
33                 if (out != null) 
34                     out.close(); 
35             } catch (Exception e) { 
36                 e.printStackTrace(); 
37             } 
38         } 
39     } 
40  
41 }

FileOutputStreamTest2

  读取一个文件内容写到另一个文件中

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.FileInputStream; 
 2 import java.io.FileOutputStream; 
 3 import java.io.IOException; 
 4 import java.io.InputStream; 
 5 import java.io.OutputStream; 
 6  
 7 public class FileInputStreamAndFileOutputStream { 
 8  
 9     public static void main(String[] args) { 
10         InputStream in = null; 
11         OutputStream out = null; 
12          
13         try { 
14             String filePath1 = "src/com/zyh/ioday02/b.txt"; 
15             String filePath2 = "src/com/zyh/ioday02/c.txt"; 
16              
17             in = new FileInputStream(filePath1); 
18             out = new FileOutputStream(filePath2); 
19  
20 //            in.skip(in.available()/2); 
21             byte[] buf = new byte[1024]; 
22             int len = -1; 
23             while((len=in.read(buf))!=-1){ 
24                 out.write(buf,0,len); 
25             } 
26             out.flush(); 
27              
28         } catch (Exception e) { 
29             e.printStackTrace(); 
30         }finally{ 
31             if(in!=null) 
32                 try { 
33                     in.close(); 
34                 } catch (IOException e) { 
35                     e.printStackTrace(); 
36                 } 
37                 if(out!=null) 
38                     try { 
39                         out.close(); 
40                     } catch (IOException e) { 
41                         e.printStackTrace(); 
42                     } 
43         } 
44          
45     } 
46  
47 }

FileInputStreamAndFileOutputStream

1.6、PipedInputStream和PipedOutputStream

     PipedInputStream管道字节输入流
          PipedOutputStream管道字节输出流

    注:使用时需要把俩个管道进行对接

     JavaSE(十二)之IO流的字节流(一)详解编程语言

      在写关于IO流的用法时,一定要知道:

            是字节流和还是字符

            是输入还是输出

            是读还是写(在下面这个例子中,首先PipedOutputStream从一个for循环中得到字节,然后PipedInputStream读到字节,通过System.out输出)

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.IOException; 
 2 import java.io.PipedInputStream; 
 3 import java.io.PipedOutputStream; 
 4  
 5 public class PipedInputAndOutputStreamTest { 
 6     public static void main(String[] args) { 
 7          
 8         try { 
 9             PipedInputStream in = new PipedInputStream(); 
10             PipedOutputStream out = new PipedOutputStream(in); 
11              
12             Thread t1 = new PipedReadThread(in); 
13             Thread t2 = new PipedWriteThread(out); 
14              
15             t1.start(); 
16             t2.start(); 
17              
18         } catch (IOException e) { 
19             e.printStackTrace(); 
20         } 
21          
22     } 
23 } 
24  
25 //负责读取数据的线程 
26 class PipedReadThread extends Thread{ 
27     private PipedInputStream in; 
28      
29     public PipedReadThread(PipedInputStream in) { 
30         this.in = in; 
31     } 
32  
33     @Override 
34     public void run() { 
35         try { 
36             int data = -1; 
37             while((data=in.read())!=-1){ 
38                 System.out.write(data); 
39                 System.out.flush(); 
40             } 
41             System.out.println("data = "+data); 
42         } catch (IOException e) { 
43             e.printStackTrace(); 
44         }finally { 
45             try { 
46                 if(in!=null)in.close(); 
47             } catch (IOException e) { 
48                 e.printStackTrace(); 
49             } 
50         } 
51     } 
52 } 
53  
54 //负责写入数据的线程 
55 class PipedWriteThread extends Thread{ 
56     private PipedOutputStream out; 
57      
58     public PipedWriteThread(PipedOutputStream out) { 
59         this.out = out; 
60     } 
61  
62     @Override 
63     public void run() { 
64         try { 
65             for(int i=97;i<=111;i++){ 
66                 out.write(i); 
67                 out.flush(); 
68                 Thread.sleep(1000); 
69             } 
70         } catch (Exception e) { 
71             e.printStackTrace(); 
72         }finally { 
73             try { 
74                 if(out!=null)out.close(); 
75             } catch (IOException e) { 
76                 e.printStackTrace(); 
77             } 
78         } 
79     } 
80 }

PipedInputAndOutputStreamTest

1.7、ObjectInputStream和ObjectOutputStream(对象流)

  1)序列化和反序列化

    Java中的序列化是指把Java对象转换为字节序列的过程
              对象—序列化—>01010101

    Java中的反序列化是指把字节序列恢复为Java对象的过程
                01010101—反序列化—>对象

  2)实现序列化和反序列化

    使用对象流即可实现对象的序列化和反序列化

      2.1)ObjectOutputStream类中的方法可以完成对象的序列化:(注:这俩个对象流都属于字节流)
                   public final void writeObject(Object obj){..}

        构造方法:

protected ObjectOutputStream()
          为完全重新实现 ObjectOutputStream 的子类提供一种方法,让它不必分配仅由 ObjectOutputStream 的实现使用的私有数据。
  ObjectOutputStream(OutputStream out)
          创建写入指定 OutputStream 的 ObjectOutputStream。

         实例:

       首先编写了一个工具类:User

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.Serializable; 
 2  
 3 public class User implements Serializable{ 
 4     private static final long serialVersionUID = 1L; 
 5      
 6     private long id; 
 7     private String name; 
 8     private int age; 
 9     private transient double salary; 
10      
11     public User() {} 
12     public User(long id, String name, int age) { 
13         this.id = id; 
14         this.name = name; 
15         this.age = age; 
16     } 
17  
18     public long getId() { 
19         return id; 
20     } 
21     public void setId(long id) { 
22         this.id = id; 
23     } 
24     public String getName() { 
25         return name; 
26     } 
27     public void setName(String name) { 
28         this.name = name; 
29     } 
30     public int getAge() { 
31         return age; 
32     } 
33     public void setAge(int age) { 
34         this.age = age; 
35     } 
36     public double getSalary() { 
37         return salary; 
38     } 
39     public void setSalary(double salary) { 
40         this.salary = salary; 
41     } 
42     @Override 
43     public String toString() { 
44         return "User [id=" + id + ", name=" + name + ", age=" + age + ", salary=" + salary + "]"; 
45     } 
46 }

User

       将序列化写到文件当中

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.FileOutputStream; 
 2 import java.io.IOException; 
 3 import java.io.ObjectOutputStream; 
 4  
 5 public class ObjectOutputStreamTest { 
 6     public static void main(String[] args) { 
 7          
 8         ObjectOutputStream out = null; 
 9 //        ByteArrayOutputStream bos = null; 
10         FileOutputStream fos = null; 
11         try { 
12             String filePath = "src/com/zyh/chap11/obj.txt"; 
13             fos = new FileOutputStream(filePath); 
14             out = new ObjectOutputStream(fos); 
15              
16             User u = new User(1L,"tom",20); 
17             u.setSalary(2000); 
18             //序列化 
19             out.writeObject(u); 
20             out.flush(); 
21              
22 //            byte[] array = bos.toByteArray(); 
23 //            System.out.println(Arrays.toString(array)); 
24              
25         } catch (Exception e) { 
26             e.printStackTrace(); 
27         }finally { 
28             try { 
29                 if(fos!=null)fos.close(); 
30             } catch (IOException e) { 
31                 e.printStackTrace(); 
32             } 
33             try { 
34                 if(out!=null)out.close(); 
35             } catch (IOException e) { 
36                 e.printStackTrace(); 
37             } 
38         } 
39          
40     } 
41 }

ObjectOutputStreamTest

        我们查看文件会发现乱码,以为我们序列化之后是字节,当我们把它写到文件中的时候会通过设置的编码解析成字符,所以出现乱码。当然这个不是给我们看的,接下来我们要去做反序列化把它转回对象。

         2.2) ObjectInputStream类中的方法可以完成对象的反序列化:
              public final Object readObject(){..}

      从刚才我们把序列化写到的那个文件中读,进行反序列化

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.FileInputStream; 
 2 import java.io.IOException; 
 3 import java.io.ObjectInputStream; 
 4  
 5 public class ObjectInputStreamTest { 
 6     public static void main(String[] args) { 
 7          
 8         ObjectInputStream in = null; 
 9         FileInputStream fis = null; 
10          
11         try { 
12             String filePath = "src/com/zyh/chap11/obj.txt"; 
13             fis = new FileInputStream(filePath); 
14             in = new ObjectInputStream(fis); 
15              
16             //反序列化 
17             User obj = (User)in.readObject(); 
18             System.out.println(obj); 
19              
20         } catch (Exception e) { 
21             e.printStackTrace(); 
22         }finally { 
23             try { 
24                 if(fis!=null)fis.close(); 
25             } catch (IOException e) { 
26                 e.printStackTrace(); 
27             } 
28             try { 
29                 if(in!=null)in.close(); 
30             } catch (IOException e) { 
31                 e.printStackTrace(); 
32             } 
33         } 
34          
35     } 
36 }

ObjectInputStreamTest      

 注意:在我们进行了序列化之后,如果给User类新增一个Salary的属性,然后进行反序列化的时候,会发现报错了(在没有添加serialVersionUID的时候)。会出现两个序列号(没有写序列号系统会有一个默认的)。

             当我们设置了serialVersionUID的时候,并且给Salary进行set属性,会发现输出了User对象。

三、字节流常用的处理流

  也可以称为功能流或者包装流,因为它是对节点流进行包装的一种流,包装后可以增加节点流的功能。但是处理流本身并不能直接读写数据

3.1、BufferedInputStream和BufferedOutputStream

      作用:可以给字节流中的节点流提供代码缓冲区的输入/输出流

    我们使用使用BufferedInputStream来读取的时候,明显比FileInputStream本身来读取的时候快很多。

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.BufferedInputStream; 
 2 import java.io.FileInputStream; 
 3 import java.io.IOException; 
 4  
 5 public class BufferedInputStreamTest { 
 6      
 7     @SuppressWarnings("unused") 
 8     public static void main(String[] args) { 
 9          
10         BufferedInputStream in = null; 
11         FileInputStream fis = null; 
12          
13         try { 
14             String filePath = "src/com/zyh/chap11/note.txt"; 
15             fis = new FileInputStream(filePath); 
16              
17             in = new BufferedInputStream(fis); 
18              
19             byte[] b = new byte[256]; 
20             int len = -1; 
21             long start = System.currentTimeMillis(); 
22             while((len=in.read(b))!=-1){ 
23                  
24             } 
25             long end = System.currentTimeMillis(); 
26             System.out.println(end-start+"毫秒"); 
27         } catch (Exception e) { 
28             e.printStackTrace(); 
29         }finally { 
30             try { 
31                 if(fis!=null)fis.close(); 
32             } catch (IOException e) { 
33                 e.printStackTrace(); 
34             } 
35             try { 
36                 if(in!=null)in.close(); 
37             } catch (IOException e) { 
38                 e.printStackTrace(); 
39             } 
40         } 
41          
42          
43     } 
44      
45 }

BufferedInputStreamTest

  
JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.BufferedOutputStream; 
 2 import java.io.FileOutputStream; 
 3 import java.io.IOException; 
 4  
 5 public class BufferedOutputStreamTest { 
 6     public static void main(String[] args) { 
 7          
 8         BufferedOutputStream out = null; 
 9         FileOutputStream fos = null; 
10          
11         try { 
12             String filePath = "src/com/zyh/chap11/d.txt"; 
13             fos = new FileOutputStream(filePath); 
14             out = new BufferedOutputStream(fos); 
15              
16             byte[] b = "test".getBytes(); 
17              
18             out.write(b); 
19             out.flush(); 
20              
21         } catch (Exception e) { 
22             e.printStackTrace(); 
23         }finally { 
24             try { 
25                 if(fos!=null)fos.close(); 
26             } catch (IOException e) { 
27                 e.printStackTrace(); 
28             } 
29             try { 
30                 if(out!=null)out.close(); 
31             } catch (IOException e) { 
32                 e.printStackTrace(); 
33             } 
34         } 
35          
36     } 
37 }

BufferedOutputStreamTes

3.2、DataInputStream和DataOutputStream

      可以给字节流中的节点流提供输入/输出java中不同类型的数据

    首先我们先来看一下DataOutputStream

    构造函数:

         DataOutputStream(OutputStream out)
               创建一个新的数据输出流,将数据写入指定基础输出流。  

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.DataOutputStream; 
 2 import java.io.FileOutputStream; 
 3 import java.io.IOException; 
 4  
 5 public class DataOutputStreamTest { 
 6     public static void main(String[] args) { 
 7          
 8         DataOutputStream out = null; 
 9         FileOutputStream fos = null; 
10          
11         try { 
12             String filePath = "src/com/zyh/chap11/d.txt"; 
13             fos = new FileOutputStream(filePath); 
14             out = new DataOutputStream(fos); 
15              
16             out.writeInt(1); 
17             out.writeLong(1000L); 
18             out.writeBoolean(false); 
19             out.writeDouble(10.5); 
20             out.writeFloat(10.5f); 
21             out.writeUTF("你好"); 
22              
23             out.flush(); 
24              
25              
26         } catch (Exception e) { 
27             e.printStackTrace(); 
28         }finally { 
29             try { 
30                 if(fos!=null)fos.close(); 
31             } catch (IOException e) { 
32                 e.printStackTrace(); 
33             } 
34             try { 
35                 if(out!=null)out.close(); 
36             } catch (IOException e) { 
37                 e.printStackTrace(); 
38             } 
39         } 
40          
41          
42     } 
43 }

DataOutputStreamTest

     查看文件我们发现乱码了,这是因为我们本来就是就只字节写到文件中去的,所以经过文件的编码解析之后就会乱码。只有其中的“你好”不会,因为我们用UTF-8编写,而文件也是通过UTF-8解析的。通过

      DataInputStream来查看。

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.DataInputStream; 
 2 import java.io.FileInputStream; 
 3 import java.io.IOException; 
 4  
 5 public class DataInputStreamTest { 
 6     public static void main(String[] args) { 
 7          
 8         DataInputStream in = null; 
 9         FileInputStream fis = null; 
10          
11         try { 
12             String filePath = "src/com/zyh/chap11/d.txt"; 
13             fis = new FileInputStream(filePath); 
14             in = new DataInputStream(fis); 
15              
16             System.out.println(in.readInt()); 
17             System.out.println(in.readLong()); 
18             System.out.println(in.readBoolean()); 
19             System.out.println(in.readDouble()); 
20             System.out.println(in.readFloat()); 
21             System.out.println(in.readUTF()); 
22              
23 //            System.out.println(in.read()); 
24              
25         } catch (Exception e) { 
26             e.printStackTrace(); 
27         }finally { 
28             try { 
29                 if(fis!=null)fis.close(); 
30             } catch (IOException e) { 
31                 e.printStackTrace(); 
32             } 
33             try { 
34                 if(in!=null)in.close(); 
35             } catch (IOException e) { 
36                 e.printStackTrace(); 
37             } 
38         } 
39          
40          
41     } 
42 }

DataInputStreamTest

      注意:我们要什么写的就要对应着怎么读。所以在开发中我们一般把同一个文件的东西写进去,读出来的时候就很方便了。    

      同时我们包装流可以包装任何的节点流,比如说ByteArrayOutputStream

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.ByteArrayOutputStream; 
 2 import java.io.DataOutputStream; 
 3 import java.io.IOException; 
 4 import java.util.Arrays; 
 5  
 6 public class DataOutputStreamTest2 { 
 7     public static void main(String[] args) { 
 8          
 9         DataOutputStream out = null; 
10         ByteArrayOutputStream bos = null; 
11          
12         try { 
13             bos = new ByteArrayOutputStream(); 
14             out = new DataOutputStream(bos); 
15              
16 //            out.writeLong(1000L); 
17 //            out.writeInt(1000); 
18 //            out.writeBoolean(false); 
19 //            out.writeChar('中'); 
20             out.writeFloat(10.5f); 
21             out.flush(); 
22              
23             byte[] b = bos.toByteArray(); 
24             System.out.println(Arrays.toString(b)); 
25              
26         } catch (Exception e) { 
27             e.printStackTrace(); 
28         }finally { 
29             try { 
30                 if(bos!=null)bos.close(); 
31             } catch (IOException e) { 
32                 e.printStackTrace(); 
33             } 
34             try { 
35                 if(out!=null)out.close(); 
36             } catch (IOException e) { 
37                 e.printStackTrace(); 
38             } 
39         } 
40          
41          
42     } 
43 }

DataOutputStreamTest2

3.3、PrintStream

    PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式

    常用的System.out中的out变量就是PrintStream类型的

    它是在OutputStream下面的,在InputStream中没有和它对应的流,所以在IO中大多数流都是成对出现的。也有极少数单个的。

    举例:

       我们使用System.out.println()都是往控制台输出的,我们知道System.out中out是一个PrintStream类型的。所以重写里面的println()方法来把它写到文件中.

JavaSE(十二)之IO流的字节流(一)详解编程语言

 1 import java.io.FileOutputStream; 
 2 import java.io.PrintStream; 
 3 import java.text.SimpleDateFormat; 
 4 import java.util.Date; 
 5  
 6 public class PrintStreamTest { 
 7     static{ 
 8         try { 
 9             String filePath = "src/com/zyh/chap11/c.txt"; 
10             PrintStream out = new PrintStream(new FileOutputStream(filePath,true)){ 
11                 private SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 
12                 @Override 
13                 public void println(String x) { 
14                     super.println(sf.format(new Date())+" mylog: "+x); 
15                 } 
16             }; 
17             System.setOut(out); 
18         } catch (Exception e) { 
19             e.printStackTrace(); 
20         } 
21     } 
22     public static void main(String[] args) { 
23         System.out.println("hello world"); 
24         System.out.println("hello world"); 
25         System.out.println("hello world"); 
26         System.out.println("hello world"); 
27         System.out.println("hello world"); 
28         System.out.println("hello world"); 
29         System.out.println("hello world"); 
30     } 
31 }

PrintStreamTest

 

觉得不错的点个“推荐”哦!

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/12413.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论