文件与IO操作

文件流

文件在程序中是以流的形式来操作的
:数据在数据源(文件)和程序(内存)之间经历的路径。
输入流:数据从数据源(文件)到程序(内存)的路径。
输出流:数据从程序(内存)到数据源(文件)的路径。

创建文件对象的相关构造器

new File(String pathname)//根据路径构建一个File对象
new File(File parent,String child)//根据父目录文件+子路径
new File(String parent,String child)//根据父目录+子路径构建
public static void main(String[] args) throws IOException {
        //new File(String pathname)创建文件
        String filepath1 = "D:\\test1.txt";
        File file = new File(filepath1);
        file.createNewFile();
        System.out.println(file+"创建成功");

        //new File(File parent,String child)创建文件
        File file1 = new File("D:\\");
        String filename = "test2.txt";
        File file2 = new File(file1, filename);
        file2.createNewFile();
        System.out.println(file2+"创建成功");

        //new File(String parent,String child ) 创建文件
        String parentName = "D:\\";
        String childName = "test3.txt";
        File file3 = new File(parentName, childName);
        file3.createNewFile();
        System.out.println(file3+"创建成功");
    }

文件创建成功了
在这里插入图片描述

文件的相关操作

        getName:得到文件的名字
        getAbsoultPath:
        getParent:得到文件的父目录
        length:文件的长度
        exists:判断文件是否存在
        isFile: 判断file是不是文件
        isDirectory: 判断file是不是一个目录

    public static void main(String[] args) throws IOException {
//        getName:得到文件的名字
//        getAbsoultPath:
//        getParent:得到文件的父目录
//        length:文件的长度
//        exists:判断文件是否存在
//        isFile: 判断file是不是文件
//        isDirectory: 判断file是不是一个目录
        //new File(String pathname)创建文件
        String filepath1 = "D:\\test1.txt";
        File file = new File(filepath1);
        file.createNewFile();
        System.out.println(file+"创建成功");
        System.out.println(file+"文件的名字是"+file.getName());
        System.out.println(file+"文件的父目录是"+file.getParent());
        System.out.println(file+"文件的绝对路径是"+file.getAbsolutePath());
        System.out.println(file+"文件的长度是"+file.length()); //因为我们只创建了文件没写如任何东西
        System.out.println(file.exists());
        System.out.println(file.isFile());
        System.out.println(file.isDirectory());
    }

在这里插入图片描述

目录的创建和删除

mkdirs:创建目录
delete:删除空目录或文件
  public static void main(String[] args) throws IOException {
        String filepath1 = "D:\\hello\\world";
        File file = new File(filepath1);
        file.mkdirs();
        System.out.println(file+"创建成功");

        boolean tmp =  file.delete();
        System.out.println(tmp); //返回目录是否删除成功
    }

在这里插入图片描述

IO流

什么是IO流?

I/O是Input/Output的缩写,I/O技术是非常实用的技术,用于处理数据传输。如读/写文件,网络通讯等。

Java程序中,对于数据的输入/输出操作以“流(stream)“的方式进行

Java.io包下提供了各种”流“类和接口,用以获取不同种类的数据,并通过方法输入和输出数据

输入input:读取外部数据(磁盘,光盘等存储设备中的数据)到程序(内存)中

输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。

节点流和输出流

节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter

在这里插入图片描述
处理流(也叫包装流)是连接已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能。如BufferedReader、BufferedWriter。
在这里插入图片描述

1.节点流是底层流,直接跟数据源相接
2.处理流包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出。
3.处理流对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连
处理流的功能主要体现在以下两个方面;
1.性能的提高:主要以增加缓冲的方式来提高输入输出的效率。
2.操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便

流的分类

按操作数据单位不同分为:字节流(8bit)二进制文件,字符流(按字符)文本文件。
按数据流的流向不同分为:输入流,输出流。
按流的角色的不同分为:节点流,处理流/包装流。

