Java文件操作和IO
认识文件
侠义文件说指存储在硬盘中的文件,具有明确的存储路径和格式。这类的文件通常以二进制(用文本打开是乱码)或文本的形式存在。文件除了包含书局除外还有一些信息,如文件名,创建时间等不作为文件的数据存在,我们称这部分信息为元信息。
广义文件涵盖所有形式的数据逻辑集合,不依赖物理存储介质,可能存在于网络、内存或虚拟环境中。其核心特征是数据的结构化组织,而非物理形态。
文件路径(path)
如何定义我们需要操作的一个文件,由于操作系统中目录于目录的之间所构成了一个树结构,因此我们就可以根据树的结点方式去定位我们的文件,也就是说从根节点出发到我们目标文件的结点,这样的路径就被称为绝对路径。
D:\图片\图片一
我们还可以从任意结点出发到我们的目标文件的结点这样的路径就被称为相对路径。
.代表当前结点 ..代表父结点
如:..\图片\图片一或.\图片一
Java中操作文件
File 类中的常⻅属性、构造⽅法和⽅法
属性(静态)
修饰符及类型 | 属性 | 说明 |
---|---|---|
static String | pathSeparator | 依赖于系统的路径分隔符(String类型) |
static char | pathSeparator | 依赖于系统的路径分隔符(char类型) |
代码示例
// 路径分隔符(例如:":" 在Unix系统,";" 在Windows系统)
public static final String pathSeparator = System.getProperty("path.separator");
public static final char pathSeparatorChar = pathSeparator.charAt(0);// 文件名分隔符(例如:"/" 在Unix系统,"\" 在Windows系统)
public static final String separator = System.getProperty("file.separator");
public static final char separatorChar = separator.charAt(0);
构造方法
签名 | 说明 |
---|---|
File(File parent, String child) | 根据父目录+孩子文件路径,创建一个新的File实例 |
File(String pathname) | 根据文件路径创建新的File实例,路径可以是绝对路径或相对路径 |
File(String parent, String child) | 根据父目录(路径表示)+孩子文件路径,创建一个新的File实例 |
代码示例
// 1. 根据路径名创建File对象
File file1 = new File("example.txt");
File file2 = new File("/home/user/documents");// 2. 根据父路径和子路径创建File对象
File file3 = new File("/home/user", "documents/example.txt");// 3. 根据父目录File对象和子路径创建File对象
File parent = new File("/home/user");
File file4 = new File(parent, "documents/example.txt");
方法
修饰符及返回值类型 | 方法签名 | 说明 |
---|---|---|
String | getParent() | 返回File对象的父目录文件路径 |
String | getName() | 返回File对象的纯文件名称 |
String | getPath() | 返回File对象的文件路径 |
String | getAbsolutePath() | 返回File对象的绝对路径 |
String | getCanonicalPath() | 返回File对象修饰过的绝对路径(解析符号链接等) |
boolean | exists() | 判断File对象描述的文件是否真实存在 |
boolean | isDirectory() | 判断File对象代表的是否为目录 |
boolean | isFile() | 判断File对象代表的是否为普通文件 |
boolean | createNewFile() | 根据File对象自动创建空文件,成功返回true |
boolean | delete() | 删除File对象对应的文件,成功返回true |
void | deleteOnExit() | 标记文件,在JVM运行结束时删除 |
String[] | list() | 返回目录下所有文件名(String数组) |
File[] | listFiles() | 返回目录下所有文件(File对象数组) |
boolean | mkdir() | 创建File对象代表的目录(仅单层) |
boolean | mkdirs() | 创建目录,必要时创建中间目录(多层) |
boolean | renameTo(File dest) | 文件改名或剪切粘贴操作 |
boolean | canRead() | 判断用户对文件是否有可读权限 |
boolean | canWrite() | 判断用户对文件是否有可写权限 |
代码示例1(get系列的方法)
public static void main(String[] args) {File file = new File("./text");//get系列的方法System.out.println("File对象的父目录文件路径:" + file.getParent());System.out.println("File对象的纯文件路径:" + file.getName());System.out.println("File对象的文件路径" + file.getPath());System.out.println("File对象的绝对路径:" + file.getAbsoluteFile());System.out.println("File对象的修饰过的绝对路径:" + file.getAbsolutePath());}
代码示例2(普通文件的创建和删除)
public static void main(String[] args) throws IOException {File file = new File("./text1");//可在创建和删除操作中增加日志进行观察//创建文件,这里的返回类型都属于booleanSystem.out.println("判断文件真实存在:" + file.exists());System.out.println("判断是否为目录:" + file.isDirectory());System.out.println("判断是否为普通文件:" + file.isFile());System.out.println("判断对象自动创建空文件" + file.createNewFile());//判断文件是否创建成功System.out.println("判断文件真实存在:" + file.exists());System.out.println("判断是否为目录:" + file.isDirectory());System.out.println("判断是否为普通文件:" + file.isFile());System.out.println("判断对象自动创建空文件" + file.createNewFile());//删除操作System.out.println("删除文件:" + file.delete());//删除操作,标记文件,在JVM运行结束时删除file.deleteOnExit();}
代码示例3(目录的文件和删除)
public static void main(String[] args) {//创建目录File file = new File("currtext1");System.out.println("判断是否为目录" + file.isDirectory());System.out.println("创建目录" + file.mkdir());System.out.println("判断是否为目录" + file.isDirectory());}public static void main(String[] args) {//创建目录,多层的情况下File file = new File("some-parent1/some-dir1");System.out.println("判断是否为目录" + file.isDirectory());System.out.println("创建目录" + file.mkdirs());System.out.println("判断是否为目录" + file.isDirectory());}
字符流详解
字节流(Byte Stream)
- 以字节为单位处理数据
- 适用于所有类型文件(文本、图片、音频等)
- 基类:InputStream 和 OutputStream
字符流(Character Stream)
- 以字符为单位处理数据
- 专门用于处理文本文件
- 自动处理字符编码转换
- 基类:Reader 和 Writer
字节流(以字节为单位,读写数据)处理二进制文件
文件内容读写是指对存储在计算机存储设备上的文件进行数据的读取和写入操作。这是程序与外部存储交互的基本方式。
文件读取(Read)也就是输入流
从文件中获取数据并加载到程序内存中的过程:
- 程序向操作系统请求访问指定文件
- 操作系统从存储设备读取数据
- 数据传输到程序的内存空间
- 程序处理这些数据
文件写入(Write)也就是输出流
将程序内存中的数据保存到文件中的过程:
- 程序准备要保存的数据
- 向操作系统请求写入权限
- 数据从内存传输到文件系统
- 最终保存到物理存储设备
InputStream 方法
方法签名 | 修饰符及返回值类型 | 说明 |
---|---|---|
int read() | int | 读取一个字节的数据,返回-1代表已经完全读完 |
int read(byte[] b) | int | 最多读取b.length 字节的数据到b 中,返回实际读到的数量;-1代表读完 |
int read(byte[] b, int off, int len) | int | 最多读取len-off 字节的数据到b 中,从off 开始存放,返回实际读到的数量;-1代表读完 |
void close() | void | 关闭字节流 |
FileInputStream 构造方法
方法签名 | 说明 |
---|---|
FileInputStream(File file) | 利用File 对象构造文件输入流 |
FileInputStream(String name) | 利用文件路径字符串构造文件输入流 |
代码示例1(需手动关闭)
InputStream inputStream = null;try {inputStream = new FileInputStream("./test.txt");} finally {inputStream.close();}
代码示例2(自动关闭)
public static void main(String[] args) {//文件资源会自动关闭try (InputStream is = new FileInputStream("./text.txt")) {while (true) {int b = is.read();if (b == -1) {//代表⽂件已经全部读完break;}//%c 表示将整数值作为字符输出System.out.printf("%c", b);//输出结果Hello}} catch (IOException e) {throw new RuntimeException(e);}}
public static void main(String[] args) throws IOException {try (InputStream is = new FileInputStream("text.txt")) {byte[] buf = new byte[1024];int len;while (true) {len = is.read(buf);if (len == -1) {// 代表文件已经全部读完break;}// 每次使用3字节进行utf-8解码,得到中文字符// 利用String中的构造方法完成// 这个方法了解一下即可,不是通用的解决办法for (int i = 0; i < len; i += 3) {String s = new String(buf, i, 3, "UTF-8");System.out.printf("%s", s);}}}}
利用Scanner进行字符
构造方法 | 说明 |
---|---|
Scanner(InputStream is, String charset) | 使用charset字符集进行is的扫描读取 |
代码示例1
public static void main(String[] args) throws IOException {try (InputStream is = new FileInputStream("text.txt")) {Scanner scanner = new Scanner(is, "UTF-8");while (scanner.hasNext()) {System.out.println(scanner.next());}}}
OutputStream进行字符写入
修饰符及返回值类型 | 方法签名 | 说明 |
---|---|---|
void | write(int b) | 写入一个字节的数据。 |
void | write(byte[] b) | 将字符数组 b 中的数据全部写入输出流中。 |
int | write(byte[] b, int off, int len) | 将字符数组 b 中从偏移量 off 开始的 len 个数据写入输出流。 |
void | close() | 关闭字节流,释放系统资源。 |
void | flush() | 强制将缓冲区中的数据写入设备。由于 I/O 速度较慢,数据通常先缓存在内存中,调用此方法可立即刷新到设备。 |
代码示例
public static void main(String[] args) throws IOException{try(OutputStream os = new FileOutputStream("text.txt")){os.write('H');os.write('e');os.write('l');os.write('l');os.write('o');os.flush();}}public static void main(String[] args) throws IOException{try(OutputStream os = new FileOutputStream("text.txt")){byte[] bytes = new byte[]{'H','e','l','l','o'};os.write(bytes);os.flush();}}public static void main(String[] args) throws IOException {try (OutputStream os = new FileOutputStream("text.txt")) {String s = "我叫小黑";byte[] bytes = s.getBytes();os.write(bytes);os.flush();}}
字符流(以字符为单位,读写数据)处理文本文件
Reader(字符输入流)
public static void main(String[] args) throws IOException {try(Reader reader = new FileReader("text.txt")){while (true){int ch = reader.read();if (ch == -1){break;}System.out.print((char)ch);}}}
Writer(字符输出流)
public static void main(String[] args) throws IOException {try(Writer writer = new FileWriter("text.txt")) {writer.write("hello word");}}