流概述
流是一组有序的数据序列,根据操作的类型,可分为输入流和输出流。I/O(Input/Output,输入/输出)流提供了一条通道程序,可以使用这条通道把源中的字节序列送到目的地。虽然I/O流通常与磁盘文件存取有关,但是程序的源和目的也可以是键盘、鼠标、内存或显示器窗口等。
Java由数据流处理输入/输出模式,程序从指向源的输入流中读取源中的数据。源可以是文件、网络、压缩包或其他数据源。
输出流的指向是数据要到达的目的地,程序通过向输出流中写入数据把信息传递到目的地。输出流的目的可以是文件、网络、压缩包、控制台和其他数据输出目标。
输入/输出流
Java语言定义了许多类专门负责各种方式的输入/输出,这些类都被放在java.io包中。其中,所有输入流都是抽象类InputStream(字节输入流)或抽象类Reader(字符输入流)的子类;而所有输出流都是抽象类OutputStream(字节输出流)或抽象类Writer(字符输出流)的子类
输入流
InputStream类是字节输入流的抽象类,是所有字节输入流的父类。
- read():从输入流读取下一个字节,返回0~255的一个int值,若因为到达字节流末尾而没有字节可以读取,则返回-1。
- read(byte[] b):从输入流中读取一定长度的字节,并以整数的形式返回字节数。
- mark(int readmit)方法:在输入流的当前位置放置一个标记,readlimit参数告知此输入流在标记位置失效之前允许读取的字节数。
- reset()方法:将输入指针返回到当前所做的标记处
- skip(long n)方法:跳过输入流上的n个字节并返回实际跳过的字节数
- markSupported()方法:如果当前流支持mark()/reset()操作就返回true
- close方法:关闭次输入流并释放与该流关联的所有系统资源。
说明:并不是所有的InpuStream类的子类都支持InputStream中定义的所有方法,如skip()、mark()、reset()等方法只对某些子类有用。
java中的字符Unicode编码,是双字节的。InputStream是用来处理字节的,并不适合处理字符文本。Java为字符文本的输入专门提供了一套单独的类Reader,但Reader类并不InputStream类的替换者,只是在处理字符串时简化了编程。Reader类是字符输入流的抽象类,所有字符输入流的实现都是它的子类。
输入流
OutputStream类是字节输出流的抽象类,此抽象类是表示输出字节流的所有类的超类。OutputStream类的具体层次。
OutputStream类中的所有方法均返回void,在遇到错误时会引发IOException异常。下面OutputStream类中的方法作简单的介绍。
- write(int b)方法:将指定的字节写入此输出流
- write(byte[] b):将b个字节从指定的byte数组写入此输出流。
- write(bute[] b, int offing len):将指定byte数组从偏移量off开始的len个字节写入此输出流。
- flush()方法:彻底完成输出并清空缓存区。
- close()方法:关闭输出流。
File类
File类是java.io包中唯一代表磁盘文件本身的对象。File类定义了一些与平台无关的方法来操作文件,可以通过调用File类中的方法,实现创建、删除、重命名文件等操作。File类的对象主要用来获取文件本身的一些信息,如文件所在的目录、文件的长度、文件读写权限等。数据流可以将数据写到文件当中,文件也是数据流最常有的数据媒体。
文件的创建与删除
可以使用File类创建一个文件对象。通常使用以下3种构造方法来创建文件对象。
(1)File(String pathname)
该构造方法通过将给定路径名字符串转换为抽象路径名创建一个新的File实例。
语法如下:
new File(String pathname)
其中,pathname指路径名称(包含文件名)。例如:
File file = new File("d:/1.txt");
(2)File(String parent,String child)
该构造方法根据定义的父路径和子路径字符串(包含文件名)创建一个新的File对象。
语法如下:
new File(String parent,String child)
- parent:父路径字符串。
- child:子路径字符串。
(3)File(File f,String child)
该构造方法根据parent抽象路径名和child路径名字符串创建一个新的File实例。
语法如下:
new File(File f,String child)
- f:父路径对象。例如,D:/doc/。
- child:子路径字符串。例如,letter.txt
说明:对于Microsoft Windows平台,包含盘符的路径名前缀由驱动器号和一个“:”组成。如果路径名是绝对路径,还可能后跟“\”
当使用File类创建一个文件对象后,例如:
File file = new File("word.txt");
如果当前目录中不存在名称为word的文件,File类对象可通过调用createNewFile()方法创建一个名称为word.txt的文件;如果存在word.txt文件,可以通过文件对象的delete()方法将其删除。
说明:由于D:/myword目录下部没有word.txt文件,因此运行程序会创建word.txt文件。
获取文件信息
File 类提供了很多方法用于获取一些文件本身信息,其中常用的方法如下表所示:
方法 | 返回值 | 说明 |
---|---|---|
getName() | String | 获取文件的名称 |
canRead() | boolean | 判断文件是否为可读的 |
canWrite() | boolean | 判断文件是否可被写入 |
exits() | boolean | 判断文件是否存在 |
length() | long | 获取文件长度(以字节为单位) |
getAbsolutePath() | String | 获取文件的绝对路径 |
getParent() | String | 获取文件的父路径 |
isFile() | boolean | 判断文件是否存在 |
isDiretory() | boolean | 判断文件是否为一个目录 |
isHidden() | boolean | 判断文件是否为隐藏文件 |
lastModified() | long | 获取文件最后修改时间 |
文件输入/输出流
如果需要将数据永久保存,可使用文件输入/输出流与指定的文件建立连接。
FileInputSream与FileOutputStream类
FileInputStream类与FileOutputStream都用来操作磁盘文件。如果用户的文件读取比较简单,则可以使用FileInputStream类,该类继承自InputStream类。FileOutputStream类与FileInputStream类对应,提供了基本的文件写入能力。FileOutputStream类是OutputStream类的子类。
FileInputStream类常用的构造方法如下:
- FileInputStream(String name)。
- FileInputStream(File file)。
第一个构造方法使用给定的文件名name创建一个FIleInputStream对象,第二个构造方法使用File对象创建FileInputStream对象。第一个构造方法比较简单,但第二个构造方法允许在把文件连接输入流之前文件作进一步分析。
FileOutputStream类有与FileInputStream类相同的参数构造方法,创建一个FileOutputStream对象时,可以指定不存在的文件名,但此文件不能是一个已被其他程序打开的文件。
说明:虽然Java在程序结束时自动关闭所有打开的流,但是当使用完流后,显式地关闭所有打开的流仍是一个好习惯。一个被打开的流有可能会用尽系统资源,这取决于平台和实现。如果没有将打开的流关闭,当另一个程序试图打开另一个流时,可能会得不到需要的资源。
FileReader和FileWriter类
使用FileOutputStream类向文件中写入数据使用FileInputStream类从文件内容读出来,都存在一点不足,即这两个类都只提供对字节或字节数的读取方法。由于汉字在文件中占用两个字节,如果使用字节流,读取不好可能会出现乱码现象,此时采用字符流Reader或Writer类即可避免这种现象。
FileReader和FileWriter字符流对应了FileInputStream和FileOutputStream类。FileReader流顺序地读取文件,只要不关闭流,每次调用read()方法就顺序地读取源中其余内容,直到源的末尾或流被关闭。
带缓存的输入/输出流
缓存是I/O的一种性能优化。缓存流为I/O流增加了内存缓存区。有了缓存区,使用在流上执行skip()、mark()和reset()方法都成可能。
BufferedInputStream与BufferedOutputStream类
BufferedInputStream类可以对所有InputStream类进行带缓存区的包装以达到性能的优化。BufferedInputStream类有两个构造方法:
- BufferedInputStream(InputStream in)。
- BufferedInputStream(InputStream in, int size)。
第一种形式的构造方法创建一个带有32个字节的缓存流;第二种形式的构造方法按指定的大小来创建缓存区。一个最优的缓存区的大小,取决于他所在的操作系统、可用的内存空间以及机器配置。从构造方法可以看出,BufferedInputStream对象位于InputStream类对象之前。
使用BufferedOutputStream输出信息和用OutputStream输出信息完全一样,只不过BufferedOutputStream有一个flush()方法用来将缓存区的数据强制输出完。BufferedOutputStream类也有两个构造方法: - BufferedOutputStream(OutputStream in)。
- BufferedOutputStream(OutputStream in, int size)。
注意:flush()方法就是用于即使在缓存区没有满的情况下,也将缓存区的内容强制写入到外设,习惯上称为这个过程为刷新。flush()方法只对使用缓存区的OutputStream()类的子类有效。当调用close()方法时,系统在关闭流之前,也会将缓存区中的信息刷新到磁盘文件当中。
BufferedReader与BufferedWriter类
BufferedReader类与BufferedWriter类分别继承Reader类与Writer类。这两个类同样具有内部缓存机制,并可以以行为单位进行输入/输出。
BufferedReader类常用的方法如下。
- read()方法:读取单个字符。
- readLine()方法:读取一个文本行,并将其返回为字符串。若无数据可读,则返回null。BufferedWriter类中的方法都返回void。常用的方法如下。
- write(String s, int off, int len)方法:写入字符串的某一部分。
- flush()方法:刷新该流的缓存。
- newLine()方法:写入一个行分隔符。
在使用BufferedWriter类的Write()方法时,数据并没有立刻被写入输出流,而是首先进入缓存区中。如果想立刻将缓存区中的数据写入输出流,一定要调用flush()方法。
数据输入/输出流
数据输入/输出流(DataInputStream类与DataOutputStream类)允许应用程序以与机器无关的方式从底层输入流中读取基本的Java数据类型。
其构造方法如下:
- DataInputStream(InputStream in):使用指定的基础InputStream 创建一个 DataInputStream.
- DataOutputStream(OutputStream out):创建一个新的数据输出流,将数据写入指定基础输出流DataOutputStream类提供了如下3种写入字符串的方法。
- writeBytes(String s)。
- writeChars(String s)。
- writeUTF(String s)。
由于Java中的字符是Unicode编码,是双字节的,writeBytes只是将字符串中的每一个字符的低节内容写入目标设备中;而writeChars将字符串中的每一个字符的两个字节的内容都写到目标设备中writeUTF将字符串按照UTF编码后的字节长度写入目标设备,然后才是每一个字节的UTF编码。
DatalnputStream类只提供了一个readUTF(方法返回字符串。这是因为要在一个连续的字节流读取一个字符串,如果没有特殊的标记作为一个字符串的结尾,并且不知道这个字符串的长度,就无法道读取到什么位置才是这个字符串的结束。DataOutputStrcam类中只有writeUTF(方法向目标设备中写 入字符串的长度,所以也能准确地读回写入字符串。
ZIP压缩输入/输出流
ZIP压缩管理文件(ZIP archive)是一种十分典型的文件压缩形式,使用它可以节省存储空间。
压缩文件
利用ZipOutputStream类对象,可将文件压缩为zip文件。ZipOutputStream类的构造方
ZipOutputStream(OutputStream out);
ZipOutputStream类的常用方法
方法 | 返回值 | 说明 |
---|---|---|
putNextEntry(ZipEntry e) | void | 开始写一个新的ZipEntry,并将流内的位置移至此entry所指数揭的 |
write(byte b,int off,int len) | void | 将字节数组写入当前ZIP条目数据 |
finish) | void | 完成写入ZIP输出流的内容,无须关闭它所配合的OutputStream 涂鸦 |
setComment(String comment) | void | 可设置此ZIP文件的注释文字 |
解压缩文件
ZiplnputStream类可读取ZIP压缩格式的文件,包括已压缩和未压缩的条目(entry)。ZipInputStream 类的构造方法如下:
ZiplnputStream(InputStream in)
ZipInputStream 类的常用方法
方法 | 返回值 | 说明 |
---|---|---|
read(byte[] b , int off,int len ) | int | 读取目标b数组内off偏移量的位置,长度是len 字节 |
available() | int | 判断是否已读完目前entry所指定的数据。已读完返回0. |
closeEntry() | void | 关闭当前ZIP条目并定位流以读取下一个条目 |
skip(long n) | long | 跳过当前ZIP条目中指定的字节数 |
getNextEntry() | ZipEntry | 读取下一个ZipEntry,并将流内的位置移至该entry所指数据的 |
createZipEntry(String name) | ZipEntry | 以指定的 name参数新建一个ZipEntry对象 |