在这里插入图片描述
Java的IO流共涉及40多个类,实际上非常规则都是从如上4个抽象基类派生的

由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。
在这里插入图片描述

FileInputStream类

FileInputStream从文件系统中的文件获取输入字节。
FileInputStream用于读取诸如图像数据的原始字节流。 要阅读字符串,请考虑使用FileReader 。

FileInputStream类构造方法

构造方法
FileInputStream(File file) 
通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。

如果命名文件不存在,则是一个目录而不是常规文件,或者由于某些其他原因无法打开读取
就会抛出一个FileNotFoundException 。 


FileInputStream(String name) 
通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。  

 public static void main(String[] args) throws IOException {

        String filepath = "D:\\abc.txt";
        File file = new File(filepath);
        //方法1  创建FileInputStream对象
        FileInputStream fileInputStream = new FileInputStream(file);
        System.out.println(fileInputStream);

        //方法2
        FileInputStream fileInputStream1 = new FileInputStream("D:\\abc.txt");
        System.out.println(fileInputStream1);
    }

在这里插入图片描述

FileInputStream类方法

public int read()  
从该输入流读取一个字节的数据。 如果没有输入可用,此方法将阻止。 

结果 
数据的下一个字节,如果到了文件的末尾,返回 -1 。 


public int read(byte[] b)
从该输入流读取最多b.length字节的数据到字节数组。 如果读不到数据,此方法将阻塞。
参数 
b - 读取数据的缓冲区。 

结果 
读入缓冲区的总字节数,如果没有更多的数据,如果文件的已经到了结尾,返回 -1 。

public long skip(long n)
跳过并从输入流中丢弃n个字节的数据。 
由于各种原因, skip方法可能会跳过一些较小数量的字节,可能是0 。 
如果n为负,则该方法将尝试向后跳。 如果后台文件不支持其当前位置的向后跳过,则会抛出IOException 。

参数 
n - 要跳过的字节数。 

结果 
返回实际跳过的字节数。 如果它向前跳,它返回一个正值。 如果它向后跳,它返回一个负值。 
该方法可能会跳过比后备文件中剩余的字节更多的字节。 这不会产生异常,

close()
关闭此文件输入流并释放与流相关联的任何系统资源。 
如果该流具有相关联的信道,则该信道也被关闭。 

 public static void main(String[] args) throws IOException {
 
        String filepath = "D:\\abc.txt";
        File file = new File(filepath);
        FileInputStream fileInputStream = new FileInputStream(file);
        int read = 0 ;  
     //read变量是来判断文件是否已经读取到结尾,如果已经到结尾 read会等于-1,就会跳出循环
        while ((read = fileInputStream.read()) != -1)//每次读取1字节
        {
            System.out.print((char)read); //因为read是int型,要强转为char
        }
         fileInputStream.close();
}

在这里插入图片描述
在这里插入图片描述

  public static void main(String[] args) throws IOException {

        String filepath = "D:\\abc.txt";
        File file = new File(filepath);
        FileInputStream fileInputStream = new FileInputStream(file);
        byte[] bcf = new byte[8];
        int readLen = 0 ;  
     //readLen变量是来判断文件是否已经读取到结尾,如果已经到结尾 read会等于-1,就会跳出循环
        while ((readLen = fileInputStream.read(bcf)) != -1)
        {
            System.out.println(new String(bcf,0,readLen));
    // bcf表示要解码为字符的字节  0表示要解码的第一个字节的索引 ,readLen表示要解码的字节数
        }
        fileInputStream.close();
    }

在这里插入图片描述
在这里插入图片描述
因为上面的代码时每次读取8字节,即第一次读取a-h,第二次换行读取i

FileOutputStream类

文件输出流是用于将数据写入到输出流File或一个FileDescriptor 。
文件是否可用或可能被创建取决于底层平台。
特别是某些平台只允许一次只能打开一个文件来写入一个FileOutputStream (或其他文件写入对象)。 在这种情况下,如果所涉及的文件已经打开,则此类中的构造函数将失败。
FileOutputStream用于写入诸如图像数据的原始字节流。 对于写入字符流,请考虑使用FileWriter 。

