Java IO input and output streams

  Refers to a group of data stream is sequential, there is a set of start and end byte.

  Initial release, only the java.io normal stream packet byte stream, i.e., a byte stream as a basic processing unit. 8 byte stream for reading and writing data, because the data does not do any conversion, it can be used to process binary data. In later versions, java.io package also joined the class dedicated to the character stream processing, this series of classes to Reader and Writer based derived.

  Further, in order to make the state of the object can be easily and permanently preserved, the java.io package also provides a mechanism for a stream of bytes based permanent preservation of the state of the object, and is accomplished by implementing ObjectInput ObjectOutput interfaces.

java.io

 

  InputStream and OutputStream classes are two abstract class, an abstract class can not be instantiated. In practice, we have to use a series of basic data stream classes are subclasses of them, at the same time achieve its parent class method and defines its unique features.

  • Input data stream

    • The input main data provided a method of operating a data stream

      • int read (): read a byte of data from the input binary stream
      • int read (byte [] b): a plurality of arrays of bytes read, to fill the entire array
      • int read (byte [] b, int off, int len): read from the input stream for len data, the start position is placed off data read from the array b as labeled, to complete their return read byte count
      • The above three methods, the data is read byte by default type. When the end of the input stream is read, it will be -1, to mark the end of the data stream. The first byte of a read () method as the read low, forming an int value 0 to 255 a return
      • void close (): Close stream
      • long skip (long l): Skip the data stream does not read the specified number of bytes, number of bytes actually skip value indicates a
      • The data stream of bytes read from beginning to end is usually carried out sequentially read in the reverse direction if desired, you need to use the push-back (Push Back) operation, support the operation of pushing back the data stream commonly used method as follows
      • boolean markSupported (): test data stream supports the push-back operation, when a data stream supports mark () and reset () method returns true, false otherwise
      • void mark (int markarea): current position mark for the data stream, and a draw buffer size parameter specifies the size of at least
      • void reset (): reposition the input stream to the stream position at the time of this last mark method was called
  • Output data stream

    • The method of operation of key data provided in the output data stream

      • void write (int i): i bytes written to the data stream, only the lowest output of the read parameter 8
      • void write (byte b []): B array [] in all b.length bytes written to the stream
      • void write (byte b [], int off, int len): B array [] is written from the data stream off the subscript start len ​​bytes. Element b [off] is the first byte of this write operation, b [off + len - 1] This is the last byte written
      • void close (): When the operation of the output data stream should be closed
      • void flush (): Flushes this output stream and forces any buffered output bytes to write

