Day63.IO流复习 -Java常用类、集合、IO#

IO流复习

.

File类的使用

1. File类的理解

1. File类的一个对象,代表一个文件或一个文件目录(俗称: 文件夹)
2. File类声明在java.io包下
3. File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,
   并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容。就必须使用IO流来完成
4. 后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的"终点"

2. File的实例化

常用构造器
File(String filePath)
File(String parentPath,String childPath)
File(File parentPath,String childPath)
路径的分类
相对路径:相较于某个路径下,指明的路径。
绝对路径:包含盘符在内的路径或文件目录的路径

说明:
    IDEA中:
    如果大家开发使用Junit中的单元测试方法测试,相对路径即为当前Module下。
    如果使用main()测试,相对路径即为当前的Project下。
    Eclipse中:
    不管使用单元测试方法还是使用main()测试,相对路径都是Project下。    
    
路径分隔符
windows: \\
unix、url: /

3. File类的常用方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YyJuCKx0-1601301910240)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20200928220402452.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4alnVWDT-1601301910243)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20200928220411023.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rceekVCk-1601301910246)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20200928220420838.png)]

/*
-File类的获取功能:
 public String getAbsolutePath(): 获取绝对(完整)路径
 public String getPath(): 获取路径
 public String getName(): 获取名称
 public String getParent(): 获取上层文件目录路径。若无,返回null
 public long length(): 获取文件长度(即: 字节数)。 不能获取目录的长度。
 public long lastModified(): 获取最后一次的修改时间,毫秒值

 如下方法适用于文件目录
 public String[] list(): 获取指定目录下的所有文件或者文件目录的名称数组
 public File[] listFile(): 获取指定目录下的所有文件或者文件目录的File数组

-File类的重命名功能:
public boolean renameTo(File dest): 把文件重命名为指定的文件路径

-File类的判断功能:
public boolean isDirectory(): 判断是否是文件目录
public boolean isFile(): 判断是否是文件
public boolean exists: 判断是否存在
public boolean canRead(): 判断是否可读
public boolean canWrite(): 判断是否可写
public boolean isHidden(): 判断是否隐藏

-File类的创建功能
public boolean createNewFile(): 创建文件。若文件存在,则不创建,返回false
public boolean mkdir(): 创建文件目录。如果此文件目录存在,就不创建了。
                        如果此文件目录的上级目录不存在,也不创建。
public boolean mkdirs(): 创建文件目录。如果上级文件目录不存在,一并创建

-File类的删除功能
public boolean delete(): 删除文件或者文件夹

 */
@Test
    public void test2(){
    File file1 = new File("hello.txt");
    File file2 = new File("D:\\io\\hi.txt");

    System.out.println(file1.getAbsolutePath());
    System.out.println(file1.getPath());
    System.out.println(file1.getName());
    System.out.println(file1.getParent());
    System.out.println(file1.length());
    System.out.println(new Date(file1.lastModified()));

    System.out.println();

    System.out.println(file2.getAbsolutePath());
    System.out.println(file2.getPath());
    System.out.println(file2.getName());
    System.out.println(file2.getParent());
    System.out.println(file2.length());
    System.out.println(file2.lastModified());
}
@Test
public void test3(){
    File file = new File("D:\\321");

    String[] list = file.list();
    for(String s:list){
        System.out.println(s);
    }

    File[] listFiles = file.listFiles();
    for (File f : listFiles){
        System.out.println(f);
    }
}

/*
public boolean renameTo(File dest): 把文件重命名为指定的文件路径
    比如: file1.renameTo(file2)为例
        要想保证返回为true,需要file1在硬盘中是存在的,且file2不能在硬盘中存在。
 */

@Test
public void test4(){
    File file1 = new File("hello.txt");
    File file2 = new File("D:\\io\\hi.txt");

    boolean renameTo = file1.renameTo(file2);
    System.out.println(renameTo);

}

