• 在Windows 系统上为分号(;),在 UNIX 系统上为冒号(:)

文件名称分隔符

  • 在 Windows 系统上为反斜线(\),在 UNIX 系统上为斜线(/)
  • Java 程序中的反斜线表示转义字符,所以如果需要在 Windows 的路径下包括反斜线,则应该使用两条反斜线,如 F:\abc\test.txt
  • Java 程序支持将斜线(/)当成平台无关的文件分隔符

行分隔符

  • Windows 系统上为 \r,UNIX/Linux/BSD 等系统上为 \n

路径

  • 绝对路径:在 Windows 等系统上,路径开头由盘符和一个 “:” 组成,在 UNIX 系统上,路径名开头是一条斜线(/)
  • 相对路径:用户的工作路径,运行 Java 虚拟机时所在的路径(默认)
  • 当二进制文件里的内容能被正常解析成字符时,则该二进制文件就变成了文本文件

Charset 类

  • 编码(Encode)和解码(Decode)
  • 标准字符集常量定义在 StandardCharsets 类中
  • Java 默认使用 Unicode 字符集(Unicode 符号集只规定了符号的二进制代码)
  • 常见的字符集:ASCII:占一个字节,只能包含128个符号,不能表示汉字ISO-8859-1(又称 latin-1):占一个字节,收录西欧语言,不能表示汉字ANSI:占两个字节,在简体中文的操作系统中 ANSI 指的是 GB2312GB2312、GBK、GB18030:占两个字节,支持中文UTF-8:是一种针对 Unicode 的可变长度字符编码,又称万国码,是 Unicode 的实现方式之一
  • 存储字母和数字:无论是什么字符集都占 1 个字节存储汉字:GBK 家族占 2 个字节,UTF-8 占 3 个字节,UTF-16 占 2 个字节

File 类

  • 全局静态常量

    • 路径分隔符:char pathSeparatorChar、String pathSeparator
    • 文件名称分隔符:char separatorChar、String separator

访问文件名

  • String getName():返回此 File 对象所表示的文件名目录名,123.txt
  • String getPath():返回此 File 对象所对应的路径名,C:/abc/123.txt
  • File getAbsoluteFile():返回此 File 对象的绝对路径
  • String getAbsolutePath():返回此 File 对象所对应的绝对路径名,C:/abc/123.txt
  • File getParentFile():返回此 File 对象所对应的父路径,如果没有,返回 null,C:/abc
  • String getParent():返回此 File 对象所对应的父路径名

检测文件

  • boolean exists():判断 File 对象所对应的文件或目录是否真实存在
  • boolean isFile():判断 Hie 对象所对应的是否是文件
  • boolean isDirectory():判断 File 对象所对应的是否是目录
  • boolean isAbsolute():判断 File 对象是否是绝对路径
  • boolean canRead():判断 File 对象所对应的文件和目录是否可读
  • boolean canWrite():判断 File 对象所对应的文件和目录是否可写
  • boolean canExecute():判断应用程序是否可以执行此 File 对象所对应的文件或目录
  • long length():获取文件内容的长度(单位为字节)(如果此路径名表示一个目录,则返回值是不确定的)
  • long lastModified():获取文件的最后修改时间

操作文件

  • boolean createNewFile():当此 File 对象所对应的文件不存在但对应的父路径存在时,新建一个该 File 对象所指定的文件
  • static File createTempFile(String prefix, String suffix):在默认的临时文件目录中创建一个临时的文件,使用给定前缀、 系统生成的随机数和给定后缀作为文件名(prefix 参数至少是 3 字节长,suffix 参数为 null 时,将使用默认的后缀“.tmp”)
  • static File createTempFile(String prefix, String suffix, File directory):在 directory 所指定的目录中创建一个临时的文件,使用给定前缀、 系统生成的随机数和给定后缀作为文件名
  • boolean mkdir():当此 File 对象所对应的目录不存在但对应的父目录存在时,新建一个 File 对象所对应的目录
  • boolean mkdirs():新建一个 File 对象所对应的目录包括所有必需但不存在的父目录
  • boolean delete():删除 File 对象所对应的文件或目录
  • void deleteOnExit():注册一个删除钩子,指定当 Java 虚拟机退出时,删除 File 对象所对应的文件或目录
  • boolean renameTo(File dest):用指定的路径名重新命名对 File 对象所对应的文件或路径
  • File[] listFiles():列出 File 对象的所有子文件和子目录的绝对路径,返回 File 数组
  • :列出 File 对象的所有子文件名和子目录的名称,返回 String 数组
  • static File[] listRoots():列出系统所有的根路径

