zoukankan      html  css  js  c++  java
  • java oop第12章_IO、序列化和反序列化

    引言:数据通常通过文件系统保存在外存中,有时需要将他们读取到程序中进行一些操作,Java针对文件系统的操作提供了一套规范,即IO,针对计算机内存而言,输入的称为输入流,输出的称为输出流。

    一、      IO的分类:

    1.     从传递方向划分:输入流(InputXxx)、输出流(OutPutXxx)。
    2.     从数据格式划分:字节流(XxxStream)、字符流(XxxReader、XxxWriter)。
    3.     从数据中转的节点划分:节点流、过滤流

        图源:http://test.processon.com/view/555f1789e4b07c1520d3c24d#map

     

    二、      字节流

    是以二进制进行数据传递的IO流,它可以操作任何类型的文件,输入的字节流有一个顶层抽象类InputStream,实现类常用的有FileInputStream、ObjectInputStream。输出的字节流有一个顶层抽象类OutPutStream,实现类常用的有FileOutPutStream、ObjectOutputStream。

    案例1:通过字节流完成文件的复制,文件可以是任何类型。

            InputStream inputStream = null;
        OutputStream outputStream = null;
    
        /**
         * 案例1:通过字节流完成文件的复制,文件可以是任何类型。
         * 
         * @throws IOException
         * @throws Exception
         */
        @Test
        public void testCopyWithStream() throws IOException {
            // 创建一个输入的字节流,通过输入字节流读取文件
            inputStream = new FileInputStream("G:/Javatest/桌面壁纸.jpg");
            // 创建一个输出的字节流:将文件写出到目标位置
            outputStream = new FileOutputStream("G:/image.jpg");
    
            /**
             * 通过输入字节流,一边读取数据,再通过输出字节流一边写数据 read(byte []
             * b):表示可以读取输入字节流中的数据,并返回读取到的字节数,若返回-1则表示读取完成。
             * 为了提高读取效率,可以传入一个byte数组作为缓冲区,否则一次只能读取一个字节,效率太低
             */
            // 创建一个缓冲区
            byte[] buffer = new byte[2048];
            
            try {
                while (inputStream.read(buffer) != -1) {
                    outputStream.write(buffer);
                    System.out.println(buffer);
                }
                System.out.println("复制成功");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
    
            }
        }    

    三、      字符流

    是以字符串进行数据传递,所以只能针对文本进行操作,输入的字符流有一个顶层抽象类Reader,常用的实现类有FileReader、BufferedReader。输出的字符流有一个顶层类Writer,常用的实现类有FileWriter、BufferedWriter。

    案例2:通过字符流完成文件复制,只能是文本操作。

            InputStream inputStream = null;
        OutputStream outputStream = null;   
    
        /**
         * 案例2:通过字符流完成文件复制,只能是文本操作。
         */
        @Test
        public void testCopyWithChar() {
            Reader reader = null;
            BufferedReader bufferedReader = null;
            
            Writer writer = null;
            BufferedWriter bufferedWriter = null; 
            
            
            try {
                /**
                 * 在Java中不管是文件名、路径、路径加文件名,通通都是用File类型表示
                 */
                
                /*
                 * //判断以上的路径是否不存在就把他创建出来
                 * File file = File("G:/Javatest");
                if (!file.exists()) {
                    file.mkdirs();
                }*/
                
                File file =  new File("G:/Javatest/java代码.txt");
                reader = new FileReader(file);
                bufferedReader = new BufferedReader(reader);
                writer = new FileWriter("G:/java.txt");
                bufferedWriter = new BufferedWriter(writer);
                /**
                 * readLine():返回值是String,即读取到一行字符串
                 * 若读取完成则返回null
                 */
                String str;
                while((str = bufferedReader.readLine()) != null) {
                    bufferedWriter.write(str + "
    ");
                    System.out.println(str);
                }
                System.out.println("复制完成");
                
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bufferedWriter != null) {
                        bufferedWriter.close();
                    }
                    if (writer != null) {
                        writer.close();
                    }
                    if (bufferedReader != null) {
                        bufferedReader.close();
                    }
                    if (reader != null) {
                        reader.close();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        } 

    四、      序列化和反序列化:

    一个类若实现了Serializable接口,表示该类可以被序列化和反序列化。

    序列化:将该类的“对象”保存到外存的过程,若属性使用transient(瞬时、临时的)关键字修饰,表示该属性不需要序列化(持久化)。

    反序列化:将保存了某个类的数据读取出来创建对象的过程。

    package com.oop.ch12;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.OutputStream;
    
    import org.junit.Test;
    
    import com.oop.entity.Grade;
    
    
    /**
     * 练习序列化和反序列化的两个过程
     * @author zhangzimu
     *
     *Java中有4中创建对象的方式
     *
     */
    public class SerializableTest {
        Grade grade = null;
        OutputStream outputStream = null;
        ObjectOutputStream objectOutputStream  = null;
        /**
         * 序列化:将该类的“对象”保存到外存的过程,若属性使用transient(瞬时、临时的)关键字修饰,表示该属性不需要序列化(持久化)。
         * 前提是类必须实现Serializable接口
         * @throws IOException 
         */
        
        @Test
        public void test1(){
            
            try {
                grade = new Grade();
                grade.setGradeId(6);
                grade.setGradeName("六年级");
                
                outputStream = new FileOutputStream("G:/Javatest/grade.txt");
                objectOutputStream = new ObjectOutputStream(outputStream);
                objectOutputStream.writeObject(grade);
                System.out.println("序列化完成");
                
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (objectOutputStream != null) {
                        objectOutputStream.close();
                    }
                    if (outputStream != null) {
                        outputStream.close();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
        
        /**
         * 反序列化:将保存了某个类的数据读取出来创建对象的过程。
         */
        @Test
        public void test2() {
            InputStream inputStream = null;
            ObjectInputStream objectInputStream = null;
            try {
                inputStream = new FileInputStream("G:/Javatest/grade.txt");
                objectInputStream = new ObjectInputStream(inputStream);
                Grade grade =  (Grade) objectInputStream.readObject();
                System.out.println("反序列化完成:" + grade);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (objectInputStream != null) {
                        objectInputStream.close();
                    }
                    if (inputStream != null) {
                        inputStream.close();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
    }
  • 相关阅读:
    Swift3 重写一个带占位符的textView
    Swift3 使用系统UIAlertView方法做吐司效果
    Swift3 页面顶部实现拉伸效果代码
    Swift3 倒计时按钮扩展
    iOS 获取当前对象所在的VC
    SpringBoot在IDEA下使用JPA
    hibernate 异常a different object with the same identifier value was already associated with the session
    SpringCloud IDEA 教学 番外篇 后台运行Eureka服务注册中心
    SpringCloud IDEA 教学 (五) 断路器控制台(HystrixDashboard)
    SpringCloud IDEA 教学 (四) 断路器(Hystrix)
  • 原文地址:https://www.cnblogs.com/zhangzimuzjq/p/11793902.html
Copyright © 2011-2022 走看看