FileOutputStream类构造方法

FileOutputStream(File file) 
创建文件输出流以写入由指定的 File对象表示的文件。  

FileOutputStream(File file, boolean append) 
创建文件输出流以写入由指定的File对象表示的文件。 
如果第二个参数是true ,则字节将被写入文件的末尾而不是开头。 
如果文件存在但是是一个目录而不是常规文件,不存在但不能创建,或者由于任何其他原因无法打开,
那么将抛出一个FileNotFoundException 。 


FileOutputStream(String name) 
创建文件输出流以指定的名称写入文件。
public static void main(String[] args) throws IOException {
        String filepath = "D:\\write.txt";
        FileOutputStream fileOutputStream = new FileOutputStream(filepath);
        System.out.println(fileOutputStream);

        FileOutputStream fileOutputStream1 = new FileOutputStream("D:\\write.txt");
        System.out.println(fileOutputStream);

        FileOutputStream fileOutputStream2 = new FileOutputStream(filepath,true);
        //true表示向该文件后追加数据
        System.out.println(fileOutputStream2);

    }

在这里插入图片描述

FileOutputStream类方法

write(int b)  
将指定的字节写入此文件输出流。  

write(byte[] b)
将 b.length字节从指定的字节数组写入此文件输出流。 

write(byte[] b, int off, int len)
从位于偏移量 off的指定字节数组写入 len字节到该文件输出流。 

close()
  关闭此文件输出流并释放与此流相关联的任何系统资源。 此文件输出流可能不再用于写入字节。 
如果该流具有相关联的信道,则该信道也被关闭。 

public static void main(String[] args) throws IOException {

        String filepath = "D:\\write.txt";
        FileOutputStream fileOutputStream = new FileOutputStream(filepath);

        fileOutputStream.write(97); //写入的时ascll码值 97就是a
        String str ="love";

        //将str转换成比特数组
        fileOutputStream.write(str.getBytes()); //全部写入

        String str1 = "you";
        fileOutputStream.write(str1.getBytes(),0,1); //写入1个字节

        //所以write.txt应该返回a+love+y = alovey
         fileOutputStream.close();

    }

在这里插入图片描述
和我们分析的一样

但是我们如果想多次添加 "alovey"字符串,是不是多次执行上面的代码就行了呢?
我们多次运行上面代码,发现结果还是这样,即不能在文件里原有的内容后面追加新的内容
在这里插入图片描述

此时,我们只要将上述代码创建FileOutputStream对象的代码修改一下即可

FileOutputStream fileOutputStream = new FileOutputStream(filepath);
改为
FileOutputStream fileOutputStream = new FileOutputStream(filepath,true);
表示可以在文件原有的内容后面追加新的内容

我们再次运行上述代码,发现果然可以在文件原有的内容后面追加新的内容。

在这里插入图片描述

FileReader类

阅读字符文件更容易。
该类的构造函数假定默认字符编码和默认字节缓冲区大小是适当的。
要自己指定这些值,请在FileInputStream上构造一个InputStreamReader。
FileReader是用于读取字符流。 要读取原始字节流,请考虑使用FileInputStream 。

FileReader类构造方法

FileReader(File file) 
创建一个新的 FileReader ,给出 File读取。  

FileReader(String fileName) 
创建一个新的 FileReader ,给定要读取的文件的名称。  
 public static void main(String[] args) throws IOException {

        String filepath = "D:\\text1.txt";
        FileReader fileReader = new FileReader(filepath);
        System.out.println(fileReader);

        FileReader fileReader1 = new FileReader("D:\\text1.txt");
        System.out.println(fileReader1);

    }

在这里插入图片描述

FileReader类方法

public int read()  读一个字符

public int read(char[] cbuf,int offset, int length)  将字符读入数组的一部分。 
cbuf - 目的缓冲区 
offset - 开始存储字符的偏移量 
length - 要读取的最大字符数 

