JavaSE(十二)之IO流的字节流(一)

时间:2022-04-22
本文章向大家介绍JavaSE(十二)之IO流的字节流(一),主要内容包括一、流的概念、二、字节流中常用节点流、1.2、OutputStream、1.3、System.out和System.in、1.4、ByteArrayInputStream和ByteArrayOutputStream、1.5、FileInputStream和FileOutputStream、1.6、PipedInputStream和PipedOutputStream、1.7、ObjectInputStream和ObjectOutputStream(对象流)、三、字节流常用的处理流、3.2、DataInputStream和DataOutputStream、3.3、PrintStream、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

前面我们学习的了多线程,今天开始要学习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是把数据输出控制台

  举例:

  对输入流的操作

  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 }

  对输出流的操作

  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 }

1.4、ByteArrayInputStream和ByteArrayOutputStream

    这个节点流非常的重要:

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

      相关的方法查看API

 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 }

1.5、FileInputStream和FileOutputStream

     FileInputStream可以读取文件中的字节

       查看api:

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

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

  例子:

  从文件中读写到控制台中

 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 }

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

 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 }

   从控制台读写到文件中去

 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 }

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

 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 }

1.6、PipedInputStream和PipedOutputStream

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

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

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

            是字节流和还是字符

            是输入还是输出

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

 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 }

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

 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 }

       将序列化写到文件当中

 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 }

        我们查看文件会发现乱码,以为我们序列化之后是字节,当我们把它写到文件中的时候会通过设置的编码解析成字符,所以出现乱码。当然这个不是给我们看的,接下来我们要去做反序列化把它转回对象。          2.2) ObjectInputStream类中的方法可以完成对象的反序列化:               public final Object readObject(){..}

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

 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 }

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

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

三、字节流常用的处理流

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

3.1、BufferedInputStream和BufferedOutputStream

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

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

 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 }
 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 }

3.2、DataInputStream和DataOutputStream

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

    首先我们先来看一下DataOutputStream

    构造函数:

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

 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 }

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

      DataInputStream来查看。

 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 }

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

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

 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 }

3.3、PrintStream

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

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

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

    举例:

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

 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 }

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