文件及IO流

File类

1、来自于java.io包
2、是文件和目录路径名的抽象表示
3、文件和目录可以通过File封装为对象
4、对于File而言,封装的不是真正存在的文件,仅仅是封装一个路径,路径不一定存在,将来可以通过具体的方法,把这个路径封装的内容转换成具体存在。
5、路径:
​ 用于描述文件或者文件夹所在位置的字符串
​ 路径分类:
​ 相对路径:是一个简化路径,相对于某个路径而言
​ 绝对路径:是一个完整路径,从盘符开始

File类的构造方法

        File f = new File("D:\\Java");File f1 = new File("D:\\Java\\test");File f2 = new File(f,"\\test");System.out.println(f);System.out.println(f1);System.out.println(f2);

输出结果为:

File类的创建方法

1、creatNewFile():创建当前File对象所描述的路径下的文件
2、mkdir():创建当前File对象所描述的文件夹(如果路径中包含不存在的父级路径,那么不会自动创建父级路径)路径中不能包含不存在的文件夹,只能创建最后一级
3、mkdirs():创建当前FIle对象所描述的文件夹(如果父级路径不存,自动创建父级路径)

        File f3 = new File("D:\\Java\\test\\file.txt");f3.createNewFile();//创建当前路径下的文件(记得写后缀名)File f4 = new File("D:\\Java\\test\\file");f4.mkdir();//创建当前目录下的文件夹File f5 = new File("D:\\Java\\test\\mkdirs\\file");f5.mkdirs();//创建当前目录下的文件夹,若无父级目录,则自动创建父级目录

代码执行结果:

File类型的删除方法

1、delete():删除调用者所描述的文件或者文件夹,文件存在/文件夹为空才能删除成功
2、如果删除文件夹,只能删除空文件夹(里面不能有任何内容,包括空文件夹),删除文件的时候,文件有没有内容不影响
3、delete方法不走回收站

        f5.delete();f4.delete();f3.delete();

执行结果:

File类型的判断方法

1、exists():判断当前调用者描述的路径是否存在,存在返回true
2、isFile():判断当前调用者是否是文件
3、isDirectory():判断当前调用者是否是文件夹
还是接之前的代码

        boolean b5 = f5.exists();boolean b4 = f4.exists();boolean b3 = f3.exists();boolean b1 = f1.exists();//D:\Java\testboolean b = f.exists();//D:\JavaSystem.out.println(b5);System.out.println(b4);System.out.println(b3);System.out.println(b1);System.out.println(b);

判断结果:3

File类型获取功能

1、getAbsolutePath():获取File对象的绝对路径,与路径是否存在无关
2、getPath():获取当前File中封装的路径
3、getName():获取当前File对象描述的文件或文件夹的名称,仅仅获取路径的最后一级
4、list():获取当前文件夹下所有的文件和文件夹名称,到一个字符串数组中(只获取当前文件夹子一级的内容,子一级文件夹中的内容不会获取)返回String[]类型数组
5、listFiles():获取当前文件夹中所有的文件和文件夹的File对象,当一个File数组中,特点和list相同,只能获取当前文件夹内

附上完整代码:

  File f = new File("D:\\Java");File f1 = new File("D:\\Java\\test");File f2 = new File(f,"\\test");System.out.println(f);System.out.println(f1);System.out.println(f2);File f3 = new File("D:\\Java\\test\\file.txt");f3.createNewFile();//创建当前路径下的文件(记得写后缀名)File f4 = new File("D:\\Java\\test\\file");f4.mkdir();//创建当前目录下的文件夹File f5 = new File("D:\\Java\\test\\mkdirs\\file");f5.mkdirs();//创建当前目录下的文件夹,若无父级目录,则自动创建父级目录f5.delete();f4.delete();f3.delete();boolean b5 = f5.exists();boolean b4 = f4.exists();boolean b3 = f3.exists();boolean b1 = f1.exists();//D:\Java\testboolean b = f.exists();//D:\JavaSystem.out.println(b5);System.out.println(b4);System.out.println(b3);System.out.println(b1);System.out.println(b);File f6 = new File("\\java");String p6 = f6.getAbsolutePath();String p5 = f5.getAbsolutePath();//路径不存在,但依然能获取String p1 = f1.getAbsolutePath();System.out.println(p6);System.out.println(p5);System.out.println(p1);String pp6 = f6.getPath();String pp5 = f5.getPath();//获取当前封装路径String pp1 = f1.getPath();System.out.println(pp5);System.out.println(pp1);System.out.println(pp6);String[] list = f6.list();//获取当前文件夹下所有的文件和文件夹名称,存到一个字符串数组中for (String s : list) {System.out.print(s+"\t");}System.out.println();File[] files = f6.listFiles();//获取当前文件夹中所有的文件和文件夹的File对象for (File file : files) {System.out.print(file+"\t");}

