3_javaSE_day05

day05

对象流:

ObjectOutputStream 对象输出流
ObjectInputStream 对象输入流

  对象流是一组高级流,作用是通过这组流可以方便的读写java中的任何对象.
  
  
  1. 对象输出流:ObjectOutputStream 用于写出对象,由于底层读写都是字节读写,所以无论什么样的数据都要转换为字节才能写出.对象输出流可以自行将给定的对象转换为一组字节然后写出.省去了我们将对象按照结构转化为字节的麻烦.

    ObjectOutputStream提供了写对象的方法:
         void writeObject(Object obj)
         该方法会将给定的对象转换为一组字节然后通过其处理的流写出
        
         这里涉及到两个操作:
         1) 对象序列化:将一个对象按照结构转换为一组字节的过程
         2) 对象持久化:将该对象写入文件(硬盘中)的过程.


  2. 对象输入流:ObjectInputStream 用于进行对象反序列化
public class am03_ObjectOutputStream_writeObject {
    public static void main(String[] args) throws IOException {
        /*
         * 将一个Person实例写入文件保存
         */
        am02_Person p = new am02_Person();
        p.setName("苍老师");
        p.setAge(18);
        p.setGender("女");
        String[] otherInfo = {"是一名演员","爱好是写毛笔字","促进中日文化交流","广大男性同胞的启蒙老师"};
        p.setOtherInfo(otherInfo);
        System.out.println(p);
        
        /*
         * 文件输出流作用:将给定的字节写入到指定文件
         */
        FileOutputStream fos
            = new FileOutputStream("person.obj");
        /*
         * 对象输出流作用:将给定的java对象转换为一组
         *              字节后写出
         */
        ObjectOutputStream oos
            = new ObjectOutputStream(fos);
        /*
         * ObjectOutputStream提供了写对象的
         * 方法:
         * void writeObject(Object obj)
         * 该方法会将给定的对象转换为一组字节然后
         * 通过其处理的流写出
         * 
         * 
         * 这里的操作是先通过OOS将p对象转换为
         * 了一组字节,然后再将该组字节通过FOS
         * 写入到了文件person.obj中
         * 这里涉及到两个操作:
         * 1:对象序列化.将一个对象按照结构转换
         *   为一组字节的过程
         * 2:对象持久化.将该对象写入文件(硬盘中)
         *   的过程.
         * 
         */
        oos.writeObject(p);
        System.out.println("写出完毕!");
        
        
        oos.close();
    }
}
public class am04_ObjectInputStream_readObject {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        FileInputStream fis
            = new FileInputStream("person.obj");
        
        ObjectInputStream ois
            = new ObjectInputStream(fis);
        /*
         * ObjectInputStream提供方法:
         * Object readObject()
         * 该方法可以读取字节并还原为指定的对象
         * 需要确保OIS读取的字节是通过对象输出流(OOS)
         * 将一个对象写出的字节.否则会抛出异常.
         */
        am02_Person p = (am02_Person)ois.readObject();
        
        System.out.println(p);
        
        ois.close();
        
    }
}

转换流:

OutputStreamWriter,InputStreamReader

    java根据读写数据的单位划分了:字节流,字符流
    InputStream,OutputStream是所有字节输入流与
    字节输出流的父类,常用实现类:FileInputStream,
    BufferedInputStream等.

    Reader,Writer是所有字符输入流与字符输出流的父类

    字节流的读写单位是字节,而字符流的读写单位是字符.
    所以字符流有局限性,只适合读写字符数据.
    但实际字符流底层本质还是读写字节,只是字符与字节
    的转换工作不用我们来做了.
public class pm01_OutputStreamWriter_write {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos
            = new FileOutputStream("osw.txt");
        /*
         * 构造方法若只传入流,那么通过当前转换流
         * 写出的字符会按照系统默认的字符集转化为
         * 对应的字节,不推荐.
         * 可以使用重载的构造方法,在第二个参数中
         * 明确使用的字符集.
         */
        OutputStreamWriter osw
            = new OutputStreamWriter(fos,"GBK");        
        String str = "夜空中最亮的星,能否听清.";
        osw.write(str);
        osw.write("那仰望的人,心底的孤独和叹息.");       
        System.out.println("写出完毕!");
        osw.close();
    }
}
public class pm02_InputStreamReader_read {
    public static void main(String[] args) throws IOException {
        FileInputStream fis 
            = new FileInputStream("osw.txt");
        
        InputStreamReader isr
            = new InputStreamReader(fis,"GBK");     
        
//      char[] data = new char[100];
//      int len = isr.read(data);       
//      String str = new String(data,0,len);        
//      System.out.println(str);
        
        StringBuilder builder = new StringBuilder();
        String str = "";
        int d = -1;
        while((d = isr.read())!=-1){
            builder.append((char)d);
        }
        str = builder.toString();
        System.out.println(str);
        isr.close();
    }
}

