文件传输基础-Java IO流

文件的编码

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...");
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,539评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,594评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,871评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,963评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,984评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,763评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,468评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,850评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,002评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,144评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,823评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,483评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,026评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,150评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,415评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,092评论 2 355

推荐阅读更多精彩内容