重学Java 第 13 天 输入流输出流

299 阅读9分钟

Java输入/输出流

标准设备输入/输出

标准输入/输出类System[ˈsɪstəm]

​ System是 Java系统中最常使用的类,它是 Java的系统类。它包含了许多静态的方法和变量,因此我们可以直接调用System类函数和变量,而不需要实例化System类

​ System 类提供的静态方法中,包含了几类功能:

  • 标准输入、标准输出和错误输出流
  • 对外部定义的属性和环境变量的访问
  • 加载文件和库
  • 快速复制数组
  • 取得系统时间,即 System.currentTimeMillis()
  • 系统推出命令,即 System.exit()
  1. out 标准输出流——输出消息到控制台

    out 是 标准输入流。此流已打开并准备接收输出数据。通常,此流对应于显示器输出,或者由主机环境或用户指定的另一个输出目标

    System.out.println(data);
    

    out 对象的类型是 PrintStream。该类提供了一系列的print()函数,用于输出各种类型的数据

  2. err标准错误输出流——输出错误消息到控制台

    err 是标准 错误输出流。此流已打开并准备接收输出数据

    System.err.println(data);
    

    标准输出和标准出错的一个区别是,标准输出往往是带缓存的,而标准出错没有缓存

  3. in 标准输入流——接收键盘输入

    in 是标准输入流。此流已打开并准备提供输入数据。通常,此流对应于键盘输入,或者由主机环境或用户指定的另一个输入源

    in 对象的类型是 InputStream

控制台读写类 Console[kɑːnsoʊl]

  1. Console 类及输出消息方法

    此类包含多个方法,可访问与当前Java 虚拟机关联的基于字符的控制台设备,常指的就是键盘

    输出消息:

    System.console.printf(str);
    
  2. 读取密码

    如果应用程序需要读取密码或其他安全数据,则它应该使用 readPassword()或readPassword(String, Object),并在执行后手工将返回的字符数组归零,以最大限度地缩短内存中敏感数据的生存期

文件操作类File[faɪl]

​ FIle 类是Java文件处理的最基础的类,它用于实现对目录的创建、删除,对文件的创建、重命名、删除。因此,File 类操作的对象分两大类:目录和文件

  1. 创建 File 实例

    • File(String pathname):通过将给定路径名字符串转换为抽象路径名来创建新File实例
    • File(String pathname, String child):根据pathname路径名字符串和child路径名字创建一个新File 实例
    • File(URI uri):将给定的 file:URI 转换为一个抽象路径名来创建一个新的File实例
    • File(File file, String child):根据file 抽象路径名和child路径名字符串创建一个新File实例
  2. 判断是目录还是文件

    • isDirectory()[dəˈrektəri]:是否是目录
    • isFile():是否是文件
  3. 检查目录或文件是否存在

    通过exists()[ɪɡˈzɪsts]方法判断它是否存在

  4. 创建目录或文件

    • mkdir()[mkˈdɪr]:创建一个目录
    • mkdirs():创建所有目录
    • createNewFile():创建一个文件
  5. 查看目录下的文件列表,并输入路径名

    对于目录来说,可以使用listFiles()取得该目录下的文件列表,它返回的是一个File类型的数组。我们可以循环该数组取得每一个文件对象,并可以使用getAbsolutePath()取得该对象的路径名

    listFiles()取得的文件列表中,既包含目录也包含文件

  6. 重命名文件

    使用renameTo()函数重命名一个新的文件名

  7. 删除目录或文件

    对于目录和文件对象,可以执行delete()函数来删除目录或文件

文件搜索类 FileFilter[ˈfɪltər] 与 FIlenameFilter

299

文件随机读写类 Random[ˈrændəm]Access[ˈækses]File

​ RandomAccessFile 类能够随机访问文件,它将文件内容存储一个大型byte数组中。它存在着指向该隐含byte数组的光标或索引,称为文件指针,该指针位置可以通过seek方法设置。输入操作从文件指针开始读取字节,并随着对文件的读取而前移此文件指针