缓冲字符流:

PrintWriter

    缓冲字符流由于内部有缓冲区,读写字符的效率高.
    并且字符流的特点是可以按行读写字符串.
    BufferedWriter,BufferedReader
    
    PrintWriter也是缓冲字符输出流,它内部总是连接
    BufferedWriter,除此之外PW还提供了自动行刷新
    功能.所以更常用.
    
   

PrintWriter提供了直接对文件进行写操作
的构造方法:
PrintWriter(File file)
PrintWriter(String fileName)
若希望按照指定的字符集向文件写出字符串,
可以使用对应重载的构造方法:
PrintWriter(File file,String csn)
PrintWriter(String fileName,String csn)
第二个参数可以指定字符集的名字(charSetName)

    public class pm03_PrintWriter_println {
    public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
        /*
         * PrintWriter提供了直接对文件进行写操作
         * 的构造方法:
         * PrintWriter(File file)
         * PrintWriter(String fileName)
         * 若希望按照指定的字符集向文件写出字符串,
         * 可以使用对应重载的构造方法:
         * PrintWriter(File file,String csn)
         * PrintWriter(String fileName,String csn)
         * 第二个参数可以指定字符集的名字(charSetName)
         */
        PrintWriter pw 
            = new PrintWriter("pw.txt","GBK");
        
        pw.println("董小姐,你从没忘记你的微笑.");
        pw.println("就算你和我一样,渴望着衰老.");
        
        System.out.println("写出完毕!");
        pw.close();
    }
}

PrintWriter提供了常规的构造方法,允许传入
一个字节流或者字符流完成流连接的创建形式

public class pm04_PrintWriter_println2 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos
            = new FileOutputStream("pw2.txt");
        /*
         * 若希望指定字符集,需要自行连接转换流
         * 因为转换流可以将字符按照指定的字符集
         * 转换为字节
         */
        OutputStreamWriter osw
            = new OutputStreamWriter(fos,"GBK");
        
        PrintWriter pw
            = new PrintWriter(osw);
        /*
         * PW的构造方法允许直接传入字节流,但实际
         * 内部还是会根据流连接最终变为PW的.只是
         * 这样做不能指定字符集
         */
//      PrintWriter pw
//          = new PrintWriter(fos);
        pw.println("我在二环路的里边,想着你.");
        pw.println("你在远方的山上,春风十里.");
        
        pw.close();
    }
    
}

缓冲字符输入流:

BufferedReader

/**
 * java.io.BufferedReader
 * 缓冲字符输入流.特点:可以按行读取字符串
 * 由于有缓冲,读取字符时的效率好.
 */
public class pm06_BufferedReader_readLine {
    public static void main(String[] args) throws IOException {
        /*
          ./JSD1708_SE\src\day05
         */
        FileInputStream fis = new FileInputStream("./JSD1708_SE"+ File.separator+"src"+File.separator+"day05"+File.separator+"pm06_BufferedReader_readLine.java");

        InputStreamReader isr = new InputStreamReader(fis);

        BufferedReader br = new BufferedReader(isr);

        String line = null;
        while ((line = br.readLine())!=null){
            System.out.println(line);
        }

        br.close();
    }
}

练习:

/**
 * 简易记事本
 * 使用PW将用户输入的每行字符串写入用户指定的文件中
 * 构造方法使用流连接形式,不使用直接对文件操作的.
 */
public class pm05_Note {
    public static void main(String[] args) throws FileNotFoundException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个文件名:");
        String fileName = scanner.nextLine();

        FileOutputStream fos = new FileOutputStream(fileName);

        OutputStreamWriter osw = new OutputStreamWriter(fos);

        /*
        当PrintWriter的构造方法第一个参数为流(字节流,字符流均可)时,
        那么支持一个重载的构造方法可以传入一个boolean值,该值若为true
        ,则当前PrintWriter具有自动刷新功能即:每当调用Println方法写出
        一行字符串后会
        自动调用flush方法将其真实写出.
        需要注意,调用print方法是不会flush的
         */
        PrintWriter pw = new PrintWriter(osw,true);

        System.out.println("请开始你的表演");
        String line = null;
        while (true) {
            line = scanner.nextLine();
            if (line.equals("exit")) {
                break;
            }
            pw.println(line);
        }
        System.out.println("再见!");
        pw.close();
    }
}

你可能感兴趣的:(3_javaSE_day05)