15.1输入/输出流
流是一组有序的数据序列,根据操作的类型,可分为输入流和输出流两种。I/O(Input/Output,输入/输出)流提供了一条通道程序,可以使用这条通道道把源中的字节序列送到目的地。虽然I/O流通常与磁盘文件存取有关,但是程序的源和目的地也可以是键盘、鼠标、内存或显示器窗口等。
1.Java有数据流处理输入/输出模式,程序从指向源的输入流中读取源中的数据。
2.输出流的指向是数据要到达的目的地,程序通过向输出流中写入数据把信息传递到目的地,如输出流的目标可以是文件、网络、压玉缩包、控制台和其他数据输出目标。
Java 语言定义了许多类专门负责各种方式的输入/输出,这些类都被放在java.io 包中。其中,所有输入流类都是抽象类InputStream(字节输入流流)或抽象类Reader(字符输入流)的子类;而所有输出流都是抽象类OutputStream(字节输出流)或抽象类Writer(字符输出流)的子类。
15.1.1 输入流
InputStream类是字节输入流的抽象类, 它是所有字节输入流的父类。
该类中所有方法遇到错误时都会引发IOEx ception 异常。下面是对该类中的一些方法的简要说明:
①read()方法:从输入流中读取数据的下一个字节。返回0~255的int字节值。如果因为已经到达流末尾而没有可用的字节,则返回值为-1。
②read(byte[]b):从输入流中读入一定长度的字节,并以整数的形式返回字节数。
③mark(int readlimit)方法:在输入流的当前位置放置一个标记,readlimit参数告知此输入流在标记位置失效之前允许读取的字节数。
④reset()方法:将输入指针返回到当前所做的标记处。
⑤skip(long n)方法:跳过输入流上的n个字节并返回实际跳过的字节数。
⑥markSupported()方法:如果当前流支持mark(/reset()操作就返回 true。
⑦close 方法:关闭此输入流并释放与该流关联的的所有系统资源。
Java 中的字符是Unicode编码,是双字节的。InputStrea am 类是用来处理字节的,并不适合处理字符文本。Java为字符文本的输入专门提供了一套单独的类,即 Reader 类,但Reader类并不是InputStream类的替换者,只是在处理字符串时简化了编程。Reader类是是字符输入流的抽象类,所有字符输入流的实现都是它的子类。
15.1.2 输出流
OutputStream类是字节输出流的抽象类,此抽象类是表示输出字节流的所有类的超类。
OutputStream类中的所有方法均返回void,在遇到错误时会引发IOException 异常。下面是对OutputStream类中的一些方法的简要说明:
①write(int b)方法:将指定的字节写入止比输出流。
②write(byte[] b)方法:将b个字节从指定的 byte 数组写入此输出流。
③write(byte[] b,int off,int len)方法:将指旨定 byte数组中从偏移量 off 开始的 len 个字节写入此输出流。
④flush()方法:彻底完成输出并清空缓存区。
⑤close()方法:关闭输出流。
Writer 类是字符输出流的抽象类,所有字符输出类的实现都是它的子类。
15.2 File类
File 类是 java.io 包中唯一代表磁盘文件本身的的类。File类定义了一些与平台无关的方法来操作文件,可以通过调用File类中的方法,实现创建、册刑除、重命名文件等操作。File类的对象主要用来获取文件本身的一些信息,如文件所在的目录、文件的长度、文件读写权限等。数据流可以将数据写入文件中,文件也是数据流最常用的数据媒体。
15.2.1 文件的创建与删除
可以使用File类创建一个文件对象。
1.File(String pathname)
该构造方法通过将给定的路劲名字符串转换为抽象路劲名来创建一个新File。
new File(Steing pathname)
其中,pathname代表路径名称(包括文件名)
File file=new File(“d:/1.txt”);
2. File(String parent,String child)
该构造方法根据定义的父路径和子路径字符串(包含文件名)创建一个新的File对象。语法如下:
new File(String parent,String child)
parent:父路径字符串,如D:/或D:/doc。
child:子路径字符串,如 letter.txt。
3.File(File f, String child)
该构造方法根据f抽象路径名和child 路径名字符串创建一个新File实例。语法如下:
new File(File f,String child)
f:父路径对象,如D:/doc/。
child:子路径字符串,如 letter.txt。
【例15.1]在D盘创建文本文件
在项目中创建FileTest类,在主方法中判断D盘的根目录是否存在word.txt文件,如果该文件存在则将其删除,不存在则创建该文件。
15.2.2 获取文件信息
【例15.2]读取文本文件的名称、长度和隐藏属性
获取D盘根目录下word.txt文件的文件名、文件长度,并判断该文件是否为隐藏文件。
15.3 文件输入/输出流
程序运行期间,大部分数据都在内存中进行操作,当当程序结束或关闭时,这些数据将消失。如果需要将数据永久保存,可使用文件输入/输出流与指定的文文件建立连接,将需要的数据永久保存到文件中,本节将讲解文件输入/输出流。
15.3.1 FilelnputStream与FileOutputStream 类
FilelnputStream类与FileOutputStream类都用来操作磁盘文件。如果用户的文件读取需求比较简单,则可以使用FileInputStream类,该类继承自InputStream类。FileOutputStream类与FileInputStream 类对应,提供了基本的文件写入能力。FileOutputStream类是OutputStream类的子类。
FileInputStream类常用的构造方法如下:
①FileInputStream(String name)。②FileInputStream(File file)。
第一个构造方法使用给定的文件名name创建一个FileInputStream对象,第二个构造方法使用File对象创建FileInputStream对象。第一个构造方法比较简单,但第二个构造方法允许在把文件连接输入流之前对文件做进一步分析。
FileOutputStream类有与FileInputStream类相同的参数构造方法,创建一个FileOutputStream对象时,可以指定不存在的文件名,但此文件不能是一个已被其他程序打开的文件。下面的实例就是使用 FileInputStream 类与FileOutputStream类实现文件的读取与写入功能的。
【例15.3】向文本文件中写入内容,再读取出来
使用FileOutputStream 类和FileInputStream类,向D盘根目录的word.txt文件中写入一句话,然后再读取出来输出在控制台上。
15.3.2 FileReader 和FileWriter类
使用FileOutputStream类向文件中写入数据与使用FileInputStream类从文件中将内容读出来,都存在一点不足,即这两个类都只提供了对字节或字节数组的读取方法。由于汉字在文件中占用两个字节,如果使用字节流,读取不好可能会出现乱码现象,此时采用字符流 FileReader类或 FileWriter类即可避免这种现象。
FileReader类和 FileWriter类对应了FileIng putStream 类和 FileOutputStream类。FileReader类顺序地读取文件,只要不关闭流,每次调用read()方法就就顺序地读取源中其余的内容,直到源的末尾或流被关闭。
【例15.4】使用字符流读写文本文件
使用FileWriter类和FileReader类,向D益盘根目录的word.txt 文件中写入一句话,然后再读取出来输出在控制台上。
import java.io.File;
import java.io.FileReader;
15.4 带缓存的输入/输出流
缓存是1/O的一种性能优化。缓存流为I/O流增加了内存缓存区,使得在流上执行skipO、mark( reset()方法都成为可能。
15.4.1 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)。
第一种构造方法创建一个有32个字节的缓存区,第第二种构造方法以指定的大小来创建缓存区。
15.4.2 BufferedReader与BufferedWriter 类
BufferedReader 类与 BufferedWriter类分别继承 Reader 类与Writer类。这两个类同样具有内部缓存机制,并能够以行为单位进行输入/输出。
BufferedReader类常用的方法如下:
①read()方法:读取单个字符。
②readLine()方法:读取一个文本行,并将其返回为字符串。若无数据可读,则返回null。BufferedWriter类中的方法都返回void。常用的方法如下:
①write(String s, int off, int len)方法:写入字符串的某一部分。
② flush)方法:刷新该流的缓存。
③newLine()方法:写入一个行分隔符。
在使用BufferedWriter类的Write()方法时,数据并没有立刻被写入输出流,而是首先进入缓存区中。如果想立刻将缓存区中的数据写入输出流,一定要调用flush()方法。
【例15.5】使用缓冲流读写文本文件
使用BufferedReader类和BufferedWriter类,向D盘根目录的word.txt文件中写入多行内容,然后再读取出来输出在控制台上。
15.5 数据输入/输出流
数据输入/输出流(DataInputStream类与DataOutputStream类)允许应用程序以与机器无关的方式从底层输入流中读取基本Java数据类型。也就是说,当读取一个数据时,不必再关心这个数值应当是哪种字节。DataInputStream类与DataOutputStream类的构造方法如下。
①DataInputStream(InputStream in):使用指定的基础InputStream对象创建一个DataInputStream
对象。
②DataOutputStream(OutputStream out):创建一个新的数据输出流,将数据写入指定基础输出流, DataOutputStream 类提供了将字符串、double 数据、int 数据、boolean数据写入文件的方法。其中,将字符串写入文件的方法有3种,分别是writeBytes(String s)、writeChars(String s)、writeUTF(String s)。由于Java中的字符是Unicode编码,是双字节的,writeBytes()方法只是将字符串中的每一个字符的低字节内容写入目标设备中:而writeChars)方法将字符串中的每一个字符的两个字节的内容都写到目标设备中: writeUTFO方法将字符串按照UTF编码后的字节长度写入目标设备,然后才是每一个字节的 UTF 编码。
DatalnputStream类只提供了一个readUTFO方法返回字符串。这是因为要在一个连续的字节流读取一个字符串,如果没有特殊的标记作为一个字符串的结尾,并且不知道这个字符串的长度,就无法知道读取到什么位置才是这个字符串的结束。DataOutputStream类中只有writeUTFO方法向目标设备中写入字符串的长度,所以也能准确地读回写入字符串。
【例15.6】使用数据流读写文本文件
分别通过DataOutputStream 类的writeUTFO)、writeDouble()、riteInt()和writeBoolean(方法向指定的 word.txt 文件中写入不同类型的数据,并通过DataInputStream类的相应方法将写入的数据输出到控制台上。