JavaSE进阶九 IO流二

File类

  • File类和四大家族没有关系,所以File类不能完成文件的读和写。
  • File对象代表什么?
    • 文件和目录路径名的抽象表示形式。
    • 一个File对象有可能对应的是目录,也有可能是文件。
代码示例
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FileTest01 {
    public static void main(String[] args)  {
        // 创建一个file对象  指定一个路径
        File file = new File("/Users/a1/Desktop/Java/Simon_JavaSE/test");
        // 判断该路径下文件是否存在
        System.out.println(file.exists());
        if (!file.exists()){ // 文件不存在,
            try {
                // 以文件的形式新建
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }

            // 以目录(文件夹)形式新建
            // file.mkdir();
        }

        File file1 = new File("/Users/a1/Desktop/Java/Simon_JavaSE/a/b/c/test.text");
        System.out.println(file1.exists());

        if (!file1.exists()){ // 不存在
            // 多重目录(文件夹)的形式新建
            file1.mkdirs();
        }

        // 获取文件的父路径
        String parentPath = file.getParent();
        System.out.println("获取父路径:" + parentPath);// /Users/a1/Desktop/Java/Simon_JavaSE
        File parentFile = file.getParentFile();
        System.out.println("获取绝对路径:" + parentFile.getAbsolutePath());

        // 获取绝对路径
        File file2 = new File("src/temp3");
        System.out.println("获取绝对路径:" + file2.getAbsolutePath());

        // 获取文件名
        System.out.println("文件名:" + file.getName());

        // 判断是否是一个目录
        System.out.println(file.isDirectory());
        // 判断是否是一个文件
        System.out.println(file.isFile());

        // 获取文件最后一次修改时间
        long hm = file.lastModified(); //从1970年到现在的总毫秒数
        Date time = new Date(hm);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        String strTime = sdf.format(time);
        System.out.println(strTime);

        // 获取文件大小
        System.out.println(file.length());

        // 获取当前目录下所有的子文件
        File file4 = new File("/Users/a1/Desktop/Java/Simon_JavaSE");
        File[] fileList = file4.listFiles();
        // foreach
        for (File fl : fileList){
            System.out.println(fl.getAbsolutePath());
            System.out.println(fl.getName());
        }
    }
}
拷贝目录demo
import java.io.*;

public class CopyCatalogue {
    public static void main(String[] args) {
        // 拷贝源
        File srcFile =  new File("/Users/a1/Desktop/Java/Simon_JavaSE/JavaTest");
        // 拷贝目标
        File disFile =  new File("/Users/a1/Desktop/Java/Simon_JavaSE/JavaTest-Copy");
        // 调用方法进行拷贝
        copyDir(srcFile,disFile);
    }

