• java中的io流


    1. IO流,什么是IO?

    I : Input
    O: Output
    通过IO可以完成硬盘文件的读和写。

    2.IO流的分类?

    有多种分类方式:
    1)一种方式是按照流的方向进行分类:
    以内存作为参照物,
    往内存中去,叫做输入。或者叫做读(Read)。
    从内存中出来,叫做输出。或者叫做写(Write)。

    2)另一种方式是按照读取数据方式不同进行分类:
    有的流是按照字节的方式读取数据,一次读取1个字节byte等同于一次读取8个二进制位。
    这种流是万能的,什么类型的文件都可以读取。包括文本文件、图片、声音文件、视频文件等等…
    假设文件file1.txt,采用字符流的话是这样读的:
    a中国bc张三fe
    第一次读:1个字节,正好读到’a’
    第二次读:1个字节,正好读到’中’字符的一半
    第三次都:1个字节,正好读到’中’字符的另外一半

    有的流是按照字符的方式读取数据,一次读取一个字符,这种流是为了方便读取普通文本文件存在的。这种流不能读取:图片、声音、视频等文件,只能读取纯文本文件,连word文件都无法读取。
    假设文件file1.txt,采用字符流的话是这样读的:
    a中国bc张三fe
    第一次读: 'a’字符('a’字符在windows系统中占用1个字节)
    第二次读: '中’字符('中’字符在windows系统中占用2个字节)

    综上所述: 流的分类
    输入流、输出流(按照流的方向进行分类)
    字节流、字符流(按照读取的方式进行分类)

    3.IO流都在java.io.*包下

    java中的IO流都已经写好了,我们程序员不需要关心,我们最主要还是掌握,在java中已经提供了哪些流,每个流的特点是什么,每个流对象上的常用方法有哪些?
    java中所有的流都是在: java.io.*下。

    java中主要还是研究:
    怎么new流对象。
    调用流对象的哪个方法是读,哪个方法是写。

    4.java IO流有四个家族

    java.io.InputStream 字节输入流
    java.io.OutputStream 字节输出流

    java.io.Reader 字符输入流
    java.io.Writer 字符输出流

    注意: 在java中只要"类名"以Stream结尾的都是字节流。以"Reader/Writer"结尾的都是字符流。

    5.java.io包下需要掌握的流有16个

    文件专属:
    java.io.FileInputStream
    java.io.FileOutputStream
    java.io.FileReader
    java.io.FileWriter

    转换流:(将字节流转换成字符流)
    java.io.InputStreamReader
    java.io.OutputStreamWriter

    缓冲流专属:
    java.io.BufferedReader
    java.io.BufferedWriter
    java.io.BufferedInputStream
    java.io.BufferedOutputStream

    数据流专属:
    java.io.DateInputStream
    java.io.DateOutputStream

    标准输出流:
    java.io.printWriter
    java.io.printStream

    对象专属流:
    java.io.ObjectInputStream
    java.io.ObjectOutputStream

    6.FileInputStream的1个字节读入法

    package com.jmpower.javase.io;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    /*
    java.io.FileInputStream:
        1.文件字节输入流,万能的,任何类型的文件都可以采用这个流来读。
        2.字节的方式,完成输入的操作,完成读的操作。(硬盘-->内存)
     */
    public class FileInputStreamTest01 {
        public static void main(String[] args) {
            FileInputStream fis=null;
            try {
                //创建字节输入流对象
                //文件路径:C:\Users\Jm\Desktop\Java\doSome.txt
                //文件内容为:abcedf
                //FileInputStream fis=new FileInputStream("C:\\Users\\Jm\\Desktop\\Java\\doSome.txt");
                //都采用了: 绝对路径
                //将"\\"写成"/"也是可以的
                fis=new FileInputStream("C:/Users/Jm/Desktop/Java/doSome.txt");
    
                int readDate=fis.read();//这个方法的返回值是读到字节本身
                System.out.println(readDate);// 97
    
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                //在finally语句块中确保流一定要关闭
                if (fis != null) {
                    //关闭流的前提是:流不是空。流是null的时候没必要关闭。
                    try {
                        fis.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    7.FileInputStream的byte[]读入法

    package com.jmpower.javase.io;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    /*
    int read(byte[] b)
        一次最多读取b.length个字节。
        减少硬盘和内存之间的交互,提高程序的执行效率。
        往byte[]数组当中读。
     */
    public class FileInputStreamTest02 {
        public static void main(String[] args) {
            FileInputStream fis=null;
            try {
                //相对路径的话呢?相对路径一定是从当前所在的位置作为起点开始找!
                //IDEA默认的当前路径是工程Object的根就是IDEA的默认当前路径。
                //文件内容:abcdef
                fis=new FileInputStream("text02.txt");
    
                byte[] bytes=new byte[4];//准备一个4个长度的byte数组,一次最多读取4个字节。
                //这个方法的返回值是,读取到的字节数量。(不是字节本身)
                //int readCount=fis.read(bytes);
                //System.out.println(readCount);// 第一次读到4个字节
    
                //将字节数组全部转换成字符串
                //System.out.println(new String(bytes));
    
                //不应该全部转换,应该读取了多少个字节,转换多少个。
                //System.out.println(new String(bytes,0,readCount));// abcd
    
                //最终版本,读取文件
                int readCount=0;
                while((readCount = fis.read(bytes))!=-1)
                {
                    System.out.print(new String(bytes,0,readCount));
                }
    
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    8.FileInputStream的其他方法

    1)int available(): 返回流当中剩余的没有读取到的字节的数量

    package com.jmpower.javase.io;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    public class FileInputStreamTest03 {
        public static void main(String[] args) {
            FileInputStream fis=null;
            try {
                fis=new FileInputStream("test03");
                System.out.println("总字节数量:"+fis.available());// 41
                //读一个字节
                //int readDate=fis.read();
                //还剩下的可读字节为40
                //System.out.println("还剩下的可读字节的数量:"+fis.available());// 40
                //这个方法有什么用?
                byte[] bytes=new byte[fis.available()];
                //不需要循环了!
                //直接读一次就行了。
                int readCount=fis.read(bytes);// 6
                System.out.println(new String(bytes)); // abcdef
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    2)long stip(long n): 跳过几个字节不读

    package com.jmpower.javase.io;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    public class FileInputStreamTest04 {
        public static void main(String[] args) {
            FileInputStream fis=null;
            try {
                fis=new FileInputStream("text02.txt");
                //a   b  c  d   e   f
                //97 98 99 100 101 102
                System.out.println(fis.read());// 97
                fis.skip(3);//跳过三个字节
                System.out.println(fis.read());// 101
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    9.FileOutputStream用法

    package com.jmpower.javase.io;
    
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class FileOutputStreamTest01 {
        public static void main(String[] args) {
            FileOutputStream fos=null;
            try {
                //file01文件不存在会自动新建!
                //这种方式慎用,这种方式会先将文件清空,然后重新写入。
                //fos=new FileOutputStream("file01");
    
                //以追加的方式在文件末尾写入。不会清空原文件的内容。
                fos=new FileOutputStream("text02.txt",true);
                //开始写
                byte[] bytes={97,98,99,100};
                //将byte数组全部写出!
                fos.write(bytes);// abcd
                //将bute数组的一部分写出!
                fos.write(bytes,0,2);// ab
    
                //字符串
                String s="我是中国人!";
                //将字符串转换成数组
                byte[] bs=s.getBytes();
                //写
                fos.write(bs);
    
                //写完之后一定要刷新
                fos.flush();
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    10.文件复制

    package com.jmpower.javase.io;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /*
    使用FileInputStream + FileOutputStream完成文件的拷贝。
    拷贝的过程一定是一边读,一边写。
    使用以上的字节流拷贝文件的时候,文件类型随意,万能的。什么样的文件都可以拷贝。
     */
    public class Copy01 {
        public static void main(String[] args) {
            FileInputStream fis=null;
            FileOutputStream fos=null;
            try {
                //创建一个输入流对象
                fis=new FileInputStream("C:\\Users\\Jm\\Pictures\\自建\\十三届蓝桥杯省一.jpg");
                //创建一个输出流对象
                fos=new FileOutputStream("C:\\Users\\Jm\\Desktop\\Java\\十三届蓝桥杯省一.jpg");
    
                //最核心的: 一边读,一边写
                byte[] bytes=new byte[1024*1024];//1MB(一次最多拷贝1MB)
                int readCount=0;
                while((readCount=fis.read(bytes))!=-1)
                {
                    fos.write(bytes,0,readCount);
                }
    
                //刷新,输出流最后要刷新
                fos.flush();
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                //分开try,不要一起try
                //一起try的时候,其中一个出现异常,可能会影响到另一个流的关闭
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    11.FileReader用法

    package com.jmpower.javase.io;
    
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    /*
    FileReader:
        读取文本内容时,比较方便,快捷。
        一次读取一个字符。
     */
    public class FileReaderTest {
        public static void main(String[] args) {
            FileReader reader=null;
            try {
                //创建文件字符输入流
                reader=new FileReader("text02.txt");
                //开始读
                char[] chars=new char[4];//一次读取4个字符(1个字符2个字节)
                int readCount=0;
                while((readCount=reader.read(chars))!=-1)
                {
                    System.out.print(new String(chars,0,readCount));
                }
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    12.复制普通文本文件(Reader/Writer)

    package com.jmpower.javase.io;
    
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class Copy02 {
        public static void main(String[] args) {
            FileReader in=null;
            FileWriter out=null;
            try {
                //读
                in=new FileReader("src/com/jmpower/javase/io/FileInputStreamTest02.java");
                //写
                out=new FileWriter("reader");
    
                //一边读一边写
                char[] chars=new char[1024*512];//1MB
                int readCount=0;
                while((readCount=in.read(chars))!=-1)
                {
                    out.write(new String(chars,0,readCount));
                }
    
                //刷新
                out.flush();
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                //关闭流
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    13.带有缓冲区的字符输入流

    package com.jmpower.javase.io;
    
    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    
    /*
    BufferedReader:
        带有缓冲区的字符输入流。
        使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组。自带缓冲。
     */
    public class BufferedReaderTest01 {
        public static void main(String[] args) {
            FileReader reader=null;
            BufferedReader br=null;
            try {
                reader=new FileReader("src/com/jmpower/javase/io/Copy02.java");
                //当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做: 节点流。
                //外部负责包装的这个流,叫做: 包装流,还有一个名字叫做: 处理流。
                //像当前这个程序来说: FileReader叫做一个节点流。BufferedReader就是包装流/处理流。
                br=new BufferedReader(reader);
                /*//第一行
                String firstLine=br.readLine();
                System.out.println(firstLine);
                //第二行
                String secondLine=br.readLine();
                System.out.println(secondLine);*/
    
                //br.readLine()方法读取一个文本行,但不带换行符。
                String line=null;
                while((line=br.readLine())!=null)
                {
                    System.out.println(line);
                }
    
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                //关闭流
                //对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭。(可以看源代码)
                if (br != null) {
                    try {
                        br.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    14.包装流和节点流(即转换流)

    package com.jmpower.javase.io;
    
    import java.io.*;
    
    public class BufferedReaderTest02 {
        public static void main(String[] args) {
    
            BufferedReader br=null;
            try {
                //字节流
                FileInputStream in=new FileInputStream("src/com/jmpower/javase/io/Copy02.java");
    
                //通过转换流转换(InputStreamReader将字节流转换成字符流)
                //in是节点流。reader是包装流。
                InputStreamReader reader=new InputStreamReader(in);
    
                //这个构造方法只能传一个字符流。不能传字节流。
                //reader是节点流。br是包装流。
                br=new BufferedReader(reader);
    
                String line=null;
                while((line=br.readLine())!=null)
                {
                    System.out.println(line);
                }
    
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                //关闭最外层
                try {
                    br.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    15.带有缓冲区的字符输出流

    package com.jmpower.javase.io;
    
    import java.io.*;
    /*
    BufferedWriter: 带有缓冲的字符输出流
    OutputStreamWriter: 转换流
     */
    public class BufferedWriterTest01 {
        public static void main(String[] args) {
            BufferedWriter out=null;
            try {
                //带有缓冲的字符输出流
                //out=new BufferedWriter(new FileWriter("bo"));
                out=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("doSome"/*,true*/)));
                //开始写
                out.write("123");
                out.write("\n");
                out.write("456");
                //刷新(输出流记得刷新)
                out.flush();
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    16.数据流

    1)写

    package com.jmpower.javase.io;
    
    import java.io.*;
    
    /*
    java.io.DataOutputStream:数据专属的流
    这个流可以将数据连通数据的类型一并写入文件。
    注意: 这个文件不是普通文本文档。(这个文件使用记事本打不开)
     */
    public class DataOutputStreamTest01 {
        public static void main(String[] args) {
    
            DataOutputStream dos=null;
            try {
                //创建数据专属的字节输出流
                dos=new DataOutputStream(new FileOutputStream("data"));
                //写数据
                byte b=100;
                short s=400;
                int i=200;
                long l=300;
                float f=3.0f;
                double d=3.14;
                boolean sex=false;
                char c='0';
                //写
                dos.writeByte(b);
                dos.writeShort(s);
                dos.writeInt(i);
                dos.writeLong(l);
                dos.writeFloat(f);
                dos.writeDouble(d);
                dos.writeBoolean(sex);
                dos.writeChar(c);
                //刷新
                dos.flush();
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (dos != null) {
                    try {
                        dos.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    2)读

    package com.jmpower.javase.io;
    
    import java.io.DataInputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    /*
    java.io.DataInputStream: 数据字节输入流
    DataOutputStream写的文件,只能使用DataInputStream去读。并且读的时候你需要提前知道写入的顺序。
    读的顺序需要和谐的顺序一致。才可以正常读出数据。
     */
    public class DataInputStreamTest01 {
        public static void main(String[] args) {
            DataInputStream dis=null;
            try {
                dis=new DataInputStream(new FileInputStream("data"));
                //开始读
                byte b=dis.readByte();
                short s=dis.readShort();
                int i=dis.readInt();
                long l=dis.readLong();
                float f= dis.readFloat();
                double d= dis.readDouble();
                boolean sex= dis.readBoolean();
                char c= dis.readChar();
    
                System.out.println(b);
                System.out.println(s);
                System.out.println(i);
                System.out.println(l);
                System.out.println(f);
                System.out.println(d);
                System.out.println(sex);
                System.out.println(c);
                
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (dis != null) {
                    try {
                        dis.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    17.标准输出流

    package com.jmpower.javase.io;
    
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.PrintStream;
    
    /*
    java.io.PrintStream: 标准的字节输出流。默认输出到控制台。
     */
    public class PrintStreamTest {
        public static void main(String[] args) {
            //联合起来写
            System.out.println("hello world!");
    
            //分开写
            java.io.PrintStream ps=System.out;
            ps.println("hello zhangsan");
            ps.println("hello lisi");
            ps.println("hello wangwu");
    
            //标准输出流不需要手动colse()关闭。
            //可以改变标准输出流的输出方向吗?可以
            
            try {
                //标准输出流不再指向控制台,指向“log”文件
                PrintStream printStream=new PrintStream(new FileOutputStream("log"));
                //修改输出方向,将输出方向修改到"log"文件
                System.setOut(printStream);
                //再输出,输入到了"log"文件中
                System.out.println("hello lisi");
                System.out.println("hello zhangsan");
                System.out.println("hello wangwu");
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    18.File类的理解以及常用方法

    1)
    boolean exists() 测试此抽象路径名表示的文件或目录是否存在。
    boolean createNewFile() 当且仅当具有该名称的文件尚不存在时,原子地创建一个由该抽象路径名命名的新的空文件。
    boolean mkdir() 创建由此抽象路径名命名的目录。
    boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录。
    String getParent() 返回此抽象路径名的父 null的路径名字符串,如果此路径名未命名为父目录,则返回null。
    File getParentFile() 返回此抽象路径名的父,或抽象路径名 null如果此路径名没有指定父目录。
    String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。
    String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。

    package com.jmpower.javase.io;
    
    import java.io.File;
    import java.io.IOException;
    
    /*
    File
        1.File类和四大家族没有关系,所以File类不能完成文件的读和写
        2.File对象代表什么?
            文件和目录路径名的抽象表示方式。
            C:\Users\Jm\Desktop\Java 这是一个File对象
            C:\Users\Jm\Desktop\Java\学习笔记(Java) 这也是一个File对象
            一个File对象有可能对应的目录,也可能是文件
            File只是一个路径名的抽象表达形式
        3.需要掌握File类中常用的方法
            boolean exists() 测试此抽象路径名表示的文件或目录是否存在。
            boolean createNewFile() 当且仅当具有该名称的文件尚不存在时,原子地创建一个由该抽象路径名命名的新的空文件。
            boolean mkdir() 创建由此抽象路径名命名的目录。
            boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录。
            String getParent() 返回此抽象路径名的父 null的路径名字符串,如果此路径名未命名为父目录,则返回null。
            File getParentFile() 返回此抽象路径名的父,或抽象路径名 null如果此路径名没有指定父目录。
            String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。
            String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。  
     */
    public class FileTest01 {
        public static void main(String[] args) {
            //创建一个File对象
            File f1=new File("D:\\file");
    
            //判断是否存在
            System.out.println(f1.exists()); // false
    
            //如果D:\file不存在,则以文件的形式创建出来
            /*if(!f1.exists())
            {
                try {
                    //以文件的形式创建出来
                    f1.createNewFile();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }*/
    
            //如果D:\\file不存在,则以目录的形式创建出来
            /*if(!f1.exists())
            {
                //以目录的形式创建出来
                f1.mkdir();
            }*/
    
            //可以创建多重目录吗?
            /*File f2=new File("D:\\a\\b\\c\\d");
            if(!f2.exists())
            {
                f2.mkdirs();
            }*/
    
            File f3=new File("C:\\Users\\Jm\\Desktop\\Java\\学习笔记(Java)");
            //获取文件的父路径
            String fatherPath=f3.getParent();
            System.out.println(fatherPath);// C:\Users\Jm\Desktop\Java
            File parentFile=f3.getParentFile();
            System.out.println("获得绝对路径: "+parentFile.getAbsolutePath());
    
            File f4=new File("doSome");
            System.out.println("绝对路径: "+f4.getAbsolutePath());
            
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    2)
    String getName() 返回由此抽象路径名表示的文件或目录的名称。
    boolean isDirectory() 测试此抽象路径名表示的文件是否为目录。
    boolean isFile() 测试此抽象路径名表示的文件是否为普通文件。
    long lastModified() 返回此抽象路径名表示的文件上次修改的时间。
    long length() 返回由此抽象路径名表示的文件的长度。

    package com.jmpower.javase.io;
    
    import java.io.File;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /*
    File常用方法:
        String getName() 返回由此抽象路径名表示的文件或目录的名称。
        boolean isDirectory() 测试此抽象路径名表示的文件是否为目录。
        boolean isFile() 测试此抽象路径名表示的文件是否为普通文件。
        long lastModified() 返回此抽象路径名表示的文件上次修改的时间。
        long length() 返回由此抽象路径名表示的文件的长度。  
     */
    public class FileTest02 {
        public static void main(String[] args) {
            File f1=new File("C:\\Users\\Jm\\Desktop\\Java\\学习笔记(Java)\\day01.txt");
            //获取文件名
            System.out.println("文件名: "+f1.getName());
    
            //判断是否是一个目录
            System.out.println(f1.isDirectory());// false
    
            //判断是否是一个文件
            System.out.println(f1.isFile());// true
    
            //判断文件最后一次修改时时间
            long haoMiao=f1.lastModified();
            Date time=new Date(haoMiao);
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
            String strTime=sdf.format(time);
            System.out.println(strTime);
    
            //获取文件的大小
            System.out.println(f1.length());// 2155字节
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    3)
    File[] listFiles() 返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。

    package com.jmpower.javase.io;
    
    import java.io.File;
    
    /*
    File中的lastFiles方法。
        File[] listFiles() 返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。  
     */
    public class FileTest03 {
        public static void main(String[] args) {
            File f1=new File("C:\\Users\\Jm\\Desktop\\Java\\学习笔记(Java)");
            File[] files=f1.listFiles();
            //foreach
            for(File file:files)
            {
                //获取绝对路径
                //System.out.println(file.getAbsolutePath());
                //获取名字
                System.out.println(file.getName());
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    19.目录拷贝

    package com.jmpower.javase.io;
    
    import java.io.*;
    //程序BUG:拷贝源目录下的第一个文件无法拷贝
    public class CopyAll {
        public static void main(String[] args) {
            //拷贝源
            File srcFile=new File("D:\\666\\c语言");
            //拷贝目标
            File destFile=new File("C:\\Users\\Jm\\Desktop\\Java");
            //调用方法拷贝
            copyDir(srcFile,destFile);
        }
        /**
         * 拷贝目录
         * @param srcFile   拷贝源
         * @param destFile  拷贝目标
         */
        private static void copyDir(File srcFile,File destFile){
            if(srcFile.isFile())
            {
                //srcFile如果是一个文件的话,递归结束
                //是文件需要拷贝
                //....一边读一边写
                FileInputStream in=null;
                FileOutputStream out=null;
                try {
                    //读这个文件
                    //D:\666\c语言\算法模板\map函数.txt
                    in=new FileInputStream(srcFile);
                    //写到这个文件中
                    //C:\Users\Jm\Desktop\Java\666\c语言\算法模板\map函数.txt
                    String path=(destFile.getAbsolutePath().endsWith("\\")?destFile.getAbsolutePath():destFile.getAbsolutePath()+"\\")+srcFile.getAbsolutePath().substring(3);
                    out=new FileOutputStream(path);
                    //一边读一边写
                    byte[] bytes=new byte[1024*1024];//1MB
                    int readCount=0;
                    while((readCount=in.read(bytes))!=-1)
                    {
                        out.write(bytes,0,readCount);
                    }
                    //刷新
                    out.flush();
                } catch (FileNotFoundException e) {
                    throw new RuntimeException(e);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                } finally {
                    if (out != null) {
                        try {
                            out.close();
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    if (in != null) {
                        try {
                            in.close();
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
                return ;
            }
            //获取源下面的子目录
            File[] files=srcFile.listFiles();
            for(File file:files)
            {
                if(file.isDirectory())
                {
                    //新建对应目录
                    //System.out.println(file.getAbsolutePath());
                    //D:\666\c语言\算法模板                           源目录
                    //C:\Users\Jm\Desktop\Java\666\c语言\算法模板     目标目录
                    String srcDir=file.getAbsolutePath();
                    String destDir=(destFile.getAbsolutePath().endsWith("\\")?destFile.getAbsolutePath():destFile.getAbsolutePath()+"\\")+srcDir.substring(3);
                    File newFile=new File(destDir);
                    if(!newFile.exists())
                    {
                        newFile.mkdirs();
                    }
                }
                else {
                    //保证拷贝目录下第一个是文件时,不会出现FileNotFound的异常
                    File newFile=new File((destFile.getAbsolutePath().endsWith("\\")?destFile.getAbsolutePath():destFile.getAbsolutePath()+"\\")+srcFile.getAbsolutePath().substring(3));
                    if(!newFile.exists())
                    {
                        newFile.mkdirs();
                    }
                }
                //递归调用
                copyDir(file,destFile);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96

    20.序列化和反序列化

    序列化: Serialize java对象存储到文件中。将java对象的状态保存下来的过程。
    反序列化:DeSerialize 将硬盘上的数据重新恢复到内存当中,恢复成java对象。
    在这里插入图片描述

    1)序列化的实现:

    package com.jmpower.javase.io;
    
    import com.jmpower.javase.bean.Student;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    /*
    1.参与序列化和反序列化的对象,必须实现Serializable接口。
    
    2.注意: 通过源码发现,Serializable接只是一个标志接口:
        public interface Serializable{
        }
        这个接口当中什么代码都没有。
        他只是起到一个标识的作用,标志的作用,java虚拟机看到这个类实现了这个接口,可能会对这个类进行特殊待遇。
    
    3.序列化版本号有什么用呢?
        java.io.InvalidClassException:
            com.jmpower.javase.bean.Student;
            local class incompatible:
                stream classdesc serialVersionUID = -6680413217747085692, (10年前)
                local class serialVersionUID = -1967551671371379446(10年后)
    
        java语言是采用什么机制来区分类的?
            第一,首先通过类名进行比对,如果类名不一样,肯定不是同一个类。
            第二,如果类名一样,再根据序列化版本号进行区分。
    
        自动生成序列化版本号的好处:
            java虚拟机会自动区分不同人相同的实现了Serializable接口的类,都有默认的序列化版本号,
            他们的序列化版本号不一样。所以区分开了。
    
        自动生成序列化版本号的坏处:
            这种自动生成的序列化版本号,一旦代码确定之后,不能进行后续的修改,
            因为只要修改,必然会重新编译,此时会生成全新的序列化版本号,这个时候
            java虚拟机会认为这是一个全新的类。(不利于以后的修改)
     */
    public class ObjectOutputStreamTest01 {
        public static void main(String[] args) {
            //创建java对象
            Student s=new Student(1111,"zhansan");
            ObjectOutputStream oos=null;
            try {
                //序列化
                oos=new ObjectOutputStream(new FileOutputStream("students"));
    
                //序列化对象
                oos.writeObject(s);
    
                //刷新
                oos.flush();
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (oos != null) {
                    try {
                        oos.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    2)反序列化的实现

    package com.jmpower.javase.io;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    
    /*
    反序列化
     */
    public class ObjectInputStreamTest01 {
        public static void main(String[] args) {
            ObjectInputStream ois=null;
            try {
                ois=new ObjectInputStream(new FileInputStream("students"));
                //开始反序列化,读
                Object obj=ois.readObject();
                //反序列化回来是一个学生对象,所以会调用学生对象的toString方法。
                System.out.println(obj);
                ois.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            } finally {
                if (ois != null) {
                    try {
                        ois.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    3)Student类

    package com.jmpower.javase.bean;
    
    import java.io.Serializable;
    
    public class Student implements Serializable {
        private int age;
        private int no;
        private String 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 + '\'' +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    21.序列化多个对象

    1)序列化

    package com.jmpower.javase.io;
    
    import com.jmpower.javase.bean.User;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.util.ArrayList;
    import java.util.List;
    /*
    一次序列化多个对象呢?
        可以,可以将对象放到集合当中,序列化对象。
    提示:
        参与序列化的ArrayList集合以及集合中的元素User都需要实现java.io.Serializable接口。
     */
    public class ObjectOutputStreamTest02 {
        public static void main(String[] args) {
            List<User> list=new ArrayList<>();
            list.add(new User(1111,"zhangsan"));
            list.add(new User(2222,"lisi"));
            list.add(new User(3333,"wangwu"));
            list.add(new User(4444,"zhaoliu"));
            ObjectOutputStream oos=null;
            try {
                oos=new ObjectOutputStream(new FileOutputStream("users"));
                //序列化一个集合,这个集合对象中放了很多其他对象。
                oos.writeObject(list);
                //刷新
                oos.flush();
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (oos != null) {
                    try {
                        oos.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    2)反序列化

    package com.jmpower.javase.io;
    
    import com.jmpower.javase.bean.User;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.util.List;
    
    public class ObjectInputStreamTest02 {
        public static void main(String[] args) throws FileNotFoundException {
            ObjectInputStream ois=null;
            try {
                //反序列化
                ois=new ObjectInputStream(new FileInputStream("users"));
                List<User> list= (List<User>) ois.readObject();
                for(User user:list)
                {
                    System.out.println(user);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            } finally {
                if (ois != null) {
                    try {
                        ois.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    22.transient关键字

    变量被transient关键词修饰,不会参与序列化。

    package com.jmpower.javase.bean;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
        //java虚拟机看到Serializable接口之后,会自动生成一个序列化版本号
        //这里没有手动写出来,java虚拟机会默认提供这个序列化版本号。
        //建议将序列化版本号手动的写出来。不建议自动生成。
        private static final long serialVersionUID=1L;//java虚拟机识别一个类的时候,先看类名,类名一样再看序列化版本号。
        private int age;
        //若不手动写序列化版本号,过了很久,Student这个类源代码改动了。
        //源代码改动之后,需要重新编译,编译之后生成了全新的字节码文件。
        //并且class文件再次运行的时候,java虚拟机生成的序列化版本号也会发生相应的改变。
        private int no;
        //transient关键字表示游离的,不参与序列化。
        private transient String name;//name不参与序列化操作!
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    23.序列化版本号

    序列化版本号有什么用呢?
    java.io.InvalidClassException:
    com.jmpower.javase.bean.Student;
    local class incompatible:
    stream classdesc serialVersionUID = -6680413217747085692,
    (10年前)
    local class serialVersionUID = -1967551671371379446
    (10年后)

    java语言是采用什么机制来区分类的?
    第一,首先通过类名进行比对,如果类名不一样,肯定不是同一个类。
    第二,如果类名一样,再根据序列化版本号进行区分。

    自动生成序列化版本号处:
    java虚拟机会自动区分不同人相同的实现了Serializable接口的类,都有默认的序列化版本号,
    他们的序列化版本号不一样。所以区分开了。

    自动生成序列化版本号处:
    这种自动生成的序列化版本号,一旦代码确定之后,不能进行后续的修改,
    因为只要修改,必然会重新编译,此时会生成全新的序列化版本号,这个时候
    java虚拟机会认为这是一个全新的类。(不利于以后的修改)

    所以我们应该手动生成序列化版本号,以后修改源代码的时候,可以不用重新编译,直接运行,不会使得java虚拟机产生新的类,便于程序的修改。

    package com.jmpower.javase.bean;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
        //java虚拟机看到Serializable接口之后,会自动生成一个序列化版本号
        //这里没有手动写出来,java虚拟机会默认提供这个序列化版本号。
        //建议将序列化版本号手动的写出来。不建议自动生成。
        private static final long serialVersionUID=1L;//java虚拟机识别一个类的时候,先看类名,类名一样再看序列化版本号。
        private int age;
        //若不手动写序列化版本号,过了很久,Student这个类源代码改动了。
        //源代码改动之后,需要重新编译,编译之后生成了全新的字节码文件。
        //并且class文件再次运行的时候,java虚拟机生成的序列化版本号也会发生相应的改变。
        private int no;
        //transient关键字表示游离的,不参与序列化。
        private transient String name;//name不参与序列化操作!
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    24.IO和Properties的联合使用

    package com.jmpower.javase.io;
    
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.Map;
    import java.util.Properties;
    import java.util.Set;
    
    /*
    IO+Properties的联合应用:
    非常好的一个设计理念:
        以后经常改变的数据,可以单独写到一个文件中,使用程序动态读取。
        将来只需要修改这个文件的内容,java代码不需要改动,不需要重新编译,
        服务器也不需要重启。就可以拿到动态的信息。
    
        类似于以上机制的这种文件被称为配置文件。
        并且当配置文件中的内容格式是:
            key1=value
            key2=value
        的时候,我们把这种配置文件叫做属性配置文件。
    
        java规范中要求: 属性配置文件建议以.properties结尾,但这不是必须的。
        这种以.properties结尾的文件在java中称为: 属性配属文件。
        其中Properties是专门存放属性配置文件内容的一个类。
     */
    public class IopropertiesTest01 {
        public static void main(String[] args) {
            /*
            Properties是一个Map集合,key和value都是String类型。
            想将doSome文件中的数据加载得到Properties的对象当中。
             */
            FileReader reader=null;
            try {
                //创建输入流对象
                reader=new FileReader("doSome1.properties");
    
                //创建一个Map集合
                Properties pro=new Properties();
    
                //调用Properties对象的load方法将文件中的数据加载到Map集合中。
                pro.load(reader);//文件中的数据顺着管道加载到Map集合中,其中=左边做key,右边做value
    
                //通过key来的调用value
                System.out.println(pro.getProperty("age"));
    
                //遍历
                Set<Map.Entry<Object, Object>> s=pro.entrySet();
                for(Map.Entry<Object,Object> o:s)
                {
                    System.out.println(o.getKey()+"="+o.getValue());
                }
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    属性配置文件的使用:

    #在属性配置文件中井号是注释
    #建议key和value之间使用=的方式,不建议使用 age:40
    #=左边是key,=右边是value
    #最好不要有空格
    username=zhangsan
    age=40
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    linux安装redis(保姆级-安装包方式安装-版本6.2.7-解决aof持久化问题)
    J9数字论:数字行业L2是当下发展的中心
    对冲基金巨头又“出事”了
    【STL】list的模拟实现
    每日一练 | 网络工程师软考真题Day34
    Mysql高可用
    入门指南:Element UI 组件的安装及使用
    Spark入门(一篇就够了)
    C++斩题录|递归专题 | leetcode50. Pow(x, n)
    Web服务器简介及HTTP协议
  • 原文地址:https://blog.csdn.net/m0_66689823/article/details/125881759