close()
关闭流并释放与之相关联的任何系统资源。 一旦流已关闭,进一步的read(),ready(),mark(),
reset()或skip()调用将抛出IOException。 关闭以前关闭的流无效。 

 public static void main(String[] args) throws IOException {
       String filepath = "D:\\abc.txt";
        FileReader fileReader = new FileReader(filepath);
        int len = 0; //每次读一个字符
        while ((len = fileReader.read())!= -1){
            System.out.print((char)len);
        }
          fileReader.close();
    }

在这里插入图片描述

  public static void main(String[] args) throws IOException {
       String filepath = "D:\\abc.txt";
        FileReader fileReader = new FileReader(filepath);
        char ucb[] = new char[8];
        int readLen = 0; //每次读八个字符
        while ((readLen = fileReader.read(ucb))!= -1){
            System.out.println(new String(ucb,0,readLen));
        }
          fileReader.close();
    }

在这里插入图片描述

FileWriter类

方便读写字符文件。 该类的构造函数假定默认字符编码和默认字节缓冲区大小是可以接受的。 要自己指定这些值,请在FileOutputStream上构造一个OutputStreamWriter。
文件是否可用或可能被创建取决于底层平台。 特别是某些平台允许一次只能打开一个文件来写入一个FileWriter (或其他文件写入对象)。 在这种情况下,如果所涉及的文件已经打开,则此类中的构造函数将失败。

FileWriter是用于写入字符流。 要编写原始字节流,请考虑使用FileOutputStream 。

FileWriter类构造方法

FileWriter(File file) 
给一个File对象构造一个FileWriter对象。  

FileWriter(File file, boolean append) 
给一个File对象构造一个FileWriter对象。  

FileWriter(String fileName) 
构造一个给定文件名的FileWriter对象。  
 public static void main(String[] args) throws IOException {

        String filepath = "D:\\abc.txt";
        FileWriter fileWriter = new FileWriter(filepath);
        System.out.println(fileWriter);
        FileWriter fileWriter1 = new FileWriter("D:\\abc.txt");
        System.out.println(fileWriter1);
        FileWriter fileWriter2 = new FileWriter(filepath,true);
        System.out.println(fileWriter2);
    }

在这里插入图片描述

FileWriter类方法

write(int c)
写一个字符 

write(char[] cbuf,int off, int len)
写入字符数组的一部分。 
参数 
cbuf - 一个字符数组 
off - 开始读取字符的偏移量 
len - 要写入的 len数 


write(String str, int off,int len)
写一个字符串的一部分。 
参数 
s - 要写入的字符串 
off - 开始读取字符的偏移量 
len - 要写入的字符数 

public void close()
关闭流,先刷新。 一旦流已关闭,进一步的write()或flush()调用将导致抛出IOException。 
关闭以前关闭的流无效。 
public static void main(String[] args) throws IOException {
        String filepath = "D:\\abc.txt";
        FileWriter fileWriter = new FileWriter(filepath);
       fileWriter.write(97); //a的ascll码是97
       fileWriter.write("你好",0,1);//写入字符串一个字符
       fileWriter.write("好".toCharArray());//将字符串转成字符数组写入
       fileWriter.close();
    }

在这里插入图片描述

BufferedReader类

从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取。
可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途。

通常,由读取器做出的每个读取请求将引起对底层字符或字节流的相应读取请求。 因此,建议将BufferedReader包装在其read()操作可能简单的读取器上,例如FileReader和InputStreamReader。
例如, BufferedReader in= new BufferedReader(new FileReader(“foo.in”));
将缓冲指定文件的输入。 没有缓冲,每次调用read()或readLine()可能会导致从文件中读取字节,转换成字符,然后返回,这可能非常低效。

BufferedReader 类中,有属性Reader,即可以封装一个节点流
该节点流可以是任意的(只要是Reader子类)

BufferedReader类构造方法

