Java 文件与 I/O
文件
File概述
我们知道,程序运行过程的数据都是临时存放在内存中,程序运行完成后,数据将会从内存从清除。
如果想要持久化存储程序运行数据,可以将这些数据持久化到文件中,为了达到该目的,就需要通过
java中的相关类来完成文件相关的操作。
java.io.File类是文件和目录的抽象表示形式。java把磁盘上的文件或目录封装为一个File类,我们可
以通过File类对文件可文件夹进行操作。
File类可以完成如下功能
- 创建目录/文件
- 删除目录/文件
- 获取目录/文件
- 判断目录/文件是否存在
- 获取文件大小
- 目录遍历
代码演示说明
1 | public class FileTest { |
输出结果
1 | fileName: max.sql |
File类的构造方法
File(File parent, String child)根据父路径与子路径获取文件或目录,父路径为File类,子路径为字符串File(File parent, String child)根据给定的文件路径获取文件或目录File(File parent, String child)根据父路径与子路径获取文件或目录,父路径、子路径都为字符串File(URI uri)根据网络url获取文件
代码演示说明
File(File parent, String child)
1 | public class FileConstructorTest { |
File(URI uri)
1 | public class FileConstructorTest { |
File类的静态成员变量
public static String pathSeparator当前系统环境变量路径配置分隔符,返回值为字符串public static char pathSeparatorChar当前系统环境变量路径配置分隔符,返回值为charpublic static char separatorChar当前系统文件路径分隔符,返回只为charpublic static String separator当前系统文件路径分隔符,返回只为字符串
代码演示说明
1 | public class FileSeparatorTest { |
文件信息获取
public String getAbsolutePath()获取文件的绝对路径字符串public String getName()获取文件名称public String length()获取文件的长度
文件属性判断
public boolean exists()判断文件是否存在public boolean isFile()判断文件是否一个标准文件public boolean isDirectory()判断文件是否是一个目录
文件创建与删除
public boolean createNewFile()当且仅当该名称的文件不存在时,创建一个新的空文件public boolean mkdir()创建一级目录public boolean mkdirs()创建多级目录public boolean delete()删除文件或目录
文件目录遍历
public String[] list()返回一个字符串数组,表示该目录中的所有子文件和目录public File[] listFiles()返回一个File数组,表示该目录中的所有子文件和目录
代码演示说明
1 | public class FileListTest { |
文件过滤器
public File[] listFiles(FileFilter filter)使用FileFilter进行文件过滤public File[] listFiles(FilenameFilter filter)使用FilenameFilter进行文件过滤
代码演示说明
FileFilter
1 | public class MyFileFilter implements FileFilter { |
编写测试类
1 | public class MyFileFilterTest { |
FilenameFilter
1 | public class MyFilenameFilter implements FilenameFilter { |
编写测试类
1 | public class MyFilenameFilterTest { |
I/O流
IO概述
前面我们提到过,我们可以将程序运行过程中的数据,持久保存到磁盘文件中,那么这个数据写入写出到文件的过程,就需要通过Java中的IO技术来实现。
根据数据的流向,可以分为输入流和输出流
- 输入流:把数据从
其他设备读取到内存中的流 - 输出流:把数据从
内存中写出到其他设备的流
根据数据的分类,可以分为字节流和字符流
IO流顶级父类
| 输入流 | 输出流 | |
|---|---|---|
| 字节流 | InputStream | OutputStream |
| 字符流 | Reader | Writer |
字节输出流
OutputStream为抽象类。是表示输出字节流的所有类的超类
OutputStream常用方法
public void close()关闭此输出流并释放与此流有关的所有系统资源public void flush()刷新此输出流并强制写出所有缓冲的输出字节public void write(byte[] b)将b.length个字节从指定的 byte 数组写入此输出流public void write(byte[] b, int off, int len)将b.length个字节从指定的 byte 数组写入此输出流
常用子类
- FileOutputStream 文件输出流,用于将数据写入
File的输出流
代码演示说明
1 | public class OutputstreamTest { |
字节输入流
InputStream为抽象类。是表示输入字节流的所有类的超类
InputStream常用方法
public void close()关闭此输出流并释放与此流有关的所有系统资源public abstract int read()输入流中读取数据的下一个字节public int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中public int read(byte[] b, int off, int len)将输入流中最多len个数据字节读入 byte 数组
常用子类
- FileInputStream 文件输入流,用于从文件系统中的某个文件中获得输入字节
代码演示说明
1 | public class InputStreamTest { |
字节流读取中文乱码问题
当读取的文本中,包含中文时,在某些情况下,可能会出现中文乱码
已知
- GBK编码下,一个中文=2个字节
- UTF-8编码下,一个中文=3个字节
代码演示说明
1 | public class InputStreamTest { |
字符输入流
为了解决字节流读取中文乱码的问题,java中通过字符流来解决该问题,字节流读取的单位是字节,字符流读取的单位是字符
Reader是用于读取字符流的抽象类
Reader常用方法
public abstract void close()关闭该流并释放与之关联的所有资源public int read()读取单个字符public int read(char[] cbuf)将字符读入数组public abstract int read(char[] cbuf, int off, int len)将字符读入数组的某一部分
常用子类
- FileReader 用来读取字符文件的字符流
代码演示说明
1 | public class FileReaderTest { |
字符输出流
Writer是用于写入字符流的抽象类
Writer常用方法
public abstract void close()关闭此流,但要先刷新它public void write(String str)写入字符串public abstract int write(char[] cbuf, int off, int len)写入字符数组的某一部分
常用子类
- FileWriter 用来写入字符文件的字符流
代码演示说明
1 | public class FileWriterTest { |
缓冲流
缓冲流又叫高效流,是对基本操作流的增强,按照数据分类分为
- 字节缓冲流:
BufferedInputStream、BufferedOutputStream - 字符缓冲流:
BufferedReader、BufferedWriter
字节缓冲流
构造方法
BufferedInputStream(InputStream in)创建一个新的缓冲输入流BufferedOutStream(OutStream out)创建一个新的缓冲输出流
代码演示说明
BufferedInputStream
1 | public class BufferedInputStreamTest { |
BufferedOutStream
1 | public class BufferedOutStreamTest { |
字符缓冲流
BufferedReader(Reader in)创建一个使用默认大小输入缓冲区的缓冲字符输入流BufferedWriter(Writer out)创建一个使用默认大小输出缓冲区的缓冲字符输出流
代码演示说明
BufferedReader
1 | public class BrTest { |
BufferedWriter
1 | public class BwTest { |
转换流
在有些时候,读取的文件字符编码与程序所在环境的字符编码不同,这将导致读取到内存中的内容出现乱码。
因此,转换流可以在操作文件的同时进行字符编码的转换
转换流分类
InputStreamReader字节流通向字符流的桥梁,它使用指定的charset读取字节并将其解码为字符OutputStreamWriter字节流通向字符流的桥梁,可使用指定的charset将要写入流中的字符编码成字节
代码演示说明
InputStreamReader
1 | public class InputStreamReaderTest { |
OutputStreamWriter
1 | public class OutputStreamWriterTest { |
随机文件读写
RandomAccessFile是Java输入/输出流体系中功能最丰富的文件内容访问类,既可以读取文件内容,也可以向文件输出数据。与普通的输入/输出流不同的是,RandomAccessFile对象包含一个记录指针,用以标识当前读写处的位置,可以跳到文件任意位置读写数据。
RandomAccessFile类在创建对象时,除了指定文件本身,还需要指定一个mode参数,该参数指定RandomAccessFile的访问模式,该参数有如下四个值:
- r:以只读方式打开指定文件。如果试图对该RandomAccessFile指定的文件执行写入方法则会抛出IOException
- rw:以读取、写入方式打开指定文件。如果该文件不存在,则尝试创建文件
- rws:以读取、写入方式打开指定文件。相对于rw模式,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备,默认情形下(rw模式下),是使用buffer的,只有cache满的或者使用RandomAccessFile.close()关闭流的时候儿才真正的写到文件
- rwd:与rws类似,只是仅对文件的内容同步更新到磁盘,而不修改文件的元数据
代码演示说明
文件随机读取
1 | public class RandomFileTest { |