美文网首页
文件传输基础-Java IO流

文件传输基础-Java IO流

作者: Hey_Shaw | 来源:发表于2018-04-19 12:55 被阅读9次

    文件的编码

    import java.io.UnsupportedEncodingException;
    
    public class EncodeDemo {
        
        public static void main(String[] args) throws UnsupportedEncodingException {
            
            String s = "慕课ABC"  ;
            byte[] bytes1 = s.getBytes() ;
            for (byte b : bytes1) {
                // 把字节(转换成int)以16进制的方式显示
                System.out.print(Integer.toHexString(b & 0xff) + "  ") ;  // 去除前面的24个0
            }
            System.out.println();
            
            // gbk编码中文占用2个字节,英文占用1个字节
            byte[] bytes2 = s.getBytes("gbk") ;
            for (byte b : bytes2) {
                System.out.print(Integer.toHexString(b & 0xff) + "  ") ;  // 去除前面的24个0
            }
            System.out.println();
            
            // UTF-8编码中文占用3个字节,英文占用1个字节
            byte[] bytes3 = s.getBytes("UTF-8") ;
            for (byte b : bytes3) {
                System.out.print(Integer.toHexString(b & 0xff) + "  ") ;  // 去除前面的24个0
            }
            System.out.println();
            
            // java是双字节编码 utf-16be
            byte[] bytes4 = s.getBytes("utf-16be") ;
            //  utf-16be中文占用2个字节,英文占用2个字节
            for (byte b : bytes4) {
                System.out.print(Integer.toHexString(b & 0xff) + "  ") ;  // 去除前面的24个0
            }
            System.out.println();
            
            /*
             * 当你的字节序列是某种编码时,这个时候想把字节序列变成字符串,
             * 也需要用这种编码方式,否则会出现乱码
             */
            String s1 = new String(bytes4); // 用项目默认编码
            System.out.println(s1);
            String s2 = new String(bytes4,"utf-16be"); // 用项目默认编码
            System.out.println(s2);
            
            /*
             * 文本文件就是字节序列,可以是任意编码的字节序列
             * 如果我们在中文机器上直接创建文本文件,那么该文本文件只认识ANSI编码
             * 联通、联这是一种巧合,他们正好符合了UTF-8编码的规则
             */
            
        }
        
    }
    
    

    java.io.File类用于表示文件(目录)
    File类只用于表示文件(目录)的信息(名称、大小等),不能用于文件内容的访问

    import java.io.File;
    import java.io.IOException;
    
    public class FileDemo {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // 了解构造函数的情况  查帮助
            File file = new File("E:\\javaio\\imooc");
            //System.out.println(file.exists());
            if(!file.exists()) // 文件是否存在
                file.mkdir(); // 创建文件;file.mkdirs()创建多级目录
            else
                file.delete();
            //是否是一个目录  如果是目录返回true,如果不是目录or目录不存在返回的是false
            System.out.println(file.isDirectory());
            //是否是一个文件
            System.out.println(file.isFile());
            
            //File file2 = new File("e:\\javaio\\日记1.txt");
            File file2 = new File("e:\\javaio","日记1.txt");
            if(!file2.exists())
                try {
                    file2.createNewFile();  // 创建文件
                } catch (IOException e) {
                    e.printStackTrace();
                }
            else 
                file2.delete();
             //常用的File对象的API
            System.out.println(file);   //file.toString()的内容
            System.out.println(file.getAbsolutePath());     // 文件位置
            System.out.println(file.getName());     // 目录名
            System.out.println(file2.getName());    // 文件名
            System.out.println(file.getParent());   // 父路径
            System.out.println(file2.getParent());  // 父路径
            System.out.println(file.getParentFile().getAbsolutePath()); // 父路径
        }
    
    }
    
    import java.io.File;
    import java.io.FileFilter;
    import java.io.FilenameFilter;
    
    public class FileDemo2 {
    
        public static void main(String[] args) {
            
            File file = new File("e:\\example");
            /*
             * String[] filenames = file.list(new FilenameFilter() {
             * 
             *      @Override 
             *      public boolean accept(File dir, String name) {
             *          System.out.println(dir+"\\"+name); 
             *          return name.endsWith("java"); 
             *      } 
             * });
             * for (String string : filenames) { 
             *      System.out.println(string);
             * }
             */
            /*
             * File[] files = file.listFiles(new FilenameFilter() {
             * 
             *      @Override 
             *      public boolean accept(File dir, String name) { 
             *          System.out.println(dir+"\\"+name);
             *          return false; 
             *      } 
             * });
             */
            File[] files = file.listFiles(new FileFilter() {
    
                @Override
                public boolean accept(File pathname) {
                    System.out.println(pathname);
    
                    return false;
                }
            });
        }
    }
    

    遍历目录

    /**
     * 列出File的一些常用操作,比如过滤、遍历等操作
     * @author Administrator
     *
     */
    public class FileUtils {
        
        /**
         * 列出指定目录下(包括其子目录)的所有文件
         * @param dir
         * @throws IOException
         */
        public static void listDirectory(File dir) throws IOException{
            
            if(!dir.exists()) {
                throw new IllegalArgumentException("目录:"+dir+"不存在。") ;
            }
            
            if(!dir.isDirectory()) {
                throw new IllegalArgumentException(dir+"不是目录。") ;
            }
            
            String[] fileName = dir.list() ;  // list()方法用于列出当前目录下的子目录和文件,返回字符串数组,直接子的名称,不包含子目录下的内容
            for (String string : fileName) {
                System.out.println(dir+"\\"+string);  // 打印整个目录
            }
            
            // 如果要遍历子目录下的内容就需要构造成File对象做递归操作,File提供了直接返回File对象的API
            File[] files = dir.listFiles() ;  // 返回的是直接子目录(文件)的抽象
            if(files != null && files.length > 0) {
                for (File file : files) {
                    if(file.isDirectory()) {
                        // 递归
                        listDirectory(dir);
                    }else {
                        System.out.println(file);
                    }
                }
            }
            
        }
    }
    
    import java.io.File;
    import java.io.IOException;
    
    public class FileUtilTest1 {
    
        public static void main(String[] args) throws IOException {
            FileUtils.listDirectory(new File("E:\\example"));
        }
    
    }
    

    RandomAccessFile类的使用

    • RandomAccessFile java提供的对文件内容的访问,既可以读文件,也可以写文件。

    • RandomAccessFile支持随机访问文件,可以访问文件的任意位置

    • java文件模型

      • 在硬盘上的文件是byte byte byte存储的,是数据的集合
    • 打开文件

      • 有两种模式"rw"(读写) "r"(只读)
      • RandomAccessFile raf = new RandomeAccessFile(file,"rw")
      • 文件指针,打开文件时指针在开头 pointer = 0;
    • 写方法

      • raf.write(int) --->只写一个字节(后8位),同时指针指向下一个位置,准备再次写入
    • 读方法

      • int b = raf.read() ---> 读一个字节
    • 文件读写完成以后一定要关闭(Oracle官方说明)

    import java.io.File;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.util.Arrays;
    
    public class RafDemo {
    
        /**
         * @param args
         */
        public static void main(String[] args) throws IOException {
            
            File demo = new File("demo");
            if (!demo.exists())
                demo.mkdir();
            File file = new File(demo, "raf.dat");
            if (!file.exists())
                file.createNewFile();
    
            RandomAccessFile raf = new RandomAccessFile(file, "rw");
            // 指针的位置
            System.out.println("指针位置:"+raf.getFilePointer());
    
            raf.write('A'); // 只写了一个字节
            System.out.println("指针位置:"+raf.getFilePointer());
            raf.write('B');
            
            int i = 0x7fffffff;
            // 用write方法每次只能写一个字节,如果要把i写进去就得写4次
            raf.write(i >>> 24);    // 高8位
            raf.write(i >>> 16);    
            raf.write(i >>> 8);
            raf.write(i);
            System.out.println("指针位置:"+raf.getFilePointer());
    
            // 可以直接写一个int
            raf.writeInt(i);
    
            String s = "中";
            byte[] gbk = s.getBytes("gbk");
            raf.write(gbk);
            System.out.println("文件长度:"+raf.length());
    
            // 读文件,必须把指针移到头部
            raf.seek(0);
            // 一次性读取,把文件中的内容都读到字节数组中
            byte[] buf = new byte[(int) raf.length()];
            raf.read(buf);
    
            System.out.println(Arrays.toString(buf));
            for (byte b : buf) {
                System.out.print(Integer.toHexString(b & 0xff) + " ");
            }
            raf.close();
        }
    
    }
    
    import java.io.IOException;
    import java.io.RandomAccessFile;
    
    public class RafReadDemo {
        
        public static void main(String[] args) throws IOException {
    
            RandomAccessFile raf = new RandomAccessFile("demo/raf.dat", "r");
            raf.seek(2);
            int i = 0;
            int b = raf.read();// 读取到一个字节
            System.out.println(raf.getFilePointer());
            i = i | (b << 24);
            b = raf.read();
            i = i | (b << 16);
            b = raf.read();
            i = i | (b << 8);
            b = raf.read();
            i = i | b;
            System.out.println(Integer.toHexString(i));
            raf.seek(2);
            i = raf.readInt();
            System.out.println(Integer.toHexString(i));
            raf.close();
    
        }
    
    }
    

    IO流(输入流、输出流)

    • 字节流、字符流
      1.字节流
      - InputStream、OutputStream
      - InputStream抽象了应用程序读取数据的方式
      - OutputStream抽象了应用程序写出数据的方式
      2.EOF = End 读到-1就读到结尾
      3.输入流基本方法
      - int b = in.read(); // 读取一个字节无符号填充到int低八位.-1是 EOF
      - in.read(byte[] buf) // 读取数据填充到字节数组buf
      - in.read(byte[] buf,int start,int size) // 读取数据到字节数组buf,从buf的start位置开始存放size长度的数据
      4.输出流基本方法
      - out.write(int b) // 写出一个byte到流,b的低8位
      - out.write(byte[] buf) // 将buf字节数组都写入到流
      - out.write(byte[] buf,int start,int size) // 字节数组buf从start位置,开始写size长度的字节到流
      5.FileInputStream --->具体实现了在文件上读取数据
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class IOUtil {
        
        /**
         * 读取指定文件内容,按照16进制输出到控制台,并且每输出10个byte换行
         * @param fileName 单字节读取不适合大文件,大文件效率很低
         */
        public static void printHex(String fileName) throws IOException {
            // 把文件作为字节流进行读操作
            FileInputStream in = new FileInputStream(fileName);
            int b;
            int i = 1;
            while ((b = in.read()) != -1) {  // -1则读到文件结尾
                if (b <= 0xf) {  
                    // 单位数前面补0
                    System.out.print("0");
                }
                System.out.print(Integer.toHexString(b) + "  ");
                if (i++ % 10 == 0) {
                    System.out.println();
                }
            }
            in.close();
        }
    }
    
    import java.io.IOException;
    
    public class IOUtilTest1 {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            try {
                IOUtil.printHex("e:\\javaio\\FileUtils.java");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    }
    
    /**
     * 批量读取,对大文件而言效率高,也是我们最常用的读文件的方式
     * 
     * @param fileName
     * @throws IOException
     */
    public static void printHexByByteArray(String fileName) throws IOException {
        FileInputStream in = new FileInputStream(fileName);
        byte[] buf = new byte[8 * 1024];
        /*
         * 从in中批量读取字节,放入到buf这个字节数组中, 从第0个位置开始放,最多放buf.length个,返回的是读到的字节的个数
         */
        /*
         * int bytes = in.read(buf,0,buf.length);   // 一次性读完,说明字节数组足够大 
         * int j = 1; 
         * for(int i= 0; i < bytes;i++){ 
         *      System.out.print(Integer.toHexString(buf[i] & * 0xff)+"  "); 
         *      if(j++%10==0){ 
         *          System.out.println(); 
         *      }
         *  }
         */
        int bytes = 0;
        int j = 1;
        while ((bytes = in.read(buf, 0, buf.length)) != -1) {
            for (int i = 0; i < bytes; i++) {
                System.out.print(Integer.toHexString(buf[i] & 0xff) + "  ");
                if (j++ % 10 == 0) {
                    System.out.println();
                }
            }
        }
        in.close();
    }
    
    import java.io.IOException;
    
    public class IOUtilTest2 {
    
        public static void main(String[] args) {
            try {
                long start = System.currentTimeMillis();
                // IOUtil.printHexByByteArray("e:\\javaio\\FileUtils.java");
                // IOUtil.printHex("e:\\javaio\\1.mp3");
                IOUtil.printHexByByteArray("e:\\javaio\\1.mp3");
                System.out.println();
                long end = System.currentTimeMillis();
                System.out.println(end - start);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    1. FileOutputStream 实现了向文件中写出byte数据的方法
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class FileOutDemo1 {
    
        public static void main(String[] args) throws IOException {
            // 如果该文件不存在,则直接创建,如果存在,删除后创建
            FileOutputStream out = new FileOutputStream("demo/out.dat"); // 追加内容,加个值为true的参数
            out.write('A');     // 写出了'A'的低八位
            out.write('B');     // 写出了'B'的低八位
            int a = 10;         // write只能写八位,那么写一个int需要些4次每次8位
            out.write(a >>> 24);
            out.write(a >>> 16);
            out.write(a >>> 8);
            out.write(a);
            byte[] gbk = "中国".getBytes("gbk");
            out.write(gbk);
            out.close();
    
            IOUtil.printHex("demo/out.dat");
        }
    }
    
    /**
     * 文件拷贝,字节批量读取
     * 
     * @param srcFile
     * @param destFile
     * @throws IOException
     */
    public static void copyFile(File srcFile, File destFile) throws IOException {
        if (!srcFile.exists()) {
            throw new IllegalArgumentException("文件:" + srcFile + "不存在");
        }
        if (!srcFile.isFile()) {
            throw new IllegalArgumentException(srcFile + "不是文件");
        }
        FileInputStream in = new FileInputStream(srcFile);
        FileOutputStream out = new FileOutputStream(destFile);
        byte[] buf = new byte[8 * 1024];
        int b;
        while ((b = in.read(buf, 0, buf.length)) != -1) {
            out.write(buf, 0, b);
            out.flush();// 最好加上
        }
        in.close();
        out.close();
    }
    
    import java.io.File;
    import java.io.IOException;
    
    public class IOUtilTest3 {
    
        public static void main(String[] args) {
            
            try {
                IOUtil.copyFile(new File("e:\\javaio\\imooc.txt"), new File("e:\\javaio\\imooc1.txt"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    1. DataOutputStream/DataInputStream
      • 对"流"功能的扩展,可以更加方面的读取int,long,字符等类型数据
      • DataOutputStream
        • writeInt()/writeDouble()/writeUTF() 装饰模式
    import java.io.DataOutputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class DosDemo {
        
        public static void main(String[] args) throws IOException {
            String file = "demo/dos.dat";
            DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
            dos.writeInt(10);
            dos.writeInt(-10);
            dos.writeLong(10l);
            dos.writeDouble(10.5);
            // 采用utf-8编码写出
            dos.writeUTF("中国");
            // 采用utf-16be编码写出
            dos.writeChars("中国");
            dos.close();
            IOUtil.printHex(file);
        }
    
    }
    
    import java.io.DataInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    
    public class DisDemo {
    
        public static void main(String[] args) throws IOException {
            String file = "demo/dos.dat";
            IOUtil.printHex(file);
            DataInputStream dis = new DataInputStream(new FileInputStream(file));
            int i = dis.readInt();  // 装饰模式
            System.out.println(i);
            i = dis.readInt();
            System.out.println(i);
            long l = dis.readLong();
            System.out.println(l);
            double d = dis.readDouble();
            System.out.println(d);
            String s = dis.readUTF();
            System.out.println(s);
    
            dis.close();
        }
    
    }
    

    8.BufferedInputStream和BufferedOutputStream
    - 这两个流类位IO提供了带缓冲区的操作,一般打开文件进行写入,或读取操作时,都会加上缓冲,这种流模式提高了IO的性能
    - 从应用程序中把输入放入文件,相当于将一缸水倒入到另一个缸中:
    - FileOutputStream --->write()方法相当于一滴一滴地把水“转移”过去;
    - DataOutputStream ---> writeXxx()方法会方便一些,相当于一瓢一瓢把水“转移”过去
    - BufferedOutputStream --->write方法更方便,相当于一飘一瓢先放入桶中,再从桶中倒入到另一个缸中,性能提高了

    /**
     * 单字节,不带缓冲进行文件拷贝
     * 
     * @param srcFile
     * @param destFile
     * @throws IOException
     */
    public static void copyFileByByte(File srcFile, File destFile) throws IOException {
        if (!srcFile.exists()) {
            throw new IllegalArgumentException("文件:" + srcFile + "不存在");
        }
        if (!srcFile.isFile()) {
            throw new IllegalArgumentException(srcFile + "不是文件");
        }
        FileInputStream in = new FileInputStream(srcFile);
        FileOutputStream out = new FileOutputStream(destFile);
        int c;
        while ((c = in.read()) != -1) {
            out.write(c);
            out.flush();        // 刷新缓冲区才能写入到文件
        }
        in.close();
        out.close();
    }
    

    字符流

    1. 编码问题
    2. 认识文本和文本文件
      • java的文本(char)是16位无符号整数,是字符的unicode编码(unicode编码是双字节编码)
      • 文件是byte byte byte ...的数据序列
      • 文本文件是文本(char)序列按照某种编码方案(utf-8,utf-16be,gbk)序列化为byte的存储结果
      • 字符流的基本实现
        • InputStreamReader 完成byte流解析为char流,按照编码解析
        • OutputStreamWriter 提供char流到byte流,按照编码处理
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    
    public class IsrAndOswDemo {
        
        public static void main(String[] args) throws IOException {
            
            FileInputStream in = new FileInputStream("e:\\javaio\\imoocutf8.txt");
            InputStreamReader isr = new InputStreamReader(in, "utf-8"); // 默认项目的编码,操作的时候,要写文件本身的编码格式
    
            FileOutputStream out = new FileOutputStream("e:\\javaio\\imoocutf81.txt");
            OutputStreamWriter osw = new OutputStreamWriter(out, "utf-8");
            /*
             * int c ; 
             * while((c = isr.read())!=-1){ 
             *      System.out.print((char)c); 
             *}
             */
            char[] buffer = new char[8 * 1024];
            int c;
            
            /*
             * 批量读取,放入buffer这个字符数组,从第0个位置开始放置,最多放buffer.length个,返回的是读到的字符的个数
             */
            while ((c = isr.read(buffer, 0, buffer.length)) != -1) {
                String s = new String(buffer, 0, c);
                System.out.print(s);
                osw.write(buffer, 0, c);
                osw.flush();
            }
            isr.close();
            osw.close();
        }
    }
    

    FileReader/FileWriter

    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class FrAndFwDemo {
        public static void main(String[] args) throws IOException {
            FileReader fr = new FileReader("e:\\javaio\\imooc.txt");
            FileWriter fw = new FileWriter("e:\\javaio\\imooc2.txt");
            // FileWriter fw = new FileWriter("e:\\javaio\\imooc2.txt",true);  // 追加内容
            char[] buffer = new char[2056];
            int c;
            while ((c = fr.read(buffer, 0, buffer.length)) != -1) {
                fw.write(buffer, 0, c);
                fw.flush();
            }
            fr.close();
            fw.close();
        }
    
    }
    

    字符流的过滤器

    • BufferedReader ----> readLine 一次读一行
    • BufferedWriter/PrintWriter ----> 写一行
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    
    public class BrAndBwOrPwDemo {
        public static void main(String[] args) throws IOException{
             // 对文件进行读写操作 
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(
                            new FileInputStream("e:\\javaio\\imooc.txt")));
            /*
             * BufferedWriter bw = new BufferedWriter(
                    new OutputStreamWriter(
                            new FileOutputStream("e:\\javaio\\imooc3.txt")));
            */
            PrintWriter pw = new PrintWriter("e:\\javaio\\imooc4.txt");
            // PrintWriter pw1 = new PrintWriter(outputStream,boolean autoFlush);  // autoFlush自動刷新缓存区
            String line ;
            while((line = br.readLine())!=null){
                System.out.println(line);   // 一次读一行,并不能识别换行
                /* 
                bw.write(line);
                // 单独写出换行操作
                bw.newLine();   // 换行操作
                bw.flush();
                */
                pw.println(line);
                pw.flush();
            }
            br.close();
            // bw.close();
            pw.close();
        }
    
    }
    

    对象的序列化,反序列化

    • 对象序列化,就是将Object转换成byte序列,反之叫对象的反序列化 ;

    • 序列化流(ObjectOutputStream),是过滤流 —— writeObject;

    • 反序列化流(ObjectInputStream) —— readObject;

    • 序列化接口(Serializable)

      • 对象必须实现序列化接口 ,才能进行序列化,否则将出现异常;
      • 这个接口,没有任何方法,只是一个标准;
    import java.io.Serializable;
    
    public class Student implements Serializable {
        private String stuno;
        private String stuname;
        // 该元素不会进行jvm默认的序列化,也可以自己完成这个元素的序列化
        private transient int stuage;
    
        public Student(String stuno, String stuname, int stuage) {
            super();
            this.stuno = stuno;
            this.stuname = stuname;
            this.stuage = stuage;
        }
    
        public String getStuno() {
            return stuno;
        }
    
        public void setStuno(String stuno) {
            this.stuno = stuno;
        }
    
        public String getStuname() {
            return stuname;
        }
    
        public void setStuname(String stuname) {
            this.stuname = stuname;
        }
    
        public int getStuage() {
            return stuage;
        }
    
        public void setStuage(int stuage) {
            this.stuage = stuage;
        }
    
        @Override
        public String toString() {
            return "Student [stuno=" + stuno + ", stuname=" + stuname + ", stuage=" + stuage + "]";
        }
    
        // ArrayList的方法签名
        private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
            s.defaultWriteObject();     // 把jvm能默认序列化的元素进行序列化操作
            s.writeInt(stuage);     // 自己完成stuage的序列化
        }
    
        // ArrayList的方法签名
        private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
            s.defaultReadObject();      // 把jvm能默认反序列化的元素进行反序列化操作
            this.stuage = s.readInt();  // 自己完成stuage的反序列化操作
        }
    }
    
    import java.io.FileInputStream;
    import java.io.ObjectInputStream;
    
    public class ObjectSeriaDemo1 {
        
        public static void main(String[] args) throws Exception {
            String file = "demo/obj.dat";
            // 1.对象的序列化
            /*
             * ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream(file));
             * Student stu = new Student("10001", "张三", 20); oos.writeObject(stu);
             * oos.flush(); 
             * oos.close();
             */
            
            // 反序列化
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
            Student stu = (Student) ois.readObject();  // 强制类型转换
            System.out.println(stu);
            ois.close();
    
        }
    
    }
    

    transient关键字

    • private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException
    • private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException

    分析ArrayList源码中序列化和反序列化的问题

    序列化中,子类和父类构造函数的调用问题

    • 对子类对象进行反序列化操作时, 如果其父类没有实现序列化接口,那么其父类的构造函数会被调用
    import java.io.FileInputStream;
    import java.io.ObjectInputStream;
    import java.io.Serializable;
    
    public class ObjectSeriaDemo2 {
        public static void main(String[] args) throws Exception {
            /*
             * ObjectOutputStream oos = new ObjectOutputStream( new
             * FileOutputStream("demo/obj1.dat")); Foo2 foo2 = new Foo2();
             * oos.writeObject(foo2); oos.flush(); oos.close();
             */
    
            // 反序列化是否递归调用父类的构造函数
            /*
             * ObjectInputStream ois = new ObjectInputStream( new
             * FileInputStream("demo/obj1.dat")); Foo2 foo2 = (Foo2)ois.readObject();
             * System.out.println(foo2); ois.close();
             */
    
            /*
             * ObjectOutputStream oos = new ObjectOutputStream( new
             * FileOutputStream("demo/obj1.dat")); Bar2 bar2 = new Bar2();
             * oos.writeObject(bar2); oos.flush(); oos.close();
             */
    
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("demo/obj1.dat"));
            Bar2 bar2 = (Bar2) ois.readObject();
            System.out.println(bar2);
            ois.close();
    
            /*
             * 对子类对象进行反序列化操作时, 如果其父类没有实现序列化接口 那么其父类的构造函数会被调用
             */
        }
    }
    
    /*
     * 一个类实现了序列化接口,那么其子类都可以进行序列化
     */
    class Foo implements Serializable {
        public Foo() {
            System.out.println("foo...");
        }
    }
    
    class Foo1 extends Foo {
        public Foo1() {
            System.out.println("foo1...");
        }
    }
    
    class Foo2 extends Foo1 {
        public Foo2() {
            System.out.println("foo2...");
        }
    }
    
    class Bar {
        public Bar() {
            System.out.println("bar");
        }
    }
    
    class Bar1 extends Bar {
        public Bar1() {
            System.out.println("bar1..");
        }
    }
    
    class Bar2 extends Bar1 implements Serializable {
        public Bar2() {
            System.out.println("bar2...");
        }
    }
    

    相关文章

      网友评论

          本文标题:文件传输基础-Java IO流

          本文链接:https://www.haomeiwen.com/subject/oagmkftx.html