BufferedReader(Reader in) 
创建使用默认大小的输入缓冲区的缓冲字符输入流。  

BufferedReader(Reader in, int sz) 
创建使用指定大小的输入缓冲区的缓冲字符输入流。  
  public static void main(String[] args) throws IOException {

        String filepath = "D:\\abc.txt";
    BufferedReader bufferedReader = new BufferedReader(new FileReader(filepath));
        System.out.println(bufferedReader);

  BufferedReader bufferedReader1 = new BufferedReader(new FileReader(filepath),5);
        System.out.println(bufferedReader1);
    }

在这里插入图片描述

BufferedReader类方法

read()
读一个字符 

readLine()
读一行文字。 一行被视为由换行符('\ n'),回车符('\ r')中的任何一个或随后的换行符终止。
结果:包含行的内容的字符串,不包括任何行终止字符,如果已达到流的末尾,则为null  

close()
关闭流并释放与之相关联的任何系统资源。 一旦流已关闭,进一步的read(),ready(),mark(),
reset()或skip()调用将抛出IOException。 关闭以前关闭的流无效。 
//按行读取
public static void main(String[] args) throws IOException {

   String filepath = "D:\\abc.txt";
   BufferedReader bufferedReader = new BufferedReader(new FileReader(filepath));
   String line;//如果已到达文章的末尾,则返回null
        while ((line = bufferedReader.readLine())!= null){
            System.out.println(line);
        }
        bufferedReader.close();
    }

按行读取,如果已到达文章的末尾,则返回null。
在这里插入图片描述
可以看到每次只读取abc.txt里的一行。一共读了3次
在这里插入图片描述
按字节读取与FileReader类似,这里不再赘述。

BufferedWriter类

将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入。
可以指定缓冲区大小,或者可以接受默认大小。 默认值足够大,可用于大多数用途。

提供了一个newLine()方法,它使用平台自己的系统属性line.separator定义的行分隔符概念。 并非所有平台都使用换行符(‘\ n’)来终止行。 因此,调用此方法来终止每个输出行,优选直接写入换行符。

一般来说,Writer将其输出立即发送到底层字符或字节流。 除非需要提示输出,否则建议将BufferedWriter包装在其write()操作可能很昂贵的Writer上,例如FileWriters和OutputStreamWriters。
例如, PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(“foo.out”)));
将缓冲PrintWriter的输出到文件。 没有缓冲,每次调用print()方法都会使字符转换为字节,然后立即写入文件,这可能非常低效。

BufferedWriter 类中,有属性Writer,即可以封装一个节点流
该节点流可以是任意的(只要是Writer子类)

BufferedWriter类构造方法

BufferedWriter(Writer out) 
创建使用默认大小的输出缓冲区的缓冲字符输出流。  

BufferedWriter(Writer out, int sz) 
创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。  
  public static void main(String[] args) throws IOException {

        String filepath = "D:\\abc.txt";
        FileWriter fileWriter = new FileWriter(filepath);
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
        System.out.println(bufferedWriter);

        BufferedWriter bufferedWriter1 = new BufferedWriter(fileWriter, 5);
        System.out.println(bufferedWriter1);

    }

在这里插入图片描述

BufferedWriter类方法

write(int c)
写一个字符 

write(char[] cbuf,int off,int len)
写入字符数组的一部分。 
通常,此方法将给定数组中的字符存储到此流的缓冲区中,
根据需要将缓冲区刷新到底层流。 然而,如果请求的长度至少与缓冲区一样大,
那么这个方法将刷新缓冲区,并将字符直接写入底层流。 
参数 
cbuf - 一个字符数组 
off - 开始读取字符的偏移量 
len - 要写入的 len数 

write(String s,int off,int len)
写一个字符串的一部分。 
如果len参数的值为负,则不会写入任何字符。 
参数 
s - 要写入的字符串 
off - 开始读取字符的偏移量 
len - 要写入的字符数 

newLine()
写一行行分隔符。 行分隔符字符串由系统属性line.separator定义,并不一定是单个换行符('\ n')字符