    /**
     * 拷贝目录
     * @param srcFile 拷贝源
     * @param disFile 拷贝目标
     */
    private static void copyDir(File srcFile, File disFile) {
        if (srcFile.isFile()){
            // srcFile是一个文件时,递归结束。
            // 是文件需要拷贝,一边读一边写...
            FileInputStream fin = null;
            FileOutputStream fos = null;
            try {
                // 读取这个文件
                fin = new FileInputStream(srcFile);
                // 写到这个文件中
                String absolutePath = disFile.getAbsolutePath();
                String path = (absolutePath.endsWith("/") ? absolutePath: absolutePath + "/") + srcFile.getAbsolutePath().substring(45);
                fos = new FileOutputStream(path);

                // 一边读一边写
                byte[] bytes = new byte[1024 * 1024]; // 一次复制1MB
                int readCount = 0;
                while ((readCount = fin.read(bytes)) != -1){
                    fos.write(bytes,0,readCount);
                }

                // 刷新
                fos.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fin != null){
                    try {
                        fin.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fos != null){
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

            return;
        }

        if (srcFile.isFile()){
            return;
        }
        // 获取拷贝源下面的子目录
        File[] files = srcFile.listFiles();
        for (File file : files){
            // 获取所有文件的绝对路径

            if (file.isDirectory()){
                String srcDir = file.getAbsolutePath();
                String disAbsolutePath = disFile.getAbsolutePath();
                String desDir = disAbsolutePath.endsWith("/") ? disAbsolutePath : disAbsolutePath + "/" + srcDir.substring(45);
                File newFile = new File(desDir);
                if (!newFile.exists()){
                    newFile.mkdirs();
                }
            }

            // 递归调用
            copyDir(file,disFile);
        }

    }
}

序列化和反序列化

  • 参与序列化和反序列化的对象,必须实现Serializable接口。

  • 通过源代码发现Serializable接口只是一个标志接口:

    • public interface Serializable{}
    • 这个接口当中什么代码都没有,起标识、标志的作用;java虚拟机看到这个类实现了这个接口,会对这个类进行特殊待遇。
    • Serializable这个标志接口是给java虚拟机参考的,java虚拟机看到这个接口之后,会为该类自动生成一个序列化版本号。
  • transient关键字:

    • 表示游离的,不参与序列化。
  • java语言中是采用什么机制区分类的

    • 1,通过类名进行比对,如果类名不一样,肯定不是同一个类
    • 2,如果类名一样,靠序列化版本号进行区分。
  • 自动生成序列化版本号的缺陷:

    • 自动生成的序列化版本号缺点是:一旦代码确定之后,不能进行后续修改,因为只有修改,必然会重新编译,
      此时会生成全新的序列化版本号,这个时候java虚拟机会认为这是一个全新的类。(如果没有重新序列化,
      只进行反序列化操作,会报异常)。
  • 开发中建议序列版本号手动写出,不建议自动生成。

代码示例
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class ObjectOutputStreamTest01 {
    public static void main(String[] args) {
        // 创建java对象
        Student student = new Student(1231,"张小五");
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;

        ObjectOutputStream oosList = null;
        ObjectInputStream oisList = null;
        try {
            // 序列化
            oos = new ObjectOutputStream(new FileOutputStream("Student"));
            // 序列化对象
            oos.writeObject(student);
            // 刷新
            oos.flush();

            // 反序列化 对象
            ois = new ObjectInputStream(new FileInputStream("Student"));
            // 开始反序列化
            Object obj = ois.readObject();
            System.out.println(obj);

            // ----------------------------------------------------------------------------

            // 序列化
            oosList = new ObjectOutputStream(new FileOutputStream("StudentList"));

            // 创建集合对象
            List<Student> list = new ArrayList<>();
            // 创建学生对象
            Student student1 = new Student(12,"张小六");
            Student student2 = new Student(13,"王小六");
            Student student3 = new Student(14,"李小六");
            Student student4 = new Student(15,"胡小六");
            // 添加元素
            list.add(student1);
            list.add(student2);
            list.add(student3);
            list.add(student4);

            // 序列化一个集合
            oosList.writeObject(list);
            // 刷新
            oosList.flush();

            // 反序列化集合
            oisList = new ObjectInputStream(new FileInputStream("StudentList"));
            Object redObj = oisList.readObject();
            // 开始反序列化
            if (redObj instanceof List){ // 如果是List集合
                // 进行类型转换
                List<Student> objs = (List<Student>) redObj;
                // 变量输出
                for (Student o : objs){
                    System.out.println(o);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (oos != null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (ois != null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (oosList != null){
                try {
                    oosList.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (oisList != null){
                try {
                    oisList.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class Student implements Serializable {
    // java虚拟机看到Serializable接口之后,会为该类自动生成一个序列化版本号。
    // 当Student这个类源代码改动了,需要重新编译,编译之后生成新的字节码文件。
    // 并且class文件再次运行的时候,java虚拟机生成的序列版本号也会发生相应的改变。

    // 如果没有重新序列化的时候,进行反序列化时会报异常。

    // 序列化版本号在没有手动写出的时候,系统会提供默认序列化版本号
    // 建议序列版本号手动写出,不建议自动生成
    private static final long serialVersionUID = 124234343342l;
    // idea工具 生成序列化版本号:" alt + 回车"

    private int no;
    // private String name;
    private transient String name; //name不参与序列化操作

    public Student() {
    }

    public Student(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}

IO+Properties的联合使用:

  • Properties是一个Map集合,key和value都是String类型。

  • 这种设计理念的好处:

    • 遇到经常要改动的数据,可以单独写到一个文件中,使用程序动态读取;将来只需要修改这个文件的内容,
      java代码不需要改动,不需要重新编译,服务器也不需要重启;就可以拿到动态信息。
  • 类似于以上机制的这种文件被称为配置文件。

    • 配置文件中的内容格式如下, 我们把这种配置文件称为:属性配置文件。

        key1=value
        key2=value
        ...
      
  • java规范中有要求:属性配置文件建议以.properties结尾,但不是必须的。

  • Properties是专门存放属性配置文件内容的一个类。(在属性配置文件中#是注释)

代码示例
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

public class IoPropertiesTest01 {
    public static void main(String[] args) {
        // 新建一个输入流对象
        FileReader reader = null;
        try {
            // 在src文件夹下新建一个userInfo文档
            // 内容填充: name=zhangsan  password=123466 (记得换行)
            reader = new FileReader("src/userInfo");

            // 新建一个Map集合
            Properties pro = new Properties();
            // 调用Properties对象的load方法将文件中的数据加载到Map集合中。
            pro.load(reader); //文件中的数据顺着管道加载到Map集合中:等号左边做key、右边做value
            // 通过key获取value
            System.out.println(pro.getProperty("name"));
            System.out.println(pro.getProperty("password"));

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

上篇:JavaSE进阶九 IO流一

下篇:JavaSE进阶十 线程一

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

推荐阅读更多精彩内容

  • 什么是IO? I:InputO:Output通过IO可以完成硬盘文件的读和写。 IO流的分类 有多种分类方式:一种...
    苦难_69e0阅读 206评论 0 1
  • 六、IO流 这一部分IO流指的是Java.util.io包下的标准IO流。java.io包下提供的是同步IO流,它...
    卑微小白在线求带阅读 134评论 0 0
  • 学习目的 了解java流的概念 了解java对流的分类 掌握java流的对象创建,以及常用方法的使用 掌握java...
    从前的小余儿阅读 236评论 0 0
  • 目录 [TOC] 第一章:IO介绍 1.1 什么是IO ​ 生活中,你肯定经历过这样的场景。当你编辑一个文本文...
    雷哒哒阅读 274评论 0 1
  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 123,140评论 2 7