20190118——Java从入门到精通 第十五章 I/O(输入/输出)
在变量、数组和对象中存储的数据是暂时存在的,程序结束后它们就会丢失。为了能够永久地保存程序创建的数据,需要将其保存在磁盘文件中,这样就可以在其他程序中使用它们。Java的I/O技术可以将数据保存到文本文件、二进制文件,甚至是ZIP的压缩文件中,以达到永久性保存数据的要求。掌握I/O处理技术能够提高对数据的处理能力。
流
流是一组有序的数据序列,根据操作的类型,可分为输入流和输出流两种.I/O流提供了一条通道程序,可以使用这条通道把源中的字节序列送到目的地。虽然I/O流通常与磁盘文件存取有关,但是程序的源和目的地可以是键盘、鼠标、内存或者是显示器窗口
Java由数据流处理输入/输出模式,程序从指向源的输入流中读取源中的数据。源可以是文件、网络、压缩包或者是其他数据
输入流的指向是数据要达到的目的地,程序通过向输出流中写入数据把信息传递到目的地,
java语言定义了许多类专门负责各种方式的输入/输出,这些类都被放在java.io包中,其中,所有的输入流泪都是抽象类InputStream(字节输入流)或者抽象类Reader(字符输入流)的子类;而所有输出流都是抽象类OutputStream(字节输出流)或者抽象Writter(字符输出流)的子类。
输入流
InputStream类是字节输入流的抽象类,是所有字节输入流的父类。InputStream类的层次结构
该类中所有方法遇到错误时都会引发IOException异常,下面是对该类中的一些方法的简要说明。
read()方法:从输入流中读取数据的下一个字节,返回0~255范围内的int字节值,如果因为已经到达流末尾而没有可用的字节,则返回值为-1
read(byte[] b): 从输入流中读入一定长度的字节,并以整数的形式返回字节数
mark(int readlimit):在输入流的当前位置放置一个标记,readlimit参数告知此输入流在标记位置失效之前允许读取的字节数。
reset()方法:将输入指针返回到当前所做的标记处。
skip
markSupported()
close()方法:关闭此输入流并释放与该流支持的mark/reset操作
并不是所有的InputStream类的子类都支持InputStream中定义的所有方法
java中的字符是Unicode编码,是双字节的。InputStream是用来处理字节的,并不适合处理字符文本。Java为字符文本的输入专门提供了一套单独的类Reader,但Reader类并不是InputStream类的替换和,只是在处理字符串时简化了编程。Reader类是字符串输入流的抽象类,所有字符输入流的实现都是它的子类。
File类
File类是java.io包中唯一代表磁盘文件本身的对象。File类定义了一些与平台无关的方法来操作文件,可以通过调用File类中的方法,实现创建,删除,重命名文件等操作。FIle类的对象主要用来获取文件本身的一些信息,如文件所在的目录、文件的长度、文件读写权限等。数据流可以将数据写入到文件中,文件也是数据流最常用的数据媒体。
文件的创建与删除
File(String pathname)
该构造方法通过将给定路径名字符串转换为抽象路径名来创建一个新的File实例
File(String parent,String child)
parent:父路径 D:/
child: 子路径letter.txt
如果当前目录中不存在名称为word的文件,file类对象可通过调用createNewFile()方法创一个名称为word.txt的文件,如果存在,可以通过文件对象的delete()方法进行删除。
package chapter15;
import java.io.File;
public class FileTest {
public static void main(String[] args) {
File file=new File("d:/1.txt");
if(file.exists()){
file.delete();
System.out.println("文件已经删除了");
}else{
try{
file.createNewFile();
System.out.println("文件已经创建");
}catch (Exception e){
e.printStackTrace();
}
}
}
}
文件输入/输出流
程序运行期间,大部分数据都在内存中进行操作,当程序结束或关闭的时候,这些数据将要消失,如果需要将数据永久保存,可使用文件输入/输出流与指定的文件建立连接,将需要的数据永久保存到文件中
FILEInputStream output
FileInputStream与FileOutputStream类都用来操作磁盘文件。如果用户的文件读取需求比较简单,则可以使用FileInputStream类,该类继承自InputStream类。
构造方法如下:
FileInputStream(String name)
FileInputStream(File file)
第一个构造方法使用给定的文件name创建一个FileInputStream对象,第二个构造方法使用File对象创建FileInputStream对象,第一个构造方法比较简单,但是第二个构造方法允许把文件连接输入流之前对文件作进一步分析。
package chapter15;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileTest1 {
public static void main(String[] args) {
File file =new File("d:/1.txt");
try{
FileOutputStream out =new FileOutputStream(file);
byte buy[]="我有一头小毛驴,我从来也不骑。".getBytes();
out.write(buy);
out.close();
}catch(Exception e){
e.printStackTrace();
}
try{
FileInputStream input =new FileInputStream(file);
byte byt[]=new byte[1024];
int len=input.read(byt);
System.out.println("文件中的信息是"+new String(byt,0,len));
}catch (Exception e){
e.printStackTrace();
}
}
}
FileReader和FileWritter
使用FileOutputStream类向文件中写入数据与使用FileInputStream类从文件中将内容读出来,都存在一点不足,即这两个类只提供了对字节或字节数组的读取方法。由于汉字在文件中占用两个字节,如果使用字节流,读取不好会出现乱码现象,此时采用字符流Reader和Writer类即可避免这种现象。
FileReader和FileWriter字符流赌赢了FileInputStream和FileOutputStream类。FileReader流顺序地读取文件,只要不关闭流,每次调用read()方法就顺序地读取源中其余的内容,直到源的末尾或流被关闭。
带缓存的输入/输出流
缓存是I/O的一种性能优化,缓存流为I/O流增加了内存缓存区,有了缓存区,使得在留上执行其他方法都成为可能。
BufferedInputStream类可以对所有InputStream类进行带缓存区的包装以达到性能的优化。
BufferedInputStream有两个构造方法
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in,int size)
第一种形式的构造方法创建一个带有32字节的缓存流;第二种形式的构造方法按照指定的大小来创建缓存区。一个最优的缓存区的大小,取决于它所在的操纵系统、可用的内存空以及机器配置。从构造方法能看出。BufferedInputStream对象位于InputStream类UI想之前