IO流

字节流

1、字节流的抽象基类:以字节读取数据
​ InputStream:字节输入流的所有类的超类
​ OutputStream:字节输出流的所有类的超类
2、根据交互的设备不同,有不同的子类

FileInputStream:文件字节输入流

1、是InputStream的子类,用于和磁盘上的文件进行交互
2、该类型不仅可以一次读取一个字节,也可以一次读取多个字节,不仅可以读取文本文件,也可以读取视频、音频、图片等非纯文本文件,一切的数据在计算机中都是以字节为单位存储的
3、构造方法:​
 FileInputStream(File f):将一个File对象所表示的文件封装到一个字节输入流中,未来都是以字节的方式读取文件中的内容
​ FileInputStream(String path):将一个字符串表示的文件文件路径封装到一个字节输入流中,未来都是以字节的方式读取文件的内容
​ 注意事项:
​  无论使用哪个构造方法,都只能封装文件的路径(封装文件夹的路径没有任何意义,文件夹本身没有任何数据,所以不能使用流对象读取)
4、读取文件的方法:
 ​int read():从当前输入流中,读取并返回一个字节,返回值为int类型,表示读取到的字节对应的整数信息,如果返回-1表示读取到文件末尾了
 ​int read(byte[] arr):读取数组大小个数的字节信息,存储到数组中,返回值结果为int,表示本次读取到的字节的个数,如果读取到-1,表示读取完毕
 ​void close():关闭流对象

        File file = new File("D:\\Java\\test\\test.txt");FileInputStream fis = new FileInputStream(file);//文件字节输入流//FileInputStream fis = new FileInputStream("D:\\Java\\test\\test.txt");int read;while ((read=fis.read())!=-1){System.out.println(read);}fis.close();

在txt文件中写入“114514”后读取,输出如下:

FileOutputStream:文件字节输出流

1、可以将字节数据写出到指定文件中
2、构造方法:
​  FileOutputStream(File f):将file对象封装为字节输出流对象
​  FileOutputStream(String path):将path描述的路径封装成字节输出流对象
​  FileOutputStream(String path,boolean append):如果第二个参数为true(拼接),这次写出的内容就直接与原文件中的内容进行拼接,不写第二个参数或者为false(新建/覆盖)的时候,每次都是相当于新建了一个文件,写入内容,原文件中的内容不存在
3、字节流写出数据的方式:
​  write(int b):将指定的字节写出到目标文件中,一次写出一个字节信息
​  *输出的是单字节信息,b=‘a’和b=97是一样的
​  *write(‘暴’.getBytes());如果想要输出一个字符串可以将字符串转为字符数组然后输出,
​  write(byte[] b):一次像一个数组的内容写入到指定文件中
 *byte[] b = {65,66,67,68}
​  write(byte[] b,int offset,int len):将len个字节内容,从指定字节数组b中的off索引开始,写出到文件中

文件复制

FileInputStream(File f):用于把想要复制的文件封装到字节输入流中
FileOutputStream(File f):把输入流中的文件输出到指定文件中

         FileInputStream fis = new FileInputStream("D:\\Java\\test\\test.txt");FileOutputStream fos = new FileOutputStream("D:\\Java\\test\\1.txt");int write;while ((write=fis.read())!=-1){fos.write(write);}/*写到这里时发现,若存在同一fis对象的多个read()方法,则只有第一个生效,猜测是复制文件时,先把文件存入到fis对象中,当触发read()函数时会释放fis对象中的文件*///把目标文件内容输出出来FileInputStream fis1 = new FileInputStream("D:\\Java\\test\\test.txt");int read;while ((read=fis1.read())!=-1){System.out.println(read);}//先关输出流,再关输入流fos.close();fis.close();

高效字节缓冲流

