ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

16.IO流

2021-10-09 13:31:11  阅读:179  来源: 互联网

标签:OutputStream IO 16 int InputStream File output 字节


IO流

Java的标准库java.io提供了File对象来操作文件和目录。构造File对象,需要传入文件路径
File对象有3种形式表示的路径:

  • 一种是getPath(),返回构造方法传入的路径
  • 一种是getAbsolutePath(),返回绝对路径
  • 一种是getCanonicalPath,它和绝对路径类似,但是返回的是规范路径

File对象既可以表示文件,也可以表示目录。构造一个File对象,即使传入的文件或目录不存在,代码也不会出错
构造一个File对象,并不会导致任何磁盘操作;只有当调用File对象的某些方法的时候,才真正进行磁盘操作
调用isFile(),判断该File对象是否是一个已存在的文件。调用isDirectory(),判断该File对象是否是一个已存在的目录

用File对象获取到一个文件时,还可以进一步判断文件的权限和大小:

  • boolean canRead():是否可读
  • boolean canWrite():是否可写
  • boolean canExecute():是否可执行
  • long length():文件字节大小

可以通过createNewFile()创建一个新文件,用delete()删除该文件


File file = new File("/path/to/file");
if (file.createNewFile()) {
    // 文件创建成功:
    // TODO:
    if (file.delete()) {
        // 删除文件成功:
    }
}

遍历文件和目录

使用list()和listFiles()列出目录下的文件和子目录名
通过以下方法创建和删除目录:

  • boolean mkdir():创建当前File对象表示的目录
  • boolean mkdirs():创建当前File对象表示的目录,并在必要时将不存在的父目录也创建出来
  • boolean delete():删除当前File对象表示的目录,当前目录必须为空才能删除成功

InputStream

InputStream是Java标准库提供的最基本的输入流。是一个抽象类,它是所有输入流的超类,定义的一个最重要的方法是int read(),读取输入流的下一个字节,并返回字节表示的int值(0~255),已读到末尾,返回-1表示不能继续读取

public abstract int read() throws IOException;

FileInputStream是InputStream的一个子类,从文件流中读取数据
用try(resource)来保证InputStream在无论是否发生IO错误的时候都能够正确地关闭

public void readFile() throws IOException {
    try (InputStream input = new FileInputStream("src/readme.txt")) {
        int n;
        while ((n = input.read()) != -1) {
            System.out.println(n);
        }
    } // 编译器在此自动为我们写入finally并调用close()
}

利用缓冲区一次性读取多个字节效率要高很多。InputStream提供了两个重载方法来支持读取多个字节:

  • int read(byte[] b):读取若干字节并填充到byte[]数组,返回读取的字节数
  • int read(byte[] b, int off, int len):指定byte[]数组的偏移量和最大填充数

利用上述方法一次读取多个字节时,需要先定义一个byte[]数组作为缓冲区,read()方法会尽可能多地读取字节到缓冲区, 但不会超过缓冲区的大小。read()方法的返回值不再是字节的int值,而是返回实际读取了多少个字节。如果返回-1,表示没有更多的数据了。

在调用InputStream的read()方法读取数据时,我们说read()方法是阻塞(Blocking)的,即必须等read()方法返回后才能执行后续代码,读取IO流相比执行普通代码,速度会慢很多

InputStream实现类
用FileInputStream可以从文件获取输入流,这是InputStream常用的一个实现类。

OutputStream

OutputStream是Java标准库提供的最基本的输出流,OutputStream也是抽象类,它是所有输出流的超类。定义的最重要的方法是void write(int b),写入一个字节到输出流。虽然传入的是int参数,但只会写入一个字节,即只写入int最低8位表示字节的部分(相当于b & 0xff)

public abstract void write(int b) throws IOException;

OutputStream提供了close()方法关闭输出流,以便释放系统资源。OutputStream还提供了一个flush()方法,将缓冲区的内容真正输出到目的地
通常情况下,不需要调用这个flush()方法,因为缓冲区写满了OutputStream会自动调用它,并且,在调用close()方法关闭OutputStream之前,也会自动调用flush()方法。但是,在某些情况下,我们必须手动调用flush()方法,例如聊天发送

OutputStream实现类
FileOutputStream实现将若干个字节写入文件流

public void writeFile() throws IOException {
    OutputStream output = new FileOutputStream("out/readme.txt");
    output.write(72); // H
    output.write(101); // e
    output.write(108); // l
    output.write(108); // l
    output.write(111); // o
    output.close();
}

public void writeFile() throws IOException {
    OutputStream output = new FileOutputStream("out/readme.txt");
    //OutputStream提供了重载方法void write(byte[])
    output.write("Hello".getBytes("UTF-8")); // Hello
    output.close();
}

需要用try(resource)来保证OutputStream在无论是否发生IO错误的时候都能够正确地关闭:

public void writeFile() throws IOException {
    try (OutputStream output = new FileOutputStream("out/readme.txt")) {
        output.write("Hello".getBytes("UTF-8")); // Hello
    } // 编译器在此自动为我们写入finally并调用close()
}

和InputStream一样,OutputStream的write()方法也是阻塞的。

同时操作多个AutoCloseable资源时,在try(resource) { … }语句中可以同时写出多个资源,用;隔开。例如,同时读写两个文件:

// 读取input.txt,写入output.txt:
try (InputStream input = new FileInputStream("input.txt");
     OutputStream output = new FileOutputStream("output.txt"))
{
    input.transferTo(output); //复制
}

Filter模式

为了解决依赖继承会导致子类数量失控的问题,JDK首先将InputStream分为两大类:一类是直接提供数据的基础InputStream,例如:FileInputStream、ByteArrayInputStream、ServletInputStream;一类是提供额外附加功能的InputStream,例如BufferedInputStream、DigestInputStream、CipherInputStream等
Filter模式即利用直接提供数据的基础InputStream得到数据源,再利用额外附加功能的InputStream提供附加功能,也称Decorator模式

序列化

可序列化的Java对象必须实现java.io.Serializable接口,类似Serializable这样的空接口被称为“标记接口”(Marker Interface);
反序列化时不调用构造方法,可设置serialVersionUID作为版本号(非必需);
Java的序列化机制仅适用于Java,如果需要与其它语言交换数据,必须使用通用的序列化方法,例如JSON

Reader & Writer

Reader是Java的IO库提供的另一个字符流输入流接口,以char为单位读取,定义了所有字符输入流的超类

  • FileReader实现了文件字符流输入,使用时需要指定编码;
  • CharArrayReader和StringReader可以在内存中模拟一个字符流输入。
    Reader是基于InputStream构造的:可以通过InputStreamReader在指定编码的同时将任何InputStream转换为Reader。使用try (resource)保证Reader正确关闭。
    Writer是带编码转换器的OutputStream,它把char转换为byte并输出,Writer定义了所有字符输出流的超类:
  • FileWriter实现了文件字符流输出;
  • CharArrayWriter和StringWriter在内存中模拟一个字符流输出。
    Writer是基于OutputStream构造的,可以通过OutputStreamWriter将OutputStream转换为Writer,转换时需要指定编码。使用try (resource)保证Writer正确关闭。

Files

Files和Paths是java.nio包里面的类,封装了很多读写文件的简单方法,如readAllBytes,readString,write,writeString
对于简单的小文件读写操作,可以使用Files工具类简化代码

标签:OutputStream,IO,16,int,InputStream,File,output,字节
来源: https://blog.csdn.net/christangdt/article/details/120669150

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有