一、File类

java.io.File类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。

1.1 构造方法

public File(String pathname); // 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
public File(String parent, String child); // 从父路径名字符串和子路径名字符串创建新的 File实例。
public File(File parent, String child); // 从父抽象路径名和子路径名字符串创建新的 File实例。

1.2 常用方法

/// API
// 获取功能
public String getAbsolutePath(); // 返回此File的绝对路径名字符串。
public String getPath(); // 将此File转换为路径名字符串。
public String getName(); // 返回由此File表示的文件或目录的名称。
public long length(); // 返回由此File表示的文件的长度。若File对象表示目录,则返回值未指定。
// 判断功能
public boolean exists(); // 此File表示的文件或目录是否实际存在。
public boolean isDirectory(); // 此File表示的是否为目录。
public boolean isFile(); // 此File表示的是否为文件。
// 创建删除功能
public boolean createNewFile(); // 当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
public boolean delete(); // 删除由此File表示的文件或目录。
public boolean mkdir(); // 创建由此File表示的目录。
public boolean mkdirs(); // 创建由此File表示的目录,包括任何必需但不存在的父目录
// 目录的遍历
public String[] list(); // 返回一个String数组,表示该File目录中的所有子文件或目录。
public File[] listFiles(); // 返回一个File数组,表示该File目录中的所有的子文件或目录。

1.3 例子

  • 递归打印多级目录
public static void printDir(File dir) {
// 获取子文件和目录
File[] files = dir.listFiles();
// 循环打印
for (File file : files) {
// 判断
if (file.isFile()) {
// 是文件,输出文件绝对路径
// if (file.getName().endsWith(".java")) // 筛选后缀是 .java 的文件
System.out.println("文件名:" + file.getAbsolutePath());
} else {
// 是目录,输出目录绝对路径
System.out.println("目录:" + file.getAbsolutePath());
// 继续遍历,调用printDir,形成递归
printDir(file);
}
}
}
  • 使用文件过滤器java.io.FileFilter接口来筛选文件:
public static void printDir2(File dir) {
// Lambda表达式优化
// File[] files = dir.listFiles(f -> f.getName().endsWith(".java") || f.isDirectory());
File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".java") || pathname.isDirectory();
}
});
// 循环打印
for (File file : files) {
// 判断
if (file.isFile()) {
System.out.println("文件名:" + file.getAbsolutePath());
} else {
printDir2(file);
}
}
}

java 7 引入了一些新的文件处理类用来代替 File 类的文件 I/O 操作方式:Java NIO系列教程

import java.nio.file.DirectoryStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;

二、基础I/O:字节流、字符流

I/O 顶级父类们
输入流 输出流
字节流 InputStream OutputStream
字符流 Reader Writer

2.1 字节流

一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节。所以字节流可以传输任意文件数据。

2.1.1 字节输出流 OutputStream

java.io.OutputStream抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字节输出流的基本共性功能方法。

public void close();
public void flush();
public void write(byte[] b);
public void write(byte[] b, int off, int len);
public abstract void write(int b);

2.1.2 FileOutputStream类

java.io.FileOutputStream类是文件输出流,用于将数据写出到文件。

public FileOutputStream(File file);
public FileOutputStream(String name);
  1. 写出字节:write 方法;
  2. 每次程序运行,创建输出流对象,都会清空目标文件中的数据。构造方法还可以传入一个boolean append参数,表示追加写。
  3. 写出换行:fos.write("\r\n".getBytes());

2.1.3 字节输入流 InputStream

java.io.InputStream抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。

public void close();
public abstract int read();
public int read(byte[] b);

2.1.4 FileInputStream类

java.io.FileInputStream类是文件输入流,从文件中读取字节。

FileInputStream(File file);
FileInputStream(String name);
  1. 读取字节:read 方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回 -1;
  2. 使用字节数组读取:read(byte[] b),每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回 -1。

2.2 字符流

一些字符如中文字符可能占用多个字节存储。所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件。

2.2.1 字符输出流 Writer

java.io.Writer抽象类是表示用于写出字符流的所有类的超类。

void write(int c);
void write(char[] cbuf);
abstract void write(char[] cbuf, int off, int len);
void write(String str);
void write(String str, int off, int len);
void flush();
void close();

2.2.2 FileWriter类

java.io.FileWriter类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

FileWriter(File file);
FileWriter(String fileName);
  1. 写出字符:write 方法;
  2. flush :刷新缓冲区;
  3. close :先刷新缓冲区,然后通知系统释放资源。

字符流,只能操作文本文件,不能操作图片,视频等非文本文件。当我们单纯读或者写文本文件时 使用字符流 其他情况使用字节流

2.2.3 字符输入流 Reader

java.io.Reader抽象类是表示用于读取字符流的所有类的超类。

public void close();
public int read();
public int read(char[] cbuf);

2.2.4 FileReader类

java.io.FileReader 类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

FileReader(File file);
FileReader(String fileName);
  1. 读取字符: read() 方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回 -1;
  2. 使用字符数组读取: read(char[] cbuf) ,每次读取b的长度个字符到数组中,返回读取到的有效字符个数,

    读取到末尾时,返回 -1。

