JavaSE-IO流


Java的IO通过java.io包下的类和接口来支持,在java.io包下主要包括输入、输出两种IO流,每种输入、输出流又可以分为字节流和字符流两大类。其中字节流以字节为单位来处理输入、输出操作,而字符流则以字符来处理输入、输出操作
Java7在java.nio及其子包下提供了一系列全新的API,这些API是对原有新IO的升级,因此也被称为NIO2,通过这些NIO2,程序可以更高效地进行输入、输出操作

File类

File类在包java.io.File下、代表操作系统的文件对象(文件、文件夹)
File类提供了诸如:定位文件,获取文件本身的信息、删除文件、创建文件(文件夹)等功能,File不能访问文件内容本身,如果需要访问文件内容,则需要使用输入/输出流

File构造器 说明
File(String pathname) 根据文件路径创建文件对象
File(String parent, String child) 从父路径名字符串和子路径名字符串创建文件对象
File(File parent, String child) 根据父路径对应文件对象和子路径名字符串创建文件对象
File(URI uri)

File对象可以定位文件和文件夹;File封装的对象仅仅是一个路径名,这个路径可以是存在的,也可以是不存在的

// 绝对路径:从盘符开始
File f1 = new File("D:\\workspace\\IdeaProjects\\JavaSE\\HelloWorld");
// 相对路径:不带盘符,默认直接到当前工程下的目录寻找文件
File f2 = new File("a.txt");
File类常用方法
常用方法 返回值类型 说明
getAbsolutePath() String 获取绝对路径
getAbsoluteFile() File 获取绝对路径的File对象
getPath() String 获取文件定义时使用的路径
getName() String 获取文件的名称(带后缀)或路径名(如果是路径名,则只返回最后一级子路径名)
getParent() String 获取最后一级子目录的父目录名
getParentFile() File 获取最后一级子目录的父目录名的File对象
getCanonicalPath() String 获取规范路径;此方法首先将路径名转换为绝对路径
getCanonicalFile() File 获取规范路径;此方法首先将路径名转换为绝对路径
length() long 获取文件的大小(字节个数)
lastModified() long 获取文件的最后修改时间(毫秒值)
createNewFile() boolean 创建一个新的空文件
delete() boolean 删除此文件或空文件夹,默认不能删除非空文件夹(不走回收站)
mkdir() boolean 只能创建一级文件夹
mkdirs() boolean 可创建多级文件夹
renameTo(File dest) boolean 重命名文件名或文件夹;如果成功返回true
exists() boolean 判断是否存在
isFile() boolean 判断是否是文件
isDirectory() boolean 判断是否是文件夹
isAbsolute() boolean 判断是否是绝对路径
isHidden() boolean 判断是否是一个隐藏文件
canRead() boolean 判断文件/文件夹是否可以读取
canWrite() boolean 判断文件/文件夹是否可以写入
canExecute() boolean
createTempFile(String prefix, String suffix) staitc File 在默认的临时文件目录中创建一个临时的空文件
createTempFile(String prefix, String suffix, File directory) static File 在指定的目录中创建一个临时的空文件
deleteOnExit() void 注册一个删除钩子,指定当JVM退出时,删除File对象所对应的文件和目录
list() String[] 获取当前目录下的所有一级文件和文件夹名称的String数组
listFiles() File[] 获取当前目录下的所有一级文件和文件夹的File数组
listRoots() static File[] 列出系统所有的根路径
list(FilenameFilter filter) String[] 只会对符合条件的文件/文件夹进行迭代(底层就是FileFilter)
listFiles(FileFilter filter) File[] 只会对符合条件的文件/文件夹进行迭代
listFiles(FilenameFilter filter) File[] 只会对符合条件的文件/文件夹进行迭代
getFreeSpace() long
getTotalSpace() long
getUsableSpace() long
toPath() Path 转换为Path对象
toURI() URI 转换为URI对象
setLastModified(long time) boolean 设置最后一次修改时间
setReadable(boolean readable) boolean 是指是否可读
setReadable(boolean readable, boolean ownerOnly) boolean 是指是否可读
setReadOnly() boolean 是指是否可读
setWritable(boolean writable) boolean 是指是否可写
setWritable(boolean writable, boolean ownerOnly) boolean 是指是否可写
setExecutable(boolean executable) boolean
setExecutable(boolean executable, boolean ownerOnly) boolean
compareTo(File pathname) int 比较
equals(Object obj) boolean 相等
hashCode() int 哈希码
toString() String 返回字符串
案例代码:查询指定目录下的指定文件
// 查询指定目录下的指定文件
public class Main {
    public static void main(String[] args) throws IOException {
        searchFile(new File("D:/"), "a.txt");
    }

    public static void searchFile(File dir, String fileName) {
        // 判断dir是否是目录
        if (dir != null && dir.isDirectory()) {
            // 提取当前目录下的一级文件对象
            File[] files = dir.listFiles();
            // 判断是否存在一级文件对象,如果存在才能遍历
            if (files != null && files.length > 0) {
                for (File file : files) {
                    // 判断当前遍历的一级文件对象是文件还是目录
                    if (file.isFile()) {
                        // 如果是要找到的文件,把其路径输出即可
                        if (file.getName().contains(fileName)) {
                            System.out.println("找到了" + file.getAbsolutePath());
                        }
                    } else {
                        // 如果是文件夹,需要继续递归查找
                        searchFile(file, fileName);
                    }
                }
            }
        } else {
            System.out.println("对不起,当前搜索的位置不是文件夹!");
        }
    }
}