close()
关闭流,先刷新。 一旦流已关闭,进一步的write()或flush()调用将导致抛出IOException。 
关闭以前关闭的流无效。 
public static void main(String[] args) throws IOException {

        String filepath = "D:\\cba.txt";
        FileWriter fileWriter = new FileWriter(filepath);
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
        bufferedWriter.write(97);
        bufferedWriter.newLine(); //   等同于 bufferedWriter.write("\n");
        bufferedWriter.write("你好世界",0,4);
        bufferedWriter.write("\n");
        bufferedWriter.write("明天会更好".toCharArray());

        bufferedWriter.close();

    }

在这里插入图片描述

BufferedInputStream类

BufferedlnputStream是字节流,在创建BufferedInputStream时,会创建一个内部缓冲区数组.

BufferedInputStream类构造方法

BufferedInputStream(InputStream in) 
创建一个 BufferedInputStream并保存其参数,输入流 in ,供以后使用。  

BufferedInputStream(InputStream in, int size) 
创建 BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 in ,供以后使用。  
public static void main(String[] args) throws IOException {

        String filepath = "D:\\cba.txt";
        FileInputStream fileInputStream = new FileInputStream(filepath);
        BufferedInputStream bis = new BufferedInputStream(fileInputStream);
        System.out.println(bis);

        BufferedInputStream bis1 = new BufferedInputStream(fileInputStream,10);
        System.out.println(bis1);

    }

在这里插入图片描述

BufferedInputStream类方法

read()
read用法与 InputStream的大致相同。 

read(byte[] b,int off, int len)
从给定的偏移开始,将字节输入流中的字节读入指定的字节数组。 
该方法与 InputStream类对应的read方法的大致合同。 


close()
 关闭此输入流并释放与流相关联的任何系统资源。 一旦流已关闭,进一步的read(),available(),
  reset()或skip()调用将抛出IOException异常。 关闭以前关闭的流无效。 

public static void main(String[] args) throws IOException {

        String filepath = "D:\\cba.txt";
        FileInputStream fileInputStream = new FileInputStream(filepath);
        BufferedInputStream bis = new BufferedInputStream(fileInputStream);
        byte ucb[] = new byte[16];
        int readLen = 0;
        while ((readLen = bis.read(ucb))!= -1){
            System.out.println(new String(ucb,0,readLen));
        }
      bis.close();
    }

在这里插入图片描述

序列化与反序列化

1.序列化就是在保存数据时,保存数据的值和数据类型
2.反序列化就是在恢复数据时,恢复数据的值和数据类型
3.需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该
类必须实现如下两个接口之一:

Serializable1/这是一个标记接口,没有方法
Externalizable //该接口有方法需要实现,因此我们一般实现上面的 Serializable接口

ObjectOutputStream提供序列化功能
ObjectInputStream提供反序列化功能

ObjectOutputStream提供序列化功能
 public static void main(String[] args) {
        String pathname = "D:\\obj.txt";
        ObjectOutputStream oss = null;
        try {
            oss = new ObjectOutputStream(new FileOutputStream(pathname));
            oss.writeInt(100); //int -- Integer 自动装箱
            oss.writeBoolean(true);//boolean -- Boolean
            oss.writeChar('a');//char -- Character
            oss.writeUTF("加油");
            oss.writeObject(new Dog("xiao",18));//写入dog对象

        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                oss.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}


//dog类必须实现Serializable才能序列化
class Dog implements Serializable {
    private String name;
    private int age;


    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

    public String getName() {
        return name;
    }
}

在这里插入图片描述

ObjectInputStream提供反序列化功能

 public static void main(String[] args) {
        String pathname = "D:\\obj.txt";
        try {
   ObjectInputStream ois = new ObjectInputStream(new FileInputStream(pathname));
            System.out.println( ois.readInt());
            System.out.println( ois.readBoolean());
            System.out.println( ois.readChar());
            System.out.println(ois.readUTF());
            Object dog = ois.readObject();
            System.out.println(dog.getClass());
            System.out.println(dog);
            Dog dog1 =(Dog) dog;
            System.out.println(dog1.getName());
            ois.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

在这里插入图片描述

注意事项和细节说明
1)读写顺序要一致
2)要求序列化或反序列化对象,需要实现Serializable
3)序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性
4)序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
5)序列化对象时,要求里面属性的类型也需要实现序列化接口
6)序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化