当创建一个文件输入流对象时,若没有该文件,会抛出FileNotFoundException;创建文件输出流对象时,若没有该文件,会自动创建。

try-with-resource

三、缓冲流、转换流、序列化流、打印流

3.1 缓冲流

缓冲流,也叫高效流,是对4个基本的FileXxx流的增强,所以也是4个流,按照数据类型分类。

  • 字节缓冲流:BufferedInputStreamBufferedOutputStream
  • 字符缓冲流:BufferedReaderBufferedWriter

缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。

3.1.1 字节缓冲流

构造方法:

public BufferedInputStream(InputStream in); // 创建一个新的缓冲输入流。
public BufferedOutputStream(OutputStream out); // 创建一个新的缓冲输出流。

字节缓冲流读写方法与基本的流是一致的。

3.1.2 字符缓冲流

构造方法

public BufferedReader(Reader in); // 创建一个新的缓冲输入流。
public BufferedWriter(Writer out); // 创建一个新的缓冲输出流。

字符缓冲流的基本方法与普通字符流调用方式一致。特有方法:

/// BufferedReader:
public String readLine(); // 读一行文字
/// BufferedWriter:
public void newLine(); // 写一行行分隔符,由系统属性定义符号

3.2 转换流

3.2.1 InputStreamReader类

转换流java.io.InputStreamReader,是Reader的子类,是从字节流到字符流的桥梁。它读取字节,并使用指定的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。

InputStreamReader(InputStream in); // 创建一个使用默认字符集的字符流。
InputStreamReader(InputStream in, String charsetName); // 创建一个指定字符集的字符流

3.2.1 OutputStreamWriter类

转换流java.io.OutputStreamWriter,是Writer的子类,是从字符流到字节流的桥梁。使用指定的字符集将字符编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。

OutputStreamWriter(OutputStream in); // 创建一个使用默认字符集的字符流。
OutputStreamWriter(OutputStream in, String charsetName); // 创建一个指定字符集的字符流。

3.3 序列化

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据对象的类型对象中存储的属性等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。

反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。对象的数据对象的类型对象中存储的属性信息,都可以用来在内存中创建对象。

3.3.1 ObjectOutputStream类

java.io.ObjectOutputStream类,将Java对象的原始数据类型写出到文件,实现对象的持久存储。

构造方法:

public ObjectOutputStream(OutputStream out); // 创建一个指定OutputStream的ObjectOutputStream