文件过滤器

  • String[] list(FilenameFilter filter)
  • File[] listFiles(FilenameFilter filter):列出 File 对象的所有符合条件的子文件和目录,返回 File 数组
  • FilenameFilter 接口中的抽象方法:boolean accept(File dir, String name)
  • 底层依次对指定 File 的所有子目录或者文件进行迭代,如果该方法返回 true,则 list() 方法会列出该子目录或者文件

IO 流概述

  • 所有传统的流类型(类或抽象类)都放在 java. io 包下
  • 流对象封装了用于保存输入或输出信息的缓冲空间,以及针对这个缓冲空间进行操作的方法
  • 步骤:
    • 创建节点对象
    • 创建 IO 流对象
    • 具体的 IO 操作(read()、write())
    • 关闭 IO 流对象
  • 输入流和输出流:从程序运行所在内存的角度来划分的
  • 字节流和字符流字节流操作的数据单元是 8 位的字节字符流操作的数据单元是 16 位的字符(2个字节)
  • 节点流和处理流
    • 节点流,和实际的输入/输出节点连接,流的构造器参数是一个物理节点
    • 处理流(包装流),对已存在的节点流进行连接或封装,流的构造器参数是已经存在的流
    • 使用处理流来包装节点流,程序通过处理流来执行输入/输出功能,让节点流与底层的 I/O 设备、 文件交互
  • 4 个抽象基类:InputStream、OutputStream、Reader、Writer
  • InputStreamReader、OutputStreamWriter 类是从字节流到字符流的桥梁


    图 1 IO流分类

输入流:InputStream 和 Reader

  • 创建字节/字符数组作为缓冲区,read in
    • int read():从输入流中读取一个字节/字符,返回所读取的字节数据/字符数据,如果已读到流的末尾,则返回 -1
    • int read(byte[]/char[] buf):从输入流中最多读取 buf.Iength 个字节/字符的数据,并将其存储在字节数组/字符数组 buf 中,返回实际读取的字节数/字符总数,如果已读到流的末尾,则返回 -1
    • int read(byte[]/char[] buf, int off, int len):从输入流中最多读取 len 个字节/字符的数据,并将其存储在字节数组/字符数组 buf 中,从数组的 off 位置开始放入,返回实际读取的字节数/字符总数,如果已读到流的末尾,则返回 -1
  • 标准字节输入流,读取键盘的输入:System.in

输出流:OutputStream 和 Writer

  • write out

    • void write(int c):将指定的字节/字符 c 输出到输出流中
    • void write(byte[]/char[] buf):将字节数组/字符数组 buf 中的数据输出到指定输出流中
    • void write(byte[]/char[] buf,int off,int len):将字节数组/字符数组 buf 中从 off 位置开始,长度为 len 的字节/字符输出到输出流中
    • void flush():刷新此输出流并强制写出所有缓冲的输出字节/字符(仅对缓冲输出流和字符输出流起作用)
  • Writer 类(字符输出流)中还包含如下两个方法

    • void write(String str, int off, int len):将 str 字符串里从 off 位置开始,长度为 len 的字符输出到指定输出流中

节点流

文件流

  • 访问文件

FilelnputStream 和 FileReader

  • 构造器(当指定 File 对象对应的文件不存在时,会在对应的目录下新建该文件)FileInputStream(File file)、FileInputStream(String name)FileReader(File file)、FileReader(String fileName)

