IO

来源:互联网 发布:云计算世界排名 编辑:程序博客网 时间:2024/06/14 03:02
在变量、数组和对象中存储的数据时暂时存在的,程序结束后它们就会丢失。为了能够永久的保存程序创建的数据,需要将其保存在磁盘文件中,这样就可以在其他程序中使用它们。Java中的IO技术可以将数据保存到文本文件、二进制文件甚至是zip压缩文件中。以达到永久性保存数据的要求。
一、输入/输出流
流按操作数据分为两种:字节流与字符流(字符流的对象融合了编码表)。
流按流向分为:输入流,输出流。
字节流的抽象基类: InputStream,OutputStream 。
字符流的抽象基类 :Reader,Writer 。
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。 如:InputStream的子类FileInputStream;Reader的子类FileReader 。后缀名是父类名,前缀名是该类对象的功能。
1.输入流
InputStream类是字节输入流的抽象类,是所有字节输入流的父类。该类中所有方法遇到错误都会引发IOException异常。其中有下面几个常用的方法:
read()方法:从输入流中读取数据的下一个字节。返回0~255范围内的int字节值。如果因为已经到达流末尾而没有可用的字节,则返回-1。
read(byte[] b):从输入流读入一定长度的字节,并以整数的形式返回字节数。
close()方法:关闭此输入流并释放与该流关联的所有系统资源。
Reader类是字符输入流的抽象类,所有字符输入流的实现都是它的子类。Reader类中的方法与InputStream类中的方法类似(将字节数组改为字符数组)。
2.输出流
OutputStream类是字节输出流的抽象类,是所有字节输出流的父类。OutputStream类中的所有方法均返回void,在遇到错误时会引发IOException异常。常用方法如下:
write(byte b):将指定的字节写入此输出流。
write(byte[] b):将制定的字符数组写入此输出流。
write(byte[] b.int off,int len):将指定byte数组中从off位置开始的len个字节写入此输出流。
flush()方法:清空缓冲区并输出。
close()方法:关闭输出流。
Writer类是字符输出流的抽象类,是所有字符输出类的父类(写入的是字符串)。
二、File类
File类是java.io包中唯一代表磁盘文件本身的对象。File类定义了一些与平台无关的方法来操作文件,可以通过调用File类中的方法,实现创建、删除、重命名文件等操作。File类的对象主要用来获取文件本身的一些信息,如文件所在的目录、文件的长度、文件读写权限等。数据流可以将数据写入到文件中,文件也是数据流最常用的数据媒体。
1.创建
File f=new("f:/itheima.txt"); 
f.createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。 和输出流不一样,输出流对象一建立就创建文件,当文件已经存在时,会覆盖 。
File dir=new File("f:/com/itheima");
dir.mkdir():创建目录,并且只能创建一级目录,返回值为boolean 。
dir.mkdirs():创建目录,可以创建多级目录。
2.删除
boolean f.delete():删除失败返回false。
void deleteOnExit():在程序退出时删除指定文件。
3.判断
canExecute():是否能执行。
canRead():是否是可读的。
canWrite(0:是否可被写入。
exists():文件是否存在。
isFile():是否为文件。
isDirectory():是否为目录。
isHidden():是否隐藏。
isAbsolute():是否绝对路径。
注意:在判断文件对象是否是文件或者目录时,必须要先判断该文件对象封装的内容是否存在!
4.获取信息
getName():获取文件的名称。
getPath():相对路径。
getParent():获取文件的父目录如果此路径名没有指定父目录,则返回 null

getAbsolutePath():获取文件的绝对路径。
long lastModified():文件最后一次被修改的时间
long length():文件的长度(以字节为单位)。
boolean f1.renameTo(f2):重命名
5.File对象功能——文件列表
File[] files= File.listRoots():返回File数组,内容为有效盘符。
String[] names=f.list():返回其所有子目录的名称。调用list方法的File对象必须是封装了一个目录,并且该目录必须存在,否则会报NullPointerException,只能获取名称。
三、文件输入/输出流
1.FileInputStream和FileOutputStream类
FileInputStream类和FileOutputStream类都用来操作磁盘文件。FileInputStream类继承自InputStream类,提供了基本的文件读取能力。FileOutputStream类继承自OutputStream类,提供了基本的文件写入能力。
FileInputStream类常用的构造方法如下:
FileInputStream(String name):使用给定的文件名name创建一个FileInputStream对象。
FileInputStream(File file):使用File对象创建一个FileInputStream对象。
FileOutputStream类与FileInputStream类有相同的参数构造方法,创建一个FileOutputStream对象时,可以指定不存在的文件名,但此文件不能是一个已被其他程序打开的文件。
注意:FileOutputStream不需要刷新但仍要关闭资源.close()。
2.FileReader和FileWriter类
使用FileOutputStream类向文件中写入数据与使用FileInputStream类从文件中将内容读出来,都存在一点不足,即这两个类都只提供了对字节或字节数组的读取方法,由于汉字在文件中占用两个字节,如果使用字节流,读取不好可能会出现乱码现象,此时采取Reader和Writer类即可避免这种现象。
FileReader和FileWriter类对应了FileInputStream和FileOutputStream类。FileReader流顺序地读取文件,只要不关闭流,每次调用read()方法就顺序地读取源中其余的内容,直到源的末尾或流被关闭。

文本文件的两种读取方式 
第一种方式:read()
 FileReader fr=new FileReader("demo.txt");创建一个文件读取流对象,和指定名称的文件相关联。 要保证该文件是已经存在的,否则会发生异常FileNotFoundException 。
 int ch=fr.read(); 调用读取流对象的read方法 read方法一次读一个字符,而且自动往下读。
 while(true) {
 int ch=fr.read(); 
 if(ch==-1) break; 
 System.out.println("ch="+(char)ch); 
   } 
fr.close(); 
第二种方式:通过字符数组进行读取
FileReader fr=new FileReader("demo.txt"); 
定义一个字符数组,用于存储读到字符。 该read(char[])返回的是读到的字符个数。 
char[] buf=new char[1024]; 
int length=0; 
while( (length=fr.read(buf)) !=- 1) { 
System.out.println("num="+num"..."+new String(buf,0,length)); 
 fr.close();
 
文本文件的写入
FileWriter fw=new FileWriter("demo.txt"):创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。 而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。 其实该步就是在明确数据要存放的目的地。fw.write("adsd"):调用write方法,将字符串写入到流中。
fw.flush(): 刷新流对象中缓冲中的数据。 将数据刷到目的地中。  
fw.close(): 关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据,将数据刷到目的地中。 
flush刷新后流可以继续使用,close刷新后会将流关闭。
 四、带缓存的输入/输出流
缓冲区的出现提高了对数据的读写效率。缓冲区要结合流才可以使用,在流的基础上对流的功能进行了增强。缓冲区的出现是为了提高流的操作效率而出现的,所以在创建缓冲区之前,必须先有流对象。只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
1.BufferedInputStream与BufferedoutoutStream类
BufferedInputStream类可以对所有InputStream类进行带缓存区的包装以达到性能的优化。BufferedInputStream类有两个构造方法:
BufferedInputStream(InputStream in);
BufferedInputStream(InputStream in.int size)。
第一种形式的构造方法创建了一个带有32个字节的缓存流;第二种形式的构造方法按指定的大小来创建缓存区。一个最优的缓存区的大小,取决于它所在的操作系统、可用的内存空间以及机器配置。
使用BufferedOutputStream输出信息和用OutputStream输出信息完全一样,只不过BufferedOutputStream有一个flush()方法用来将缓存区的数据强制输出完。BufferedOutputStream类也有两个构造方法:
BufferedOutputStream(OutputStream out);
BufferedOutputStream(OutoutStream out,int size)。
第一种形式的构造方法创建了一个带有32个字节的缓存流;第二种形式的构造方法按指定的大小来创建缓存区。
flush()方法只对使用缓存区的OutputStream类的子类有效。当调用close()方法时,系统在关闭流之前。也会将缓存区中信息刷新到磁盘文件中。
2.BufferedReader与BufferedWriter类
BufferedReader与BufferedWriter类分别继承Reader类与Writer类。这两个类同样具有内部缓存机制,并可以以行为单位进行输入/输出。
BufferedReader类常用的方法:
read()方法:读取单个字符。
readLine()方法:读取一个文本行,并将其返回为字符串。若无数据可读,则返回null。
BufferedWriter类中的方法都返回void。常用的方法如下:
write(String s,int off,int len)方法:写入字符串的某一部分。
flush()方法:刷新该流的缓存。
newLine()方法:写入一个跨平台的行分隔符。
五、转换流
1.读取键盘录入 
System.out:对应的是标准输出设备,控制台 
System.in:对应的是标准输入设备,键盘 
 InputStream in=System.in; 
int ch=in.read(); 
System.out.println(ch);
2.读取转换流 
InputStreamReader in=InputStreamReader(InputStream in): 
字节流通向字符流的桥梁,将字节流对象转成字符流对象 
如何从键盘获取一行数据并输出: 
readLine方法时字符流BufferedReader的方法,而键盘录入的read方法是字节流InputStream的方法。 
(1)获取键盘录入对象: 
InputStream in=System.in; 
(2)将字节流对象转成字符流对象,使用转换流InputStreamReader 
InputStreamReader isr=new InputStreamReader(in); 
(3)为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader 
BufferedReader bufr=new BufferedReader(isr); 
以上三句等于 BufferedReader bufr= new BufferedReader(new InputStreamReader(System.in)); 
String line=null; 
while((line=bufr.readLine())!=null) 
{
 if("over".equals(line))
 break; 
 System.out.println(line); 
bufr.close();
3.写入转换流 
OutputStreamWriter osw=new OutputStreamWriter(OutputStream out); 
字符流通向字节流的桥梁。需要刷新 
OutputStream out=System.out;往屏幕输出
OutputStreamWriter osw=new OutputStreamWriter(out); 
BufferedWriter bufw=new BufferedWriter(osw); 
以上三句等于 BufferedWriter bufw= new BufferedWriter(new OutputStreamWriter(System.out)); 
bufw.write(line); 
bufw.newLine(); 
bufw.flush(); 
以上三句等于System.out.println(line);
六、打印流
打印流: 该流提供了打印方法,可以将各种数据类型的数据都原样打印。 
1.字节打印流: PrintStream 
构造函数可以接受的参数类型: 
(1)File对象       File 
(2)字符串路径 String 
(3)字节输出流 OutputStream 
2. 字符打印流: PrintWriter 
构造函数可以接受的参数类型: 
(1)File对象       File
(2)字符串路径 String 
(3)字节输出流 OutputStream 
(4)字符输出流 Writer
七、流操作的基本规律
通过两个明确来完成: 
1.明确源和目的。
 源:输入流。InputStream Reader 
 目的:输出流。OutputStream Writer 
2.操作的数据是否是纯文本 
 是:字符流 
 不是:字节流 
3.当体系明确后,再明确要使用哪个具体的对象。  通过设备来进行区分: 
源设备:内存 ArrayStream,硬盘 FileStream,键盘 System.in
目的设备:内存 ArrayStream,硬盘 FileStream,控制台 System.out
4.是否需要提高效率 
是:加入缓冲区 
如果存储时需要加入指定编码表,而指定的编码表只有转换流可以指定。所以要使用的对象是OutputStreamWriter。
八、IO异常处理方式
FileWriter fw=null;
try
fw=new FileWriter("demo.txt"); 
fw.write("abcdefg"); 
catch(IOException e) 
Syetem.out.println(e.toString()); 
finally 
  try 
if(fw!=null) 
  fw.close(); 
catch(IOException e) 
Syetem.out.println(e.toString()); 
}
0 0