/// 示例:
FileOutputStream fileOut = new FileOutputStream("employee.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
  1. 一个对象要想序列化,必须满足两个条件
  • 该类必须实现java.io.Serializable接口,Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出NotSerializableException
  • 该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用transient关键字修饰
  1. 写出对象方法
public final void writeObject (Object obj); // 将指定的对象写出

3.3.2 ObjectInputStream类

java.io.ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。

构造方法:

public ObjectInputStream(InputStream in); // 创建一个指定InputStream的ObjectInputStream。

如果能找到一个对象的class文件,我们可以进行反序列化操作,调用 ObjectInputStream 读取对象的方法:

public final Object readObject (); // 读取一个对象

对于JVM可以反序列化对象,它必须是能够找到class文件的类。如果找不到该类的class文件,则抛出一个ClassNotFoundException异常。

另外,当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改,那么反序列化操作也会失败,抛出一个InvalidClassException异常。 发生这个异常的原因如下:

  • 该类的序列版本号与从流中读取的类描述符的版本号不匹配
  • 该类包含未知数据类型
  • 该类没有可访问的无参数构造方法

Serializable接口给需要序列化的类,提供了一个序列版本号。 serialVersionUID该版本号的目的在于验证序列化的对象和对应类是否版本匹配。示例:

public class Employee implements java.io.Serializable {
// 加入序列版本号
private static final long serialVersionUID = 1L;
public String name;
public String address;
// 添加新的属性 ,重新编译, 可以反序列化,该属性赋为默认值
public int eid; public void addressCheck() {
System.out.println("Address check : " + name + " ‐‐ " + address);
}
}

3.4 打印流

平时我们在控制台打印输出,是调用 print 方法和 println 方法完成的,这两个方法都来自于java.io.PrintStream类,该类能够方便地打印各种数据类型的值,是一种便捷的输出方式。

3.4.1 PrintStream类

构造方法:

public PrintStream(String fileName);
public PrintStream(File file);
public PrintStream(OutputStream out);
  • System.out 就是 PrintStream 类型的,只不过它的流向是系统规定的,打印在控制台上。

    我们可以改变它的流向:
public class PrintDemo {
public static void main(String[] args) throws IOException {
// 调用系统的打印流,控制台直接输出97
System.out.println(97);
// 创建打印流,指定文件的名称
PrintStream ps = new PrintStream("ps.txt");
// 设置系统的打印流流向,输出到ps.txt
System.setOut(ps);
// 调用系统的打印流, ps.txt中输出97
System.out.println(97);
}
}

另,三篇讲得较全面的博客:

博客园:这些年一直记不住的 Java I/O

简书:看完这个,Java IO从此不在难

CSDN:Java8 I/O源码-整体结构

Java文件I/O简单介绍的更多相关文章

  1. java中io对文件操作的简单介绍

    11.3 I/O类使用 由于在IO操作中,需要使用的数据源有很多,作为一个IO技术的初学者,从读写文件开始学习IO技术是一个比较好的选择.因为文件是一种常见的数据源,而且读写文件也是程序员进行IO编程 ...

  2. PHP 关于文件操作的简单介绍

    文件操作一直是Web程序员头疼的地方,而文件操作在CMS这样的系统中又是必须的.如今,PHP文件操作的函数内容已经非常强大,文件这部分也是学习PHP非常重要的一部分,希望大家不要忽略.这篇文章会简单介 ...

  3. java反射机制的简单介绍

    参考博客: https://blog.csdn.net/mlc1218559742/article/details/52754310 先给出反射机制中常用的几个方法: Class.forName (& ...

  4. Java泛型使用的简单介绍

    目录 一. 泛型是什么 二. 使用泛型有什么好处 三. 泛型类 四. 泛型接口 五. 泛型方法 六. 限定类型变量 七. 泛型通配符 7.1 上界通配符 7.2 下界通配符 7.3 无限定通配符 八. ...

  5. Java Linked集合的简单介绍和常用方法的使用

    LinkedList的简单介绍 java.util.LinkedList 集合数据存储的结构是链表结构.LinkedList是一个双向链表在实际开发中,对一个集合元素的添加和删除,经常涉及到首尾操作, ...

  6. Java中NIO的简单介绍

    NIO基本介绍 Java NIO(New IO) 也有人称之为Java non-blocking IO 是从Java1.4版本开始引入的一个新的IO API,可以代替标准的IO API.NIO与原来的 ...

  7. java中数据流的简单介绍

    java中的I/O操作主要是基于数据流进行操作的,数据流表示了字符或者字节的流动序列. java.io是数据流操作的主要软件包 java.nio是对块传输进行的支持 数据流基本概念 “流是磁盘或其它外 ...

  8. java文件断点续传的简单实现

    一.概述 所谓断点续传,其实只是指下载,也就是要从文件已经下载的地方开始继续下载.在以前版本的HTTP协议是不支持断点的,HTTP/1.1开始就支持了.一般断点下载时才用到Range和Content- ...

  9. php之文件上传简单介绍

    要声明的form表单格式 <form action="act.php" method="post" enctype="multipart/for ...

随机推荐

  1. Spring Cloud Gateway简单入门,强大的微服务网关

    我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 简介 见名知义,Spring Cloud Gateway是用于微服务场景的网关组件,它是基于Spring WebFlu ...

  2. hash表及带注释插头dp

    struct hash_map { node s[SZ+10];int e,adj[SZ+10]; inline void init(){e=0;memset(adj,0,sizeof(adj));} ...

  3. 精通LED驱动芯片HT1632C指令与编程应用

    HT1632C是一款很常用的LED(数码管或点阵)驱动芯片,虽然官方已经宣布该芯片明年(2021年)即将寿终正寝(停产),但是相同厂家生产的同系列芯片的控制方式通常是相同的(事实上,大多数LED驱动芯 ...

  4. 玩转STM32MP157- 使用fbtft驱动 lcd ili9341

    之前使用了 fbtft 成功驱动了lcd st7735r,现在尝试下驱动 ili9341, 配置 跟之前用 fbtft 驱动 st7735r 一样,先用 make menuconfig 配置内核,添加 ...

  5. python之str 字符串

    str,字符串,有序的,存储多个字符,不可修改,通过下标值访问快捷方式 1, 定义一个空字符串 2,定义一个非空字符串 3,索引,又名下标值 4,切片与延长 5,转义字符 6, python 属于面向 ...

  6. .Net Core with 微服务 - Consul 配置中心

    上一次我们介绍了Elastic APM组件.这一次我们继续介绍微服务相关组件配置中心的使用方法.本来打算介绍下携程开源的重型配置中心框架 apollo 但是体系实在是太过于庞大,还是让我爱不起来.因为 ...

  7. ansible 任务执行

    ansible 任务执行模式 Ansible 系统由控制主机对被管节点的操作方式可分为两类,即adhoc和playbook: ad-hoc模式(点对点模式)• ad-hoc模式(点对点模式) 使用单个 ...

  8. SpringMVC(10)实现注解式权限验证

    在项目中如何处理出现的异常,在每个可能出现异常的地方都写代码捕捉异常?这显然是不合理的,当项目越来越大是也是不可维护的.那么如何保证我们处理异常的代码精简且便于维护呢?这就是本篇要讲的内容->异 ...

  9. easyui的combobox的onChange事件的实现

    easyui的combobox的onChange事件的实现,直接上代码: <div style="display:inline;margin-left:15px;"> ...

  10. linux学习之路第五天(文件目录类第一部分)

    文件目录类 pwd 指令 基本语法 pwd (显示当前目录的绝对路径) Ls 指令 cd 指令 -代表的是上一级目录 mkdir指令 用于创建目录 基本语法 mkdir [选项] 要创建的目录 常用选 ...