FileOutputStream 和 FileWrite

  • 构造器(当指定 File 对象对应的文件不存在时,会在对应的目录下新建该文件)FileOutputStream(File file, boolean append)、FileOutputStream(String name, boolean append)FileWriter(File file, boolean append)、FileWriter(String fileName, boolean append)

数组流(内存流)

  • 访问数组:字节流以字节数组为节点,字符流以字符数组为节点ByteArrayInputStream、ByteArrayOutputStreamCharArrayReader、CharArrayWriter

  • 访问字符串StringReader、StringWriter

管道流(线程通讯流)

  • 将 A 线程的管道输出流连和 B 线程的管道输入流连接(connect)来实现线程之间通信功能
  • PipedlnputStream、 PipedOutputStreamPipedReader、 PipedWriter
  • java.util 包中,可以使用正则表达式来解析基本类型和字符串的简单文本扫描器

  • 构造器Scanner(File source, String charsetName)Scanner(InputStream source, String charsetName)Scanner(String source):创建一个从指定字符串扫描的扫描器

  • 实例方法:(xxx表示数据类型,如byte、int 、boolean等)boolean hasNextXxx():判断此扫描器输入信息中的下一个标记是否可以解释为一个 xxx 值Xxx nextXxx():将输入信息的下一个标记扫描为一个 xxx 值boolean hasNextLine() :如果在此扫描器的输入中存在另一行,则返回 trueString nextLine():此扫描器执行当前行,并返回跳过的输入信息Scanner useDelimiter(Pattern pattern):将此扫描器的分隔模式设置为指定模式,返回 this

Properties 类加载配置文件

  • void load(InputStream inStream)void store(OutputStream out, String comments)

访问其它进程

  • 以子进程为节点:用于本进程读写其他进程中的数据

  • Process 类中用于让程序和其子进程进行通信的实例方法:InputStream getInputStream():获取子进程的输入流OutputStream getOutputStream():获取子进程的输出流InputStream getErrorStream():获取子进程的错误流

RandomAccessFile

  • 可以自由访问文件的任意地方
  • 构造器RandomAccessFile(File file, String mode)RandomAccessFile(String name, String mode)模式参数:"r"、"rw"、"rws" 或 "rwd"

处理流

  • 关闭输入/输出流资源时,只要关闭最上层的处理流即可

缓冲流

  • 缓冲区大小为 8192 个字节或字符
  • 构造器BufferedInputStream(InputStream in)、BufferedReader(Reader in)

  • BufferedReader 类(字符缓冲输入流)中特有的方法String readLine():读取一个文本行(换行 '\n' 或回车 '\r'),如果已到达流末尾,则返回 null

BufferedOutputStream 和 BufferedWriter

  • 构造器BufferedOutputStream(OutputStream out)、BufferedWriter(Writer out)

  • BufferedWriter 类(字符缓冲输出流)中特有的方法void newLine():写入一个行分隔符(由系统属性 line.separator 定义)

转换流

  • 将字节流转换成字符流:InputStreamReader、OutputStreamWriter

  • 构造器InputStreamReader(InputStream in, String charsetName)OutputStreamWriter(OutputStream out, String charsetName)

  • 转换流特有的方法String getEncoding():返回此流使用的字符编码的名称