1、BufferedOutputStream:是OutputStream的子类,表示高效字节缓冲输出流,代码底层其实是一个8182(1028*8)个字节的数组,提供了数组缓冲区,写出的时候也是,不直接写到磁盘上,而是写出到缓冲数组中,直到数组写满了或者调用flush方法(刷新),将内容刷新到目标文件中
2、BufferedInputStream:是InputStream的子类,高效缓冲输入流,代码低层也是一个8192个字节的数组,每次调用read()方法 一次读取8192个字节的内容,放入到缓冲数组中,但是每次调用read方法只读取一个,此时就是将缓冲数组中的内容,给你一个,直到你读取够8192个字节时,再次访问磁盘读取8192个字节信息
3、这两个流是包装类型,本身不具备任何读写功能,需要作用于某个流的基础上,对其进行增强,例如FileInputStream和FileOutputStream,原本效率比较低,加强之后效率就高
4、构造方法:
​  BufferedOutputStream(OutputStream):创建字节缓冲输出流对象
​  BufferedIutputStream(IutputStream):创建字节缓冲输入流对象

下面是使用高效字节缓冲流复制文件:

//高效字节缓冲流BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\Java\\test\\meeting.mp4"));//准备复制的文件路径BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\Java\\test\\1.mp4"));//准备拷贝的目标文件路径,若目标文件已存在,则会覆盖int write;while ((write=bis.read())!=-1){bos.write(write);}bos.flush();//调用flush()函数手动刷新,将缓存区中的内容刷新到目标文件夹中。bos.close();bis.close();

IO流如何保证流对象关闭

若忘记关闭流对象,或者代码出现问题没能执行关闭流对象时,可能会导致资源泄露问题,调用过的资源一直存在不被释放,会占用资源,也可能导致依赖这个资源的后续代码无法执行,甚至可能导致程序崩溃。
使用finally可以轻松解决这个问题,格式如下:

try{流对象的使用
}catch{ }finally{流对象的关闭
}

字符流

字符流写入数据:

1、字符输出流顶层父类Writer:
​  用于写出字符流的抽象父类
​  FileWriter:用于将字符写出到文件的常用子类
2、构造方法:
​  FileWriter(File f):根据File描述的路径创建一个字符输出流对象
​  FileWriter(String path):根据描述的路径,创建一个字符输出流对象
​  FileWriter(String path,boolean append):第二个参数表示拼接或覆盖
3、输出的方法:
​  write(int c):写出一个字符
​  write(char[] c):写出一个字符数组
​  write(char[] c,int off,in len):写出字符数组的一部分,从off开始len个
​  write(String str):写出一个字符串
​  write(String str,int off,int len):写出字符串的一部分,从off开始len个

        FileWriter fw = new FileWriter(new File("D:\\Java\\test\\1.txt"));fw.write("你好,世界!");fw.write("hello world!");fw.write("114514");fw.close();

字符流读取数据:

1、字符输入流Reader
​  用于读取字符的抽象父类
​  FileReader:用于读取字符流的常用子类
2、FileReader的构造方法:
​  FileReader(File f):使用File对象描述的路径创建一个字符输入流对象
​  FileReader(String path):使用path描述的路径创建一个字符输入流对象
3、读取的方法:
​  int read():一次读取一个字符,返回值int类型,返回的就是这个字符在编码表中对应的整数,如果读取到-1表示到了文件末尾
​  int read(char[] arr):一次读取字符数组大小个字符,将文件中读取的字符放到参数数组中,返回值结果是int,表示读取到的字符个数,如果读取到了-1表示到了文件末尾

读取txt文件中的格式:
第一种方法:

     FileReader fr = new FileReader("D:\\Java\\test\\1.txt");String line="";//可以将字符存在line中int len;while ((len=fr.read())!=-1){line+=(char)len;//将字节型转换成字符型System.out.print((char) len);}fr.close();

第二种方法:

         FileReader fr = new FileReader("D:\\Java\\test\\1.txt");int len;char[] c=new char[1000];//将字符存储到定长的char数组中while ((len=fr.read(c))!=-1){System.out.println(new String(c,0,len));}fr.close();

高效缓冲字符流特有的方法

*其他方法见高效字节缓冲流
*高效的原理:减少了IO(输入输出)的次数
1、BufferedReader:
​  readLine():可以从输入流中一次读取一行的数据,返回一个字符串,如果到达文件末尾,则返回null
2、BufferedWriter:
​  newLine():作用是提供一个换行符

        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\Java\\test\\bw.txt"));BufferedReader br = new BufferedReader(new FileReader("D:\\Java\\test\\br.txt"));bw.write("114514"+"\n");bw.write("helloworld");bw.newLine();bw.write("你好,世界!"+"\n");String str = "";while ((str=br.readLine())!=null){System.out.println(str);}bw.close();br.close();

转换流

1、编码表:
​  GBK:中文占两个字节,英文占一个字节
​  UTF-8:中文占三个字节,英文占一个字节
2、转换流作用:针对于不同编码集的文件,有正确的读写过程
3、OutputStreamWriter:字符流到字节流的桥梁,可以指定编码形式
 构造方法 :OutputStreamWriter(OutputStream os,String charsetName)