/*
-File类的判断功能:
public boolean isDirectory(): 判断是否是文件目录
public boolean isFile(): 判断是否是文件
public boolean exists: 判断是否存在
public boolean canRead(): 判断是否可读
public boolean canWrite(): 判断是否可写
public boolean isHidden(): 判断是否隐藏
 */
@Test
public void test5(){
    File file1 = new File("hello.txt");

    System.out.println(file1.isDirectory());
    System.out.println(file1.isFile());
    System.out.println(file1.exists());
    System.out.println(file1.canRead());
    System.out.println(file1.canWrite());
    System.out.println(file1.isHidden());

    System.out.println();

    File file2 = new File("D:\\io");

    System.out.println(file2.isDirectory());
    System.out.println(file2.isFile());
    System.out.println(file2.exists());
    System.out.println(file2.canRead());
    System.out.println(file2.canWrite());
    System.out.println(file2.isHidden());
}
/*
-File类的创建功能: 创建硬盘中对应的文件或文件目录
public boolean createNewFile(): 创建文件。若文件存在,则不创建,返回false
public boolean mkdir(): 创建文件目录。如果此文件目录存在,就不创建了。
                        如果此文件目录的上级目录不存在,也不创建。
public boolean mkdirs(): 创建文件目录。如果上级文件目录不存在,一并创建

-File类的删除功能:  删除硬盘中对应的文件或文件目录
public boolean delete(): 删除文件或者文件夹
    注意事项:
    Java中的删除不走回收站
 */
@Test
public void test6() throws IOException {
    //文件的创建
    File file1 = new File("hi.txt");
    if (!file1.exists()){
        file1.createNewFile();
        System.out.println("创建成功");
    }else{//文件存在
        file1.delete();
        System.out.println("删除成功");
    }
}

@Test
public void test7() {
    //文件目录的创建
    File file1 = new File("D:\\io\\io1\\io3");
    boolean mkdir1 = file1.mkdir();
    if (mkdir1) {
        System.out.println("创建成功1");
    }else {
        System.out.println("创建失败1");
    }


    File file2 = new File("D:\\io\\io1\\io4");
    boolean mkdir2 = file2.mkdirs();
    if (mkdir2) {
        System.out.println("创建成功2");
    }else {
        System.out.println("创建失败2");
    }
}

.

IO流概述

1. 流的分类

1. 操作数据单位: 字节流、字符流
2. 数据的流向: 输入流、输出流
3. 流的角色: 节点流、处理流
图示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-107PxAxv-1601727768016)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201003190517523.png)]

2. 流的体系结构

在这里插入图片描述

说明:

​ 红框对应的是IO流的4个抽象基类。

​ 蓝框的流需要重点关注

3. 重点说明的几个流结构

抽象基类                节点流 (或文件流)                              缓冲流 (处理流的一种)
InputStream             FileInputStream (read(byte[] buffer))          BufferedInputStream (read(byte[] buffer))
OutputStream            FileOutputStream (write(cbuf,0,len))           BufferedOutputStream (write(cbuf,0,len)) / flush()
Reader                  FileReader(read(char[] cbuf))                  BufferedReader (read(char[] cbuf) / readline())
Writer                  FileWriter(write(cbuf,0,len))                  BufferedWriter (write(cbuf,0,len)) / flush()

4. 输入、输出的标准化过程

输入过程

①创建File的对象,指明读取数据的来源。(要求此文件一定要存在)

②创建相应的输入流,将File类的对象作为参数,传入流的构造器中。

③具体的读入过程:

​ 创建相应的byte[] 或 char[]。

④关闭流资源。

说明: 程序中出现的异常需要使用try-catch-finally处理。

输出过程

①创建File的对象,指明写出数据的位置。(不要求此文件一定要存在)

②创建相应的输出流,将File类的对象作为参数,传入流的构造器中。

③具体的写出过程:

​ write(char[] / byte[] buffer,0,len);

④关闭流资源。

说明: 程序中出现的异常需要使用try-catch-finally处理。
.

节点流(或文件流)

1. FileReader / FileWriter的使用:

FileReader的使用:
将Note下的hello.txt文件内容读入程序中,并输出到控制台

说明:
1. read()的理解: 返回读入的一个字符。如果达到文件末尾,返回 -12. 异常的处理: 为了保证 流 资源一定可以执行关闭操作。需要使用try-catch-finally处理
3. 读入的文件一定要存在,否则就会报FileNotFoundException。

@Test
    public void testFileReader1(){
        FileReader fr = null;
        try {
            //1. File类的实例化
            File file = new File("hello.txt");

            //2. FileReader流的实例化
            fr = new FileReader(file);
            //3. 读入的操作
            //read(char[] cbuf,):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回 -1。
            char[] cbuf = new char[5];
            int len;
            while ((len =fr.read(cbuf)) != -1 ){
            //方式一:

                //错误写法:
//                for (int i = 0; i < cbuf.length; i++) {
//                    System.out.print(cbuf[i]);
//                }
                //正确写法:
//                for (int i = 0; i < len; i++) {
//                    System.out.print(cbuf[i]);
//                }

            //方式二:
                //错误写法:
//                String s = new String(cbuf);
//                System.out.println(s);
                //正确写法:
                String s =new String(cbuf,0,len);
                System.out.print(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fr!=null){
                    //4. 资源关闭
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
FileWriter的使用:
从内存中写出数据到硬盘文件里。

说明:
    1. 输出操作,对应的File可以不存在。并不会报异常。
    2.    File对应硬盘中的文件,如果不存在,在输出的过程中会自动创建此文件。
          File对应硬盘中的文件,如果存在:
                如果流使用的构造器是:FileWriter(file,false) / FileWriter(file): 对原有文件的覆盖
                如果流使用的构造器是:FileWriter(file,true): 不会对原有文件覆盖,而是在原有文件基础上追加内容

@Test
public void testFileWriter() {
    FileWriter fw = null;
    try {
        //1. 提供File类的对象,指明写出到的文件
        File file =new File("hello1.txt");

        //2. 提供FileWriter的对象,用于数据的写出
        fw = new FileWriter(file,false);

        //3. 写出的操作
        fw.write("i have a dream!\n");
        fw.write("you need to have a dream!");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (fw != null){
                //4. 流资源的关闭
                fw.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
文本文件的复制:
    @Test
    public void testFileWriterFileReader() {
        FileReader fr = null;
        FileWriter fw = null;
        try {
            //1. 创建File类的对象,指明读入和写入的文件
            File srcFile = new File("hello.txt");
            File destFile = new File("hello2");

            //不能使用字符流来处理图片等字节数据
//            File srcFile = new File("灯光.png");
//            File destFile = new File("灯光1.png");

            //2. 创建输入流和输出流对象
            fr = new FileReader(srcFile);
            fw = new FileWriter(destFile);

            //3. 数据的读入和写出操作
            char[] cbuf = new char[5];
            int len;//记录每次读入到cbuf数组中的字符个数
            while ((len = fr.read(cbuf))!=-1){
                fw.write(cbuf,0,len);

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. 关闭流资源
            //方式一:
//            try {
//                if (fw !=null){
//                    fw.close();
//                }
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//            finally{
//                try {
//                    if (fr !=null){
//                        fr.close();
//                    }
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
            //方式二
            try {
                if (fw !=null){
                    fw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
                try {
                    if (fr !=null){
                        fr.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }
}

2. FileInputStream / FileOutputStream的使用

1. 对于文本文件(.txt,.java,.c,.cpp),使用字符流来处理
2. 对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,.md,...),使用字节流来处理
//实现对图片的复制操作
@Test
public void testFileInputStreamFileOutputStream(){
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
        //1. 创建File类对象,指明输出输入的文件
        File srcFile = new File("灯光.png");
        File goalFile = new File("灯光2.png");

        //2. 创建输出和出入流对象
        fis = new FileInputStream(srcFile);
        fos = new FileOutputStream(goalFile);

        //3. 写入输出操作
        byte[] cbuf = new byte[5];
        int len;
        while ((len = fis.read(cbuf))!=-1){
            fos.write(cbuf,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //4. 流操作的关闭

        try {
            if (fos!= null) {
                fos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (fis != null) {
                fis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
【注意点】

相对路径在IDEA 和 Eclipse中使用的区别?

IDEA:

如果使用单元测试方法 (@Test) ,相对路径基于当前Module的。

如果使用main()测试,相对路径基于当前Project工程的。

Eclipse:

单元测试方法(@Test) 还是 main() 都是基于当前Project工程的。

.

缓冲流的使用

1. 缓冲流涉及到的类:

BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter

2. 作用:

提供流的读取、写入速度
提高读写速度的原因:
                 内部提供了一个缓冲区
                 默认情况下是8kb

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TuopzpDm-1601727768025)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201003194617772.png)]

3.典型代码:

使用BufferedInputStream和BufferedOutputStream:非文本文件
//实现非文本文件的复制
    @Test
    public void BufferedInputStreamTest(){
        FileInputStream fis = null;
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            //1. File类的文件创建
            File srcFile = new File("灯光.png");
            File destFile = new File("灯光3.png");

            //2. 流文件对象的创建
            //2.1 两个节点流(文件流)
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);
            //2.2 两个缓冲流
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);


            //3. 复制操作: 读取、写入
            byte[] buffer = new byte[10];
            int len;
            while((len = bis.read(buffer))!=-1){
                bos.write(buffer,0,len);
//                bos.flush();//刷新缓冲区
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. 流的关闭
            //要求4.1: 先关闭外层的流,再关闭内层的流
            if (bis!= null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bis!= null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //说明: 关闭外层流的同时,内层流也会自动的关闭。关于内层流的关闭操作,可以省略。
//            fis.close();
//            fos.close();
        }
    }
使用BufferedReader和BufferedWriter:
//使用BufferedReader和BufferedWriter实现文本文件的复制
    @Test
    public void testBufferedReaderBufferedWriter(){
        //创建File类文件和对应流文件
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new FileReader(new File("消息信息.txt")));
            bw = new BufferedWriter(new FileWriter(new File("消息信息1.txt")));

            //复制操作
            //方式一: 使用char[]
//            char[] buffer = new char[10];
//            int len;
//            while ((len = br.read(buffer))!=-1){
//                bw.write(buffer,0,len);
//            }

            //方式二: 使用String
            String date;
            while ((date = br.readLine()) != null){
                //方法一:
//                bw.write(date+"\n");//date中不包含换行符
                //方法二:
                bw.write(date);//date中不包含换行符
                bw.newLine();//提供换行操作
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流资源
            try {
                if (bw != null){
                    bw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (br != null){
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

.

转换流的使用

1. 转换流涉及到的类: 属于字符流

InputStreamReader: 	将一个字节的输入流转换为字符的输入流
解码: 字节、字节数组  --->字符数组、字符串

OutputStreamWriter: 将一个字符的输出流转换为字节的输出流
编码: 字符数组、字符串  --->字节、字节数组

说明: 编码 决定 解码 的方式

2. 作用:

提供字节流与字符流之间的转换

3. 图示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N8PeUTmF-1601727768028)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201003200141545.png)]

4. 典型实现:

    //InputStreamReader的使用,实现将字节输入流转字符输入流转换
    @Test
    public void test1(){
        java.io.InputStreamReader isr = null;//指明具体使用哪个字符集,其取决于文件消息信息.txt他保存时使用的字符集
        try {
            FileInputStream fis = new FileInputStream("消息信息.txt");
//        java.io.InputStreamReader isr = new java.io.InputStreamReader(fis);//使用系统默认的字符集
            isr = new java.io.InputStreamReader(fis,"UTF-8");

            char[] cubf = new char[20];
            int len;
            while ((len = isr.read(cubf)) != -1){
                String str = new String(cubf,0,len);
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (isr!=null){
                try {
                    isr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
//将消息信息.txt从字符集UTF-8转换为GBK字符集,使用转换流实现文件的读入和写出转换
@Test
public void test2(){
    java.io.InputStreamReader isr = null;
    OutputStreamWriter osw = null;
    try {
        FileInputStream fis = new FileInputStream("消息信息.txt");
        FileOutputStream fos = new FileOutputStream("消息信息_gbk.txt");

        isr = new java.io.InputStreamReader(fis,"UTF-8");
        osw = new OutputStreamWriter(fos,"GBK");

        char[] cubf = new char[20];
        int len;
        while ((len = isr.read(cubf))!= -1){
            osw.write(cubf,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (osw != null){
            try {
                osw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (isr != null){
            try {
                isr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

5. 说明:

文件编码的方式(比如:GBK),决定了解析时使用的(也只能GBK)字符集。

.

编码表(字符集)

1. 常见的编码表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8n8CF0HN-1601727768031)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201003200731175.png)]

2. 对后面学习的启示

客户端/浏览器端 <—> 后台(java,Go,Python,Node.js,php) <—> 数据库

要求前前后后使用的字符集都要统一: UTF-8

.

其他流的使用

1. 标准的输入输出流:

System.in: 标准的输入流,默认从键盘输入
System.out: 标准的输出流,默认从控制台输出
修改默认的输入和输出行为:
System类的setIn(InputStream is) / setOut(PrintStream ps)方式重新指定输入输出的流。

2. 打印流:

PrintStream 和 PrintWriter
说明:
提供了一系列重载的print() 和 println(),用于多重数据类型的输出
System.out返回的是PrintStream的实例

3. 数据流:

DateInputStream 和 DateOutputStream
作用:
用于读取或写出基本数据类型的变量或字符串
实例代码:
将内存中的字符串、基本数据类型的变量写出到文件中。

 */

//数据写入
@Test
public void test3(){
    //1.
    DataOutputStream dos = null;
    try {
        dos = new DataOutputStream(new FileOutputStream("date.txt"));
        //2.
        dos.writeUTF("阿昌");
        dos.flush();//刷新操作,将内存中的数据写入文件
        dos.writeInt(21);
        dos.flush();
        dos.writeBoolean(true);
        dos.flush();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //3.
        if (dos!= null){
            try {
                dos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

/*
将文件中存储的基本数据类型和字符串读取到内存中,保存在变量中。

注意点:读取不同类型数据的顺序要按照当初写入的顺序保持一致。

 */

//数据读取
@Test
public void test4(){
    DataInputStream dis = null;
    try {
        //1.
        dis = new DataInputStream(new FileInputStream("date.txt"));
        //2.
        String name = dis.readUTF();
        int age = dis.readInt();
        boolean isMale = dis.readBoolean();

        System.out.println("name="+name);
        System.out.println("age="+age);
        System.out.println("isMale="+isMale);

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (dis != null){
            //3.
            try {
                dis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

对象流的使用

1. 对象流:

ObjectInputStream 和 ObjectOutputStream

2. 作用:

ObjectOutputStream: 内存中的对象 —>存储中的文件、通过网络传输 :序列化过程

ObjectInputStream : 存储中的文件、通过网络传输 —> 内存中的对象: 反序列化过程

3. 对象的序列化机制

运行把内存中的Java对象转行为二进制流,从而允许把这二进制流持久地保存在磁盘中,
或是通过网络将二进制流传输到另一个网络节点。当其他程序获取到这个二进制流,
就可以将它恢复成原来的Java对象。

4. 序列化代码实现

序列号过程

/*
序列号过程: 将内存中的Java对象保存在磁盘中或通过网络传输出去
使用ObjectOutputStream实现
 */
@Test
public void testObjectOutputStream(){
    ObjectOutputStream oos = null;
    try {
        //1.
        oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
        //2.
        oos.writeObject(new String("我爱敲代码"));
        oos.flush();//刷新操作

        oos.writeObject(new Person("阿昌",21));
        oos.flush();//刷新操作

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (oos != null){
            try {
                //3.
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

5.反序列化代码实现

反序列化过程

/*
反序列化过程: 将磁盘文件中的对象还原为内存中的Java对象
使用ObjectInputStream实现
 */
@Test
public void testObjectInputStream(){
    ObjectInputStream ois = null;
    try {
        ois = new ObjectInputStream(new FileInputStream("object.dat"));

        Object obj = ois.readObject();
        String str = (String)obj;

        Person p =(Person)ois.readObject()  ;

        System.out.println(str);
        System.out.println(p);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (ois != null){
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

6.实现序列化的对象所属的类需要满足:

1. 需要实现接口: Serializable
2. 需要当前类提供一个全局常量: serialVersionUID,序列版本号
3. 除了当前Person类需要实现Serializable接口之外,还必须保证其内部的所有属性
   也必须是可序列号的。(默认情况下,基本数据类型都可序列化)

补充:ObjectInputStream 和 ObjectOutputStream不能序列化static和transient修饰的成员变量

RandomAccessFile的使用

1. 随机存取文件流:

RandomAccessFile

2. 使用说明:

1. RandomAccessFile直接继承于java.lang.Object类,实现了DateInput和DateOutput接口
2. RandomAccessFile既可以作为一个输入流,又可以作为一个输出流。
3. 如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行时自动创建。
                                 写出到的文件存在,则会对原有文件内容,进行覆盖。(默认情况下,从头覆盖)
4. 可以通过相关的操作实现RandomAccessFile"插入"数据的效果   seek(int pos)

3.代码举例

典型代码1:
复制操作,可充当输入输出流

@Test
public void test1(){
    RandomAccessFile raf1 = null;
    RandomAccessFile raf2 = null;
    try {
        //1.
        raf1 = new RandomAccessFile(new File("灯光.png"),"r");
        raf2 = new RandomAccessFile(new File("灯光6.png"),"rw");
        //2.
        byte[] buffer = new byte[20];
        int len;
        while ((len = raf1.read(buffer)) != -1){
            raf2.write(buffer,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //3.
        if (raf1 != null){
            try {
                raf1.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (raf2 != null){
                try {
                    raf2.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
典型代码2:
/*
使用RandomAccessFile实现数据的插入效果
 */
@Test
public void test3() throws IOException {
    RandomAccessFile raf1 = new RandomAccessFile(new File("hi.txt"),"rw");

    raf1.seek(3);//将指针调到3下标位置
    //保存3下标后面所有数据到stringBuffer中
    StringBuffer stringBuffer = new StringBuffer((int) new File("hi.txt").length());
    byte[] buffer = new byte[5];
    int len;
    while ((len = raf1.read(buffer)) != -1){
        stringBuffer.append(new String(buffer,0,len));
    }

    raf1.seek(3);//将指针调到要插入3下标的位置,插入"Oni_pepe"
    raf1.write("Oni_pepe".getBytes());

    //写入保存在StringBuffer内的数据到文件中
    raf1.write(stringBuffer.toString().getBytes());

    raf1.close();

}

Path、Paths、Files的使用

1. NIO的使用说明:

Java NIO (New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新 的IO API,可以替代标准的Java IO API

NIO与原来的IO有同样的作用和目 的,但是使用的方式完全不同,NIO支持面向缓冲区的(IO是面向流的)、基于 通道的IO操作。

NIO将以更加高效的方式进行文件的读写操作。

随着 JDK 7 的发布,Java对NIO进行了极大的扩展,增强了对 文件处理和文件系统特性的支持,以至于我们称他们为 NIO.2

2. Path的使用 —jdk7提供

Path的说明:

Path替换原有的File类。

如何实例化:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mxQ0z737-1601891141705)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201005174107757.png)]

常用方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nxmC4Ogg-1601891141708)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201005174124914.png)]

3. Files工具类 —jdk7提供

作用:

操作文件或文件目录的工具类

常用方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DXo7wQDC-1601891141710)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201005174225247.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PW8LebL8-1601891141714)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201005174238749.png)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿昌喜欢吃黄桃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值