​ 通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出EOFException。如果有序某些原因无法读取任何字节,而不是在读取所需数量的字节之前已经到达文件末尾,则抛出IOException。如果流已关闭,则可能抛出IOException

  1. 打开与关闭文件

    • RandomAccessFile(File file,String mode):创建从中读取和向其中写入的随机访问文件流,该文件由File参数指定

    • RandomAccessFile(String name, String mode):创建从中读取和向其中写入的随机访问文件流,该文件由具有指定名称

      第一种是通过一个File对象创建,第二张直接指向文件名。 mode 表示对目标文件的访问模式

      含义
      r以只读方式打开。调用结果对象的任何 write 方法都将导致抛出IOException
      rw打开以便读取和写入,如果该文件尚不存在,则尝试创建该文件
      rws打开以便读取和写入。对于 rw ,还要求对文件内容或元数据的每个更新都同步写入到底层存储设备
      rwd打开以便读取和写入,对于 rw ,还要求对文件内容的每个更新都同步写入到底层存储设备

      然后在完成了对文件的一系列操作之后,还需要使用close()函数关闭文件(打开文件后必须关闭,否则该文件会被占用)

      1. 读取文件长度

        可以使用length()取得文件长度,该数值是该文件的字节数

      2. 设置文件指针位置

        打开文件后,默认的读取指针指向文件的最开始处,即0。RandomAccessFile 类之所以是随机访问类,就是因为它能够自动定位读取的指针。可以使用 seek(long pos) 方法来定位读取位置

  2. 读取文件

    打开文件后,即可从该文件中读取数据

    1. 读取一个数据字节: read()
    2. 读取字节数组:read(byte[] b)
    3. 灵活读取字节数组: read(byte[] b, int off, int len)
    4. 读取固定类型的数值
    5. 读取一行字符串:readLine()
    6. 读取中文字符: readUTF()
  3. 写入文件

    1. 写入一个数据字节: write()
    2. 写入字节数组: write(byte[] b)
    3. 灵活写入字节数组:write(byte[] b, int off, int len);
    4. 写入固定类型的数值
    5. 写入一个字符串:writeBytes()与writeChars()
    6. 写入中文字符:writeUTF()

输入/输出流

​ Java IO最关键的4个父类是:InputStream(输入字节流)、OutputStream(输出字节流)、Reader(输入字符流)、Writer(输出字符流)

​ InputStream 和 OutputStream 对于数据的传Reader 和 Writer 对于数据的传输是以字符character 为单位的

输入字节流输出字节流输入字符流输出字符流
抽象类InputStreamOutputStreamReaderWriter
转换类InputStreamReaderOutputStreamWriter
第一类:数据源类
数组ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWrite
文件FileInputStreamFileOutputStreamFileReaderFileWriter
对象ObjectInputStreamObjectOutputStream
字符串StringBufferInputStreamStringReaderStringWriter
第二类:数据流串联
管道PipedInputStreamPipedOutputStreamPipedReaderPipedWriter
序列SequenceInputStream
第三类:数据过滤流
过滤FilterInputStreamFilterOutputStreamFilterReaderFilterWriter
缓存BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter
数据DataInputStreamDataOutputStream
行号LineNumberInputStreamLineNumberReader
推回PushbackInputStreamPushbackReader
格式化PrintStreamPrintWriter

流的运作原理

​ 所谓流就是数据的有序排列,而流可以是从某个源(称为流源)出来,到某个目的地去

  • 根据流的方向不同,可以分成输入流和输出流,一个程序从输入流读取数据项输出流写数据

  • 根据流的数据类型不同,又可以分为字节流和字符流

    输入流和输出流是两个相反的流,一个负责读入数据,一个负责输出数据。而输入流和输出流还可以通过各种流的过滤器进行包装,形成流的链

  1. 输入流

  2. 输出流

  3. 输入流链

    Java 的 I/O库提供了一个称做链接(Chaining)的机制,可以将一个流处理器跟另一个流处理器首尾相接,以其中之一的输出作为另一个的输入,形成一个流管道的链接

  4. 输出流链

    DataOutputStream 可以将源数据转换成 Byte 类型的数据再输出

    流处理器所处理的流必定都有流的输入源

  • 第一类:数组、String、File...原始流源
  • 同样类型的流用做链接流类的源流,叫链接源流

输入流 InputStream

​ InputStream 的作用是标志那些从不同输入源产生输入的类。InputStream 是所有输入流的抽象父类,因此不能够直接构造 InputStream的实例,必须通过它的子类来进行构造。由于它是抽象类,因此提供了一些抽象接口和固有的 函数实现

输入源类型作用
ByteArrayInputStream把内存中的一个缓存区作为InputStream使用
FileInputStream把一个文件作为InputStream,实现对文件的读取操作
ObjectInputStream把一个对象作为InputStream实现对对象的读取操作
StringBufferInputStream把一个String对象作为InputStream
3个特殊实现
PipedInputStream实现了管道 (Pipe)的概念,主要在线程中使用
SequenceInputStream把多个InputStream 合并为一个 InputStream
FilterInputStream对输入流进行各种过滤操作
FilterInputStream还有一组过滤器的具体实现
BufferedInputStream缓存过滤器
DataInputStream数据过滤器
LineNumberInputStream行号过滤器
回退过滤器

输出字节流 OutputStream

​ OutputStream 的作用是接收输出字节,并将这些字节发送到某个接收器。

  • ByteArrayOutputStream:把信息存入内存中的一个缓存区中

  • FileOutputStream:把信息存入文件中

  • ObjectOutputStream:把一个对象作为OutputStream,实现对对象的写入操作

    有两个特殊操作

  • PipedOutputStream:实现了 pipe 的概念,主要在线程中使用

  • FilterOutputStream:对数据流进行各种过滤操作

    FilterOutputStream 还有一组过滤器的聚特实现

  • BufferedOutputStream:缓存过滤器

  • DataOutputStream:数据过滤器

  • PrintStream:格式化过滤器