​  创建一个转换流对象,可以将接收到的字符,通过指定的编码表charsetName,编码字节信息在通过指定的字节流os,将字节信息输出
​  使用方法:直接使用Writer类中的方法,该类是Writer的子类
4、InputStreamReader:字节流到字符流的桥梁,可以指定编码形式
 构造方法:InputStreamReader(InputStream is,String charsetName);
​  创建一个转换流对象,可以使用is这个字节流,从磁盘中读取字节信息,通过指定的编码表,将字节信息转换为对应的字符信息,返回给调用者
​  该类是Reader的子类,直接使用Reader的方法即可

以gbk编码表为例,中文占两个字节,英文占一个字节,当读取utf-8格式的txt文件时会出现乱码

 InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\Java\\test\\1.txt"),"gbk");int read;while ((read=isr.read())!=-1){System.out.print((char) read);}


而如果使用转换流将其用gbk编码格式写入后再读取,则不会出现乱码情况,即保证读写时使用的编码格式相同即可。

        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\Java\\test\\2.txt"),"gbk");osw.write("114514"+"\n");osw.write("一一四五一四"+"\n");osw.write("AADEAD"+"\n");osw.close();

对象流

对象序列化

对象流

1、对象流:将一个对象写出到文件中(序列化),将文件中的对象读取(反序列化)
2、序列化:就是将对象写入到文件的过程
3、反序列化:将对象和对象的内容从文件中获取到
4、对象:表示任意对象,Object的子类,都可以读写
序列化的类需要接口serialVersion

以Person类为例:

import java.io.Serializable;public class Person implements Serializable {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

对象输出流

1、ObjectOutputStream:对象输出流
​  功能:将对象写入到文件中
2、构造方法:
​  ObjectOutputStream(OutputStream o):需要绑定一个写出的位置,比如向文件中写出
3、常用方法:
​  writeObject(Object o):向目标位置写出一个对象
4、注意事项:
​  写出的对象,必须实现Serializable序列化接口,如果没有实现接口,就会报错
5、对象写出到目标文件中,内容无法人为阅读,因为计算机将对象转换成了字节信息存储,只有计算机能够读懂,当反序列化的时候,能够将对象成功读取

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\Java\\test\\Output.txt"));oos.writeObject(new Person("珂朵莉",15));oos.writeObject(new Person("577",17));oos.writeObject(new Person("Abigail",19));oos.close();

对象输入流

1、ObjectInputSteam:对象输入流,是InputStream的子类
2、功能:将对象从文件中读取
3、构造方法:
​  ObjectInputStream(InputStream in):从指定的某个流中读取
4、常用方法:
​  readObject():将对象从文件中读取出来,每次读取一个对象,返回值类型Object类型,如果文件中没有对象还要继续读取,就会抛出异常

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\Java\\test\\Output.txt"));Person p;while ((p=(Person) ois.readObject())!=null){System.out.println(p.getName()+":"+p.getAge()+"岁");}ois.close();

运行后会出现异常,这里是正常现象,不影响代码运行,若不想看到红色提示可以用try…catch来捕获while函数的异常

序列号serialVersionUID和transient关键字

1、类每次被编译成.class文件的时候,都会有一个版本号long类型的数字
2、类有任何改动,都会重新编译.class文件,生成一个新的版本
3、两次的数字如果不相等,进行对象序列化的时候,会记录class文件的版本号long数字,反序列化的时候,会检测当前.class文件的版本号和序列化时是否一致,如果不一致就会报错,无效的类异常InvalidClassException

4、解决方案:
​  手动添加一个成员序列号,序列号是一个固定的值,不管改不改代码,序列号都是一致的,当我们认为类中的内容改动比较大,就可以去修改序列号,此时在这之前存储的对象都不能使用了
​  private static final long serialVersionUID = 1l;
*相当于手动添加了版本号

private static final long serialVersionUID = 10000;

5、transient关键字:
 如果一个对象中的成员变量值,不希望跟随序列化被保存,就可以使用transient关键字来修饰,修饰之后,该成员变量的值,就不会被序列化,不会写出到文件中。
*transient修饰的内容,不会写出到目标文件中,相当于不参与序列化
比如把类中的成员变量age用transient修饰:

Java基础(三)IO流和对象流相关推荐

  1. java基础三--IO流(1)

    2019独角兽企业重金招聘Python工程师标准>>> 概述: 1.IO流:即Input Output的缩写. 2.特点: 1)IO流用来处理设备间的数据传输. 2)Java对数据的 ...

  2. Java基础之IO流操作

    第14章 File类与IO流 主要内容 File类 字节流 字符流 文件流 缓冲流 转换流 数据流 对象流 打印流 Scanner与System与IO流 教学目标 使用File类对象表示文件或目录 能 ...

  3. 【Java基础】· IO流习题详解

    写在前面 Hello大家好, 我是[麟-小白],一位软件工程专业的学生,喜好计算机知识.希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误或不足之处,请多多指正!谢谢大家!!! ...

  4. Java基础学习—— IO流

    Java基础学习-- IO流 1 文件 1.1 文件的创建 1.2 文件常用的方法 2 IO流 2.1 FileInputStream 2.2 FileOutputStream 2.3 文件的拷贝 2 ...

  5. 让你的数据和对象有源有出路,一文打尽,Java常用IO流处理流(处理字节流文件流)缓冲流、转换流、对象流等

    文章目录 缓冲流 转换流 标准输入输出流 打印流 数据流 对象流 随机存取文件流 Java NIO 缓冲流 为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个 ...

  6. 2020.8.4课堂笔记(IO 缓冲流,对象流)

    课前复习: 1.什么是io流,如何分类 流向: 输入:InputStream,Reader 输出:OutputStream,Writer 按读取的单元: 字节流:InputStream,OutputS ...

  7. Java基础知识运用,用对象,线程,Java窗口画出太阳系

    一个项目让你搞懂对象:Java基础知识运用,用对象,线程,GUI画出太阳系 一.需求分析: 用java基础知识画出太阳系八大行星的运行轨迹图,要求:运行轨迹图是动态图片,画出运行轨迹,画出地月系(不需 ...

  8. Java学习笔记(7)——Java基础之IO多线程网络思维导图

    Java面向对象学习笔记之:包括IO(字节流,字符流,节点流,处理流).线程(线程创建,线程控制,线程同步).网络(TCP Scoket,  UDP Scoket)(全屏观看Java学习笔记(7)-- ...

  9. .dat文件写入byte类型数组_文件字节流、文件字符流、缓冲字节流、缓冲字符流字节数组流、数据流、转换流、对象流...

    一.实操名称: 描述如下流的基本作用:文件字节流.文件字符流.缓冲字节流.缓冲字符流字节数组流.数据流.转换流.对象流二.描述1.文件字节流:包括:FileInputStream,FileOutput ...

  10. Java基础之IO模型

    Java基础之IO模型 I/O 常见的IO模型 Java中3种常见的IO模型 BIO(Blocking I/O) NIO(Non-blocking/New I/O) AIO(Asynchronous ...

最新文章

  1. (转)Invoke and BeginInvoke
  2. android之descendantFocusability用法简析
  3. 香帅的北大金融学课笔记12 -- 资产估值
  4. 简单三个数比较大小 “?!”的用法
  5. mysql 8.0.16修改root密码_mysql 8.0.16 winx64及Linux修改root用户密码 的方法
  6. Linux内核机器ID,linux-如何强制内核重新读取/重新初始化PCI设备ID?
  7. java 调用window程序_Windows下Java调用可执行文件代码实例
  8. PyTorch 1.0 中文官方教程:基于注意力机制的 seq2seq 神经网络翻译
  9. 【Vue学习】—Vue UI组件库(二十八)
  10. Unity Bound
  11. Json时间格式转换
  12. 装甲逆袭-玩家碰撞处理
  13. 计算机c盘是内存还是外存,rom是内存还是外存?
  14. 链接标签a去掉下划线
  15. 令人吐血的女大学生平安信.
  16. fread函数详解和fwrite函数详解
  17. Javascript脚本运行的方式(js写在页面什么地方)
  18. 美容店信息管理系统与小程序设计与实现
  19. XILINX FPGA数字信号处理——13、信号同步原理实现
  20. Python中的链表和数组如何区分?

热门文章

  1. 软件工程复习知识点汇总(2)
  2. From Fidelity to Perceptual Quality: A Semi-Supervised Approach for Low-Light Image Enhancement
  3. win10内置录音机无法录制网页视频声音
  4. sybase 快速删除大数据库的手顺方法
  5. Latex书籍模板分享
  6. 教你创建电脑、手机同步的markdown云笔记--力扣刷题力荐!
  7. xshell连接不上虚拟机Linux
  8. Eclipse官网下载
  9. 微软新Logo四色代表什么?Win8/Office/Xbox等
  10. Linux中不同MTD设备分区,Linux MTD设备总结