顺序流(合并流)

  • 把多个字节输入流合并成一个字节输入流对象
  • SequenceInputStream构造器:SequenceInputStream(InputStream s1, InputStream s2)
  • ObjectInputStream构造器:ObjectInputStream(InputStream in)实例方法:Object readObject():从 ObjectInputStream 读取对象(可能需要强转

  • ObjectOutputStream构造器:ObjectOutputStream(OutputStream out)实例方法:void writeObject(Object obj):将指定的对象写入 ObjectOutputStream

  • 对象序列化机制允许将内存中实现序列化的 Java 对象转换成字节序列(二进制流),使得对象可以脱离程序的运行而独立存在(保存到磁盘上或者通过网络传输)

  • 对象的序列化(Serialize) :将一个 Java 对象写入二进制流中

  • 对象的反序列化(Deserialize) :从二进制流中恢复该 Java 对象(反序列化时必须存在对象的字节码对象)

  • 支持序列化机制的对象的类必须实现 Serializable 接口(标识接口,无抽象方法)

  • 为了在反序列化时确保序列化版本的兼容性,最好在每个要序列化的类中定义一个 private static final long serialVersionUID 字段,用于标识该 Java 类的序列化版本号(具体数值可以自己定义),如果不显式定义 serialVersionUID 类变量的值,该类变量的值将由 JVM 根据类的相关信息计算

打印流

  • 都是输出流

  • PrintStream 构造器PrintStream(File file, String csn)PrintStream(String fileName, String csn)PrintStream(OutputStream out)

  • PrintWriter 构造器PrintWriter(File file, String csn)PrintWriter(String fileName, String csn)PrintWriter(Writer out, boolean autoFlush)如果 autoFlush 为 true,则在调用 println、printf 或 format 的其中一个方法时将刷新输出缓冲区,否则只会在调用 flush、close 方法时才会写出所有缓冲的输出字符

  • 实例方法void print(Object o):打印任意类型数据值或对象的字符串值void println(Object o):打印任意类型数据或对象的字符串值,然后换行PrintStream printf(String format, Object… args):使用指定格式字符串和参数将格式化的字符串写入此输出流

  • 标准字节打印流,输出到显示器:System.out标准错误字节打印流:System.err

  • System 类中重定向标准输入/输出的类方法void setIn(InputStream in):将 SyStem.in 的输入重定向到其它输入流void setOut(PrintStream out):将 SyStem.out 的输出重定向到其它打印流void setErr(PrintStream err):将 SyStem.err 的输出重定向到其它打印流

数据流

  • DataInputStream:从二进制流中读取字节,并根据所有基本类型数据进行重构
  • DataOutputStream:将数据从任意基本类型转换为一系列字节,并将这些字节写入二进制流
  • 注意:writeXxx 和 readXxx 必须要对应起来,writeByte 写出的数据,此时只能使用 readByte 读取回来

Java 4 的 NIO

NIO与传统IO的比较
图 2 NIO与传统IO的比较

  • NIO 的三大重要组件:Channel(通道)、Buffer(缓冲区)和 Selector(选择器)
  • 通道(Channel)与传统 IO 中的流(Stream)类似,表示打开到 IO 设备(例如:文件、套接字)的连接,但通道是双向的,而 Stream 是单向的,输入流只负责输入,输出流只负责输出
  • 在 NIO 中,有 FileChannel、SocketChannel、ServerSocketChannel 和 DatagramChannel 4 种 Channel 对象,第一种是针对文件的,后三种是针对网络编程的
  • 唯一能与通道交互的组件是缓冲区(Buffer),通过通道,可以从缓冲区中读写数据
  • Buffer 对象用来缓存读写的内容,在 NIO 中,通过 Channel 对象来进行读写操作,通过 Buffer 对象缓存读写的内容
  • 选择器(Selector)可以同时监控多个 SelectableChannel 的 IO 状况,是非阻塞 IO 的核心
  • FileChannel 不能与 Selector —起使用,因为 FileChannel 不能切换到非阻塞模式

Java 7 的 NIO.2

Path 接口、Files 和 Paths 工具类

  • Paths 中的类方法Path get(String first, String… more)

  • Files 中的用于文件拷贝的类方法Path copy(Path source, Path target, CopyOption… options)long copy(InputStream in, Path target, CopyOption… options)long copy(Path source, OutputStream out)

  • Files 中其它的类方法:isHidden、readAllLines、size、write、list、walk、find

使用 FileVisitor 遍历文件和目录

  • Files 类遍历文件的类方法Path walkFileTree(Path start, FileVisitor<? super Path> visitor):遍历 start 路径下的所有文件和子目录Path walkFileTree(Path start, Set<FileVisitOption> options, int maxDepth, FileVisitor<? super Path> visitor):与上一个方法的功能类似,该方法最多遍历 maxDepth 深度的文件

  • 通过继承 SimpleFileVisitor(FileVisitor的实现类)来实现自己的 “ 文件访问器”

使用 WatchService 监控文件变化

访问文件属性