Atomic Byte Stream Class


 

  • File data stream

    • FileInputStream file and data stream includes a FileOutputStream, these two classes used for file I / O processing, the data source or data destination file should be. Can operate on files on the machine by the provided methods, but the method does not support mark () and reset ()

    • Example (1)

      • FileInputStream fis = new FileInputStream("myFile.txt");
        // 同样可以使用 FileOutputStream  向文件中输出字节
        FIleOutputStream out = new FileOutputStream("myFile.txt");
    • 示例(2)

      • FIleOutputStream out = new FileOutputStream("myFile.txt");
        out.wirte('H');
        out.wirte(69);
        out.wirte(76);
        out.wirte('L');
        out.wirte('O');
        out.close();
        FIleInputStream fis = new FileInputStream("myFile.txt");
        while(fis.available() > 0){
            System.out.print(fis.read() + " ");
        }
        fis.close();
  • 过滤器数据流(直接继承与FilterInputStream、FilterOutputStream)

    • 缓冲区数据流
      • 一个过滤器数据流在创建时与一个已经存在的数据流相连,这样在从这样的数据流中读取数据时,它提供的是对一个原始输入数据流的内容进行了特定处理的数据。缓冲区数据流有BufferedInputStream 和 BufferedOutinputStream,它们是在数据流上增加了一个缓冲区,都属于过滤器数据流。当读写数据时,数据以块为单位先进入缓冲区(块大小可以进行设置),其后的读写操作则作用于缓冲区。采用这个办法可以降低不同硬件设备之间速度的差异,提高I/O操作的效率

      • 示例(使用默认缓冲区大小)

      • FileInputStream fis = new FileInputStream("myFile.txt");
        InputStream is = new BufferedInputStream(fis);
        FileOutputStream fos = new FileOutputStream("myFile.txt");
        OutputStream is = new BufferedOutputStream(fos);
      • 示例(自定义设置缓冲区大小)

      • FileInputStream fis = new FileInputStream("myFile.txt");
        InputStream is = new BufferedInputStream(fis, 1024);
        FileOutputStream fos = new FileOutputStream("myFile.txt");
        OutputStream is = new BufferedOutputStream(fos, 1024);
      • 一般在关闭一个缓冲区输出流之前,应先使用 flush() 方法,强制输出剩余数据,以确保缓冲区内的所有数据全部写入输出流

    • 数据数据流
      • 前面提到的数据流中处理数据都是指字节或字节数组,这是进行数据传输时系统默认的数据类型。但实际上所处理的数据并非只有这两种类型,遇到这种情况时就要应用一种专门的数据流来处理。DataInputStream和DataOutputStream就是这样的两个过滤器数据流,它们允许通过数据流来读写 Java 基本类型

      • 示例

      • DataInputStream dis = new DataInputStream(is);
        DataOutputStream ous = new DataOutputStream(os);
      • 常用方法

      • // DataInputStream 常用方法
        
        byte readByte()
        long readLong()
        doublue readDouble()
        boolean readBoolean()
        String readUTF()
        int readInt()
        float readFloat()
        short readShort()
        char readChar()
        
        // DataOutputStream 常用方法
        
        void writeByte(int aByte)
        void writeLong(long aLong)
        void writeDouble(double aBouble)
        void writeBoolean(boolean aBool)
        void writeUTF(String aString)
        void writeInt(int aInt)
        void writeFloat(float aFloat)
        void writeShort(short aShort)
        void rwriteChar(char aChar)
      • 虽然这两个数据流定义了对字符串进行读写的方法,但是由于字符编码的原因,应该避免使用这些方法。Reader 和 Writer 重载了这两个方法,对字符进行操作时应当使用 Reader 和 Writer 两个系列类中的方法

    • 对象流
      • 能够输入/输出对象的流称为对象流。Java 通过 java.io 包中的 ObjectInputStream 和 ObjectOutputStream 两个类实现把对象写入文件数据流或从文件数据流中读出的功能

      • 示例

      • // 写对象数据流
        
        Date date = new Date();
        FileOutputStream fos = new FileOutputStream("date.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(date);
        oos.close();
        
        // 读对象数据流
        
        Date date = null;
        FileInputStream fis = new FileInputStream("date.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        date = (Date) ois.readObject(date);
        ois.close();
        System.out.println("Date serialized at " + date);
    • 序列化
      • 序列化的概念

        • 能够记录自己的状态以便将来得到复原的能力,称为对象的持久性(Persistence)。一个对象时可持久的,意味着它可以把这个对象存入内存或者磁盘等介质中,也就是把对象存为某种永久存储类型。对象通过数值来描述自己的状态,记录对象也就是记录下这些数值。把对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为对象的过程称为对象的反序列化。序列化的主要任务是写出对象实例变量的数值。序列化是一种用来处理对象流的机制,所谓的对象流也就是将对象的内容进行流化。序列化是为了解决在对对象流进行读写操作时所引发的问题
      • Serializable 接口中没有定义任何方法,只是作为一个标记来指示实现该接口的类可以进行序列化,只有实现 Serializable 接口的类才能被序列化。当一个类实现 Serializable 接口时,表明该类加入了对象序列化协议

      • 序列化一个对象,必须与特定的对象输出/输入流联系起来,通过对象输出流/输入流将对象状态保存下来或者将对象状态恢复。通过 java.io 包中的 ObjectInputStream 和 ObjectOutputStream 两个类可以实现。writeObject() 和 readObject() 方法可以直接将对象保存到输出流中或者从输出流中读取一个对象

      • // 序列化
        
        public class Student implements Serializable {
            int id;
            String name;
            int age;
            String department;
            public Student(int id, String name, int age, String department) {
                this.id = id;
                this.name = name;
                this.age = age;
                this.department = department;
            }
        }
        
        // 对象的存储
        
        Student stu = new Student(927103, "Li Ming", 16, "CSD");
        FileOutputStream fo = new FileOutputStream("data.ser");
        ObjectOutputStream so = new ObjectOutputStream(fo);
        so.writeObject(stu);
        so.close();
        
        // 对象的恢复
        
        Student stu;
        FileInputStream fi = new FileInputStream("data.ser");
        ObjectInputStream si = new ObjectInputStream(fi);
        stu = (Student)si.readObject();
        si.close();
        System.out.println("ID:" + stu.id + ";name:" + stu.name);
      • 对象结构表

        • 序列化只能保存对象的非静态成员变量,而不能保存任何成员方法和静态成员变量,并且保存的只是变量的值,对于变量的任何修饰符都不能保存,访问权限(public, protected, private)对于数据域的序列化没有影响
        • 有一些对象不具有可持久性,因为其数据的特性决定了它会经常变化,其状态只是瞬时的,这样的对象是无法保存起状态的,如 Thread 对象。对于这样的成员变量,必须用 transient 关键字标明,否则编译器将报错。任何用 transient 关键字标明的成员变量都不会被保存
        • 序列化可能涉及将对象存放到磁盘上或者再网络上发送数据,这时会产生安全问题。对于一些保密的数据,为了保证安全,不应保存在永久介质中,应在这些变量前加上 transient 关键字
        • 当数据变量是一个对象时,该对象的数据成员也可以被持久化。对象的数据结构或结构树,包括其子对象树在内,构成了这个对象的结构表
      • 示例

      • public class Student implements Serializable {
            public transient Thread myThread;
            private transient String customerID;
            private int total;
        }

基本字符流


 

  从 JDK1.1 开始,java.io 包中加入了专门用于字符流处理的类,它们是以 Reader 和 Writer 为基础派生的一系列类。

  一、读者(Reader)和写者(Writer)

    同其他语言使用 ASCII 字符集不同,Java 使用 Unicode 字符集来表示和字符。ASCII 字符集以一个字节(8bit)表示一个字符,可以认为一个字符就是一个字节(byte)。但是 Java 使用的 Unicode 是一种大字符集,用两个字节(16bit)来表示一个字符,这时字节与字符就不再相同。为实现与其他程序语言及不同平台的交互,Java 提供一种新的数据流处理方案称作 Reader 和 Writer。在 java.io 包中有许多不同类对其进行支持,其中最重要的是 InputStreamReader 和 OutputStreamWriter 类。这两个类是字节流和 Reader 和 Writer 的接口,用来在字节流和字符流之间作为中介

    在英语国家中,字节编码采用 ISO8859_1 协议。ISO8859_1 是 Latin-1 编码系统映射到 ASCII 标准,能够在不同平台之间正确转换字符。

// 构造映射到 ASCII 码的标准的 InputStreamReader 的方法

InputStreamReader ir = new InputStreamReader(System.in, "8859_1");

// Reader 提供的方法

void close();
void mark(int readAheadLimit);
boolean markSupported();
int read();
int read(char[] cbuf);
int read(char[] cbuf, int off, int len);
boolean ready();
void reset();
long skip(long n);

// Writer 提供的方法

void close();
void flush();
void write(char[] cbuf);
void write(char[] cbuf, int off, int len);
void write(int c);
void write(String str);
void write(String str, int off, int len);

  二、缓冲区读者和缓冲区写者

    java.io 中提供流缓冲流 BufferedReader 和 BufferedWriter。其构造方法与 BufferedInputStream 和 BufferedOutputStream 类似。另外,除了 read() 和 write() 方法外,还提供了整行字符的处理方法

    • 方法如下

      • public String readLine():BufferedReader 的方法,从输入流中读取一行字符,行结束标志为 '\n' 、'\r' 或者两者一起
      • public void newLine():BufferedWriter 的方法,向输出流中写入一个行结束标志
    • 示例

      • FileInputStream fis = new FileInputStream("data.ser");
        InputStreamReader dis = new InputStreamReader(fis);
        BufferedReader reader = new BufferedReader(dis);
        // BufferedReader reader = new BufferedReader(new FileReader("data.ser"));
        String s;
        while((s = reader.readLine()) != null) {
            System.out.println("read:" + s);
        }
        dis.close();
    • 当你写文件的时候,为了提高效率,写入的数据会先放入缓冲区,然后写入文件。因此有时候你需要主动调用 flush()方法

      • // FileWriter
        FileWriter fw = new FileWriter("D:/Test.txt");
        String s = "hello world";
        fw.write(s, 0, s.length());
        fw.flush(); //flush将缓冲区内容写入到问题件
        // OutputStreamWriter
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:/Test1.txt"));
        osw.write(s, 0, s.length());
        osw.flush();
        // PrintWriter
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new
        FileOutputStream("D:/Test2.txt")), true);
        // PrintWriter pw = new PrintWriter(new FileWriter("D:/Test2.txt"));
        
        pw.println(s); 
        
        // close AllWriter 
        
        fw.close(); 
        osw.close(); 
        pw.close();
    • 文件拷贝
      • File file = new File("D:/Test.txt");
        File dest = new File("D:/new.txt");
        try {
            BufferedReader reader = new BufferedReader(new FileReader(file));
            BufferedWriter writer = new BufferedWriter(new FileWriter(dest)); 
            String line = reader.readLine();
            while(line!=null){
                writer.write(line);
                line = reader.readLine();
            }
            writer.flush();
            reader.close();
            writer.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

         

Guess you like

Origin www.cnblogs.com/qpliang/p/10994926.html