IO流框架

  • I表示intput,输入流,读数据到内存
  • O表示output,输出流,写数据到磁盘

字节流和字符流

字节流和字符流它们的操作完全一样,区别只是操作的数据单元不同而已——字节流操作的数据单元是字节,字符流操作的单元是字符

分类 字节输入流 字节输出流 字符输入流 字符输出流
抽象基类 InputStream OutputStream Reader Writer
访问文件 FileInputStream FileOutputStream FileReader FileWriter
访问数组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
访问管道 PipedInputStream PipedOutputStream PipedReader PipedWriter
访问字符串 —— —— StringReader StringWriter
缓冲流 BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
转换流 —— —— InputStreamReader OutputStreamWriter
对象流 ObjectInputStream ObjectOutputStream —— ——
抽象基类 FilterInputStream FilterOutputStream FilterReader FilterWriter
打印流 —— PrintStream —— PrintWriter
推回输入流 PushbackInputStream —— PushbackReader ——
特殊流 DataInputStream DataOutputStream —— ——

\[\text{IO常用类} \begin{cases} \text{InputStream} \begin{cases} \text{FileInputStream}\\ \text{ByteArrayInputStream}\\ \text{SequenceInputStream}\\ \text{ObjectInputStream}\\ \text{PipedInputStream}\\ \text{FilterInputStream} \begin{cases} \text{BufferedInputStream}\\ \text{DataInputStream}\\ \text{DigestInputStream} \end{cases} \end{cases} \\ \text{OutputStream} \begin{cases} \text{FileOutputStream}\\ \text{ByteArrayOutputStream}\\ \text{ObjectOutputStream}\\ \text{PipedOutputStream}\\ \text{FilterOutputStream} \begin{cases} \text{BufferedOutputStream}\\ \text{DataOutputStream}\\ \text{DigestOutputStream}\\ \text{PrintStream} \end{cases} \end{cases} \\ \text{Reader} \begin{cases} \text{InputStreamReader} \to \text{FileReader} \\ \text{CharArrayReader} \\ \text{StringReader} \\ \text{BufferedReader} \\ \text{FilterReader} \\ \text{PipedReader} \end{cases} \\ \text{Writer} \begin{cases} \text{OutputStreamWriter} \to \text{FileWriter} \\ \text{CharArrayWriter} \\ \text{StringWriter} \\ \text{PrintWriter} \\ \text{FilterWriter} \\ \text{PipedWriter} \end{cases} \end{cases} \]

代码案例:文件拷贝(高级流BufferedInputStream)
// 文件拷贝
String srcPath = "D:\\avatar.jpg";
String destPath = "D:\\new.jpg";
try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(srcPath));
     BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(destPath));) {
    byte[] buffer = new byte[1024];
    int len = 0;
    while ((len = in.read(buffer)) != -1) {
        out.write(buffer, 0, len);
    }
    System.out.println("复制文件已完成~");
} catch (Exception e) {
    e.printStackTrace();
}
代码案例:解决读取文件乱码的问题(使用转换流来解决)
// 获取正确编码的输入流(InputStreamReader:将字节输入流转换为字符输入流)
String srcPath = "D:/a.txt";
try (Reader reader = new InputStreamReader(new FileInputStream(srcPath), "GBK");
     BufferedReader bufferedReader = new BufferedReader(reader);) {
    String line;
    while ((line = bufferedReader.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

// 输出正确编码的输出流(OutputStreamWriter:字节输出流转换为字符输出流)
String destPath = "D:/b.txt";
try (Writer writer = new OutputStreamWriter(new FileOutputStream(destPath), "GBK");
     BufferedWriter buffer = new BufferedWriter(writer);) {
    buffer.write("hello 不二橘子酱!");
} catch (IOException e) {
    e.printStackTrace();
}
代码案例:序列化与反序列化(使用对象流来处理)
@Data
public class Student implements Serializable {
    private String name;
    private transient String password;
    private int age;
}

// 序列化:把内存中的对象存入到磁盘文件中
Student s = new Student("不二橘子酱", "123456", 18);
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/a.txt"))) {
    // 直接调用序列化方法
    oos.writeObject(s);
} catch (IOException e) {
    e.printStackTrace();
}

// 反序列化:把磁盘中的对象数据转换成内存中的Java对象
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/a.txt"))) {
    Student s = (Student) ois.readObject();
    System.out.println(s); // Student{name='不二橘子酱', password='null', age=18}
} catch (Exception e) {
    e.printStackTrace();
}
代码案例:打印流的区别(PrintStream/PrintWriter)
// 打印流:在打印数据功能上是一模一样的,区别在于PrintStream只能写字节数据;PrintWriter只能写字符数据
// PrintStream继承自OutputStream;PrintWriter继承自Writer
try (PrintStream ps1 = new PrintStream(new FileOutputStream("D:/a.txt"), true);
     PrintStream ps2 = new PrintStream("D:/b.txt");
     PrintWriter ps3 = new PrintWriter("D:/c.txt");
) {
    ps2.println("我是打印流输出的,是什么就打印什么");
    ps3.write("不二橘子酱");
} catch (Exception e) {
    e.printStackTrace();
}

nio

nio2