04 IO流
概念
IO:我们把输入和输出的动作成为IO操作,以内存为中心。
-
把外部数据读入到内存,称为输入(读)Input操作。 例如,把文件从磁盘读取到内存,从网络读取数据到内存等等。
-
把数据从内存输出到外部,称为输出(写)Output操作。例如,把数据从内存写入到文件,把数据从内存输出到网络等等。
电脑上的数据有三种存储方式,一种是外存,一种是内存,一种是缓存。比如电脑上的硬盘,磁盘,U盘等都是外存,在电脑上有内存条,缓存是在CPU里面的。外存的存储量最大,其次是内存,最后是缓存,但是外存的数据的读取最慢,其次是内存,缓存最快。对于内存和外存的理解,我们可以简单的理解为容器,即外存是一个容器,内存又是另外一个容器。
文件:硬盘中,存储的是文件
File对象:Java中,把文件封装成File对象
流:是一个抽象的概念,在java中,对数据的输入输出操作都是以“流”的方式进行的。当程序需要从数据源中读入数据的时候就会开启一个输入流,相反,写出数据到某个数据源目的地的时候也会开启一个输出流。
IO流以byte(字节)为最小单位,因此也称为字节流。
一、File
常用方法:
①、创建方法 1.boolean createNewFile() 不存在返回true 存在返回false 2.boolean mkdir() 创建目录,如果上一级目录不存在,则会创建失败 3.boolean mkdirs() 创建多级目录,如果上一级目录不存在也会自动创建 ②、删除方法 1.boolean delete() 删除文件或目录,如果表示目录,则目录下必须为空才能删除 2.boolean deleteOnExit() 文件使用完成后删除 ③、判断方法 1.boolean canExecute()判断文件是否可执行 2.boolean canRead()判断文件是否可读 3.boolean canWrite() 判断文件是否可写 4.boolean exists() 判断文件或目录是否存在 5.boolean isDirectory() 判断此路径是否为一个目录 6.boolean isFile() 判断是否为一个文件 7.boolean isHidden() 判断是否为隐藏文件 8.boolean isAbsolute()判断是否是绝对路径 文件不存在也能判断 ④、获取方法 1.String getName() 获取此路径表示的文件或目录名称 2.String getPath() 将此路径名转换为路径名字符串 3.String getAbsolutePath() 返回此抽象路径名的绝对形式 4.String getParent()//如果没有父目录返回null 5.long lastModified()//获取最后一次修改的时间 6.long length() 返回由此抽象路径名表示的文件的长度。 7.boolean renameTo(File f) 重命名由此抽象路径名表示的文件。 8.File[] liseRoots()//获取机器盘符 9.String[] list() 返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录。 10.String[] list(FilenameFilter filter) 返回一个字符串数组,命名由此抽象路径名表示的目录中满足指定过滤器的文件和目录。
二、InputStream/OutputStream(输入/输出流,所有流的超类)
作用:在内存中操作“文件”数据,使用字节流来操作数据,操作的数据都是字节。 例如,创建文件之后,要向文件中写/读数据。
分类:字节输入流、字节输出流
- 字节输入流,读取文件/stream/数组 ---> inputStream流(内存中)。
- 方法:close()、 flush()、 read()、read(byte[] b)、 read(byte b[], int off, int len)
- read()(从(来源)输入流中(读取内容)读取的一定数量字节数,并将它们存储到(去处)缓冲区数组b中)
- available() 估计流的大小,需要重写,否则返回0
- 字节输出流,以字节流形式将内存中数据输出
- 方法:write(int b) 、write(byte[] b)、 write(byte[] b, int off, int len)
2.1 FileInputStream/FileOutputStream(文件流)
作用:对文件的字节流操作。 (文件存储在磁盘上)
分类:
- 文件输入流,从File中获得输入字节;
- 文件输出流,写入数据到File。
使用:
1、创建一个输入流/输出流对象(根据File对象/String文件名) FileOutputStream fos = new FileOutPutStream(file); FileOutputStream fos = new FileOutPutStream("filename");
2、使用方法read(从流读取)/write(写入数据到流)
2.2 ByteArrayInputStream/ByteArrayOutputStream(内存流)
作用:对字节数组的流操作。 (在内存中的存储形式是字节数组)
分类:
- ByteArrayInputStream,从字节数组(内存)读取到inputStream流。 就是把一个字节数组 byte[] 包装了一下,使其具有流的属性,可顺序读下去。还可标记跳回来继续读。(inputStream = new ByteArrayInputStream(byte[] buf));
- ByteArrayOutputStream,从内存输出数据。
方法:
public byte[] toByteArray() // 将内存中的所有数据转换为字节数组(重要)
public String toString() // 使用平台默认的字符集,通过解码字节将缓冲区内容转换为字符串。
public void writeTo(OutputStream out) throws IOException // 将内存中所有数据输入到另一个输出流,可以是文件流也可以是网络流等。(重要)
注意:
1、使用时注意OOM问题
2、这两个流虽然被称作「流」,但是它们本质上并没有像真正的流一样去分配一些资源,所以我们无需调用它的 close 方法,调了也没用(人家官方说了,has no effect)。
2.3 BufferedInputStream/BufferedOutputStream(高效缓冲流)
作用:为其它输入流提供缓冲功能,提供高效的io流操作。
分类:字节缓冲流:BufferedInputStream,BufferedOutputStream
字符缓冲流:BufferedReader,BufferedWriter
本质:通过一个内部缓冲区数组实现的。例如,创建BufferedInputStream时,我们会通过它的构造函数指定某个输入流为参数,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。
使用:字节缓冲流 + 数组方式(最高效,按数组写入)感受缓冲流的高效
其他:为另一个输入流添加一些功能,例如,提供“缓冲功能”以及支持“mark()标记”和“reset()重置方法”。
2.4 InputStreamReader/OutputStreamWriter(转换流)
作用:把字节流转换为字符流
分类 :InputStreamReader,把字节输入流转换为字符输入流
OutputStreamWriter,把字节输出流转换为字符输出流
2.5 SequenceInputStream/SequenceOutputStream(合并流)
作用:把多个输入流合并为一个流,也叫顺序流,因为在读取的时候是先读第一个,读完了在读下面一个流。
参考资料
http://c.biancheng.net/view/1144.html
https://www.runoob.com/java/java-bytearrayinputstream.html
https://blog.csdn.net/qiaojialin/article/details/81031598

浙公网安备 33010602011771号