转换流

转换流-InputStreamReader和 OutputStreamWriter

当文件出现乱码时,就可以使用转换流
1 .InputStreamReader: Reader的子类,可以将InputStream(字节流)包装成(转换)Reader(字符流)
2.OutputStreamWriter: Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)
3.当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题,所以建议将字节流转换成字符流
4.可以在使用时指定编码格式(比如utf-8, gbk , gb2312, ISO8859-1等)

OutputStreamWriter类

OutputStreamWriter(OutputStream out,String charsetName)
创建一个使用命名字符集的OutputStreamWriter。 

参数 
out - 一个OutputStream 
charsetName - 支持的名称charset 


OutputStreamWriter(OutputStream out)
创建一个使用默认字符编码的OutputStreamWriter。 默认是utf8编码
 演示OutputStreamWriter 使用
 * 把FileOutputStream字节流,转成字符流OutputStreamWriter
 * 指定处理的编码gbk/utf-8/utf8

  public static void main(String[] args) throws IOException {
           String filepath = "D:\\h.txt";
           FileOutputStream fileOutputStream = new FileOutputStream(filepath);
           OutputStreamWriter osi = new OutputStreamWriter(fileOutputStream); 
           osi.write("hello世界");
           osi.close();
    }

我们打开h.txt文件
OutputStreamWriter(OutputStream out)
可以看到当创建OutputStreamWriter对象不指定编码时, 默认是utf8编码
在这里插入图片描述

  public static void main(String[] args) throws IOException {
           String filepath = "D:\\h.txt";
           String charSet = "GBK"; //按照gbk编码,也就是ANSI编码
           FileOutputStream fileOutputStream = new FileOutputStream(filepath);
     OutputStreamWriter osi = new OutputStreamWriter(fileOutputStream,charSet);
           osi.write("hello世界");
           osi.close();
    }

我们打开h.txt文件
OutputStreamWriter(OutputStream out,String charsetName)
可以看到当创建OutputStreamWriter对象指定gbk编码时, 打开就是ANSI编码

在这里插入图片描述

InputStreamReader 类

InputStreamReader(InputStream in,String charsetName)
创建一个使用命名字符集的InputStreamReader。 

参数 
in - 一个InputStream 
charsetName -的名字支持charset 

InputStreamReader(InputStream in)
创建一个使用默认字符集的InputStreamReader。 
将字节流FileInputStream转换成字符流InputStreamReader
public static void main(String[] args) throws IOException {
         String filepath = "D:\\h.txt";
        FileInputStream fileInputStream = new FileInputStream(filepath);
        InputStreamReader isr = new InputStreamReader(fileInputStream,"utf-8");
        //2.把InputStreamReader传入BufferedReader来读取
        BufferedReader bf = new BufferedReader(isr);
        System.out.println(bf.readLine());
        bf.close();
        
    }

在这里插入图片描述
可以看到我们用utf8编码来读取h.txt(gbk编码),会出现乱码。
在这里插入图片描述

public static void main(String[] args) throws IOException {
         String filepath = "D:\\h.txt";
        FileInputStream fileInputStream = new FileInputStream(filepath);
        InputStreamReader isr = new InputStreamReader(fileInputStream,"gbk");
        //2.把InputStreamReader传入BufferedReader来读取
        BufferedReader bf = new BufferedReader(isr);
        System.out.println(bf.readLine());
        bf.close();

    }

可以看到我们用gbk编码来读取h.txt(gbk编码),就不会出现问题。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值