Java IO系统
一,IO
1,输入(input)与输出(output)
Java语言在IO设计方面取得较大的成功,它是完全面 向对象的,主要采用装饰器模式避免大量的类,包括了最大的可能性,提供了较好的扩展机制。
Java的IO主要包含三个部分:
流式部分------IO的主体部分
非流式部分----主要包含一些辅助流式部分的类
文件读取部分的与安全相关的类以及与本地操作系统相关的文件系统的类
2,Java中的流操作分为两种:
基本字节流(InputStream读取,OutputStream写入)
字符流(Reader读取,Writer写入)
Java IO流可以概括为:两个对应、一个桥梁。两个对应指字节流(Byte Stream)和字符流(Char Stream)的对应,输入流和输出流的对应。一个桥梁指从字节流到字符流的桥梁 。
3,Java中,设计了四个抽象类来表示流:
InputStream,字节流,读取数据
OutputStream,字节流,写入数据
Reader,字符流,读取数据
Writer,字符流,写入数据
其他多种多样变化的流均是继承了他们,并进行了豪华装饰派生出来的加强版
下图是一个描述输入流和输出流的类层次图。
二,File类
1, File类对象表示磁盘上的文件或目录。它提供了与平 台无关的方法来对磁盘上的文件或目录进行操作。
代码展示:
package io;
import java.io.File;
import java.io.IOException;
public class Test01 {
public static void main(String[] args) {
File f1 = new File("bb.txt"); //在创建一个名为bb的txt文件
File f2 = new File("d:/aa/aa.txt"); //在D盘中创建一个名为aa的文件夹,并在文件夹里面创建一个名为aa的txt文件
File f3 = new File("d:/bb"); //在D盘中创建一个名为bb的文件夹
File f4 = new File("d:/cc/dd"); //在D盘中创建一个名为cc的文件夹,并在cc文件夹里面创建一个名为dd的文件夹
try {
boolean b1 =f1.createNewFile();
boolean b2 =f2.mkdir();
boolean b3 = f3.mkdir();
boolean b4 = f4.mkdirs();
if (b1&b2&b3&b4){
System.out.println("创建成功");
}else {
System.out.println("创建失败");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
结果展示:
创建成功
2,FileInputStream和FileOutputStream
FileInputStream
FileInputStream提供了测试文件大小的方法 available(),提供了关闭流的方法close(),使用 read()方法从数据源中读取数据。可以使用缓冲区, 通过指定byte[]b的大小来提高效率——如果不设计 缓冲区,那么只能一个字节一个字节的读取,效率太低。
可认为创建了一个瓢(缓冲区),能盛放200毫升的 水,使用这个瓢从缸里舀水到另外一个缸里,每次舀 到多少就倒多少(舀200ml就倒200ml,舀10ml就 倒10ml),如果什么也没有舀到,就停止取水。
在使用的时候,操作完成后,注意关闭文件流。
FileOutputStream
FileOutputStream类中提供了三种写入数据的write() 方法
代码展示:
复制图片:
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test02 {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("d:/ab.jpg");//原图片
fos = new FileOutputStream("d:/bb/as.jpg");//复制图片
} catch (FileNotFoundException e) {
e.printStackTrace();
}
byte [] b = new byte[1024];
int result = 0;
try {
while ((result=fis.read(b))!=-1){
fos.write(b,0,result);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fis.close(); //关闭数据流
fos.close(); //关闭数据流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果:
成功运行,图片成功复制。
3,BufferedReader和BufferedWriter
BufferedReader与BufferedWriter实现了自带缓冲 区的字符流高效读写,其最小操作单元为一个字符 (16位),同时,我们也可以自己指定缓冲区的大 小,默认的缓冲区有8192个字符,通常情况下已经 足够了
(1)BufferedReader
对比FileInputStream,我们发现它多了两个方法: readLine()和ready(),readLine()方法用于从缓冲区 每次读取一行,ready()用于判断文件是否被读取完毕。
BufferedReader在读取文字档案时,会先将数据资 料先读入缓冲区,而之后若使用read()等方法时,会 先从缓冲区中进行读取,如果缓冲区数据不足,才会 再从文件中读取,藉由缓冲区,可以减少对磁盘的 I/O动作,借以提高程序的效率
(2)BufferedWriter
该类具有缓冲区,所以在写入的过程是首先将字符填 充缓冲区(8192个字符),然后再将缓冲区的内容 交由操作系统写入磁盘上的文件,这样就提高了性能, 避免了对每个字符写入磁盘的频繁操作
flush()方法的作用就是将缓冲区内的数据传递给操作 系统,并通过操作系统写入磁盘。在调用close()方法 时,会自动调用flush()方法
(3)代码展示
package io;
import java.io.*;
public class Test03 {
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fot=null;
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
try {
fis = new FileInputStream("d:/bb/as.jpg");
fot = new FileOutputStream("d:/cc/dd/aa.jpg");
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fot);
byte[] b =new byte[1024];
int result=0;
try {
while ((result=bis.read(b))!=-1){
bos.write(b,0,result);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
try {
bis.close();
bos.close();
fis.close();
fot.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行成功:
三,Java字符集
在JVM内部,统一使用基于Unicode字符集的字符编码。
对于中文版操作系统来说,系统默认编码为GBK。
代码展示:
package io;
public class Text06 {
public static void main(String[] args) {
System.out.println(System.getProperty("file.encoding"));
}
}
运行结果:
四,PrinterWriter
PrintWriter类和BufferedWriter一样,也继承自 Writer类,它们的大部分功能是一样的。不同的是, BufferedWriter提供了缓冲区,能提供高效的数据写 入,而PrintWriter提供了数据的格式化,例如 print(boolean b)、print(char c)、print(double d) 及支持任意平台的换行方法println()等等,这使得我们的程序更加自由
1,代码展示:
package io;
import java.io.*;
public class Text04 {
public static void main(String[] args) {
BufferedReader br=null;
BufferedWriter bw=null;
try {
br = new BufferedReader(new FileReader("d:/bb/aa.txt")); //原版
try {
bw = new BufferedWriter(new FileWriter("d:/cc.txt")); //复制版
String temp = null;
while ((temp=br.readLine())!=null){
bw.write(temp);
bw.newLine();
}
bw.flush(); //刷新缓冲区
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
try {
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果:
2,代码展示
package io;
import java.io.*;
public class Test05 {
public static void main(String[] args) {
BufferedReader br=null;
BufferedWriter bw=null;
br = new BufferedReader(new InputStreamReader(System.in));
try {
bw = new BufferedWriter(new FileWriter("d:/bb/asd.txt"));
String temp=null;
while ((temp=br.readLine())!=null){
if (temp.equals("quit")){ //输入quit退出
break;
}
bw.write(temp);
bw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果:
总结:
File类的用来创建文件、文件夹,并实现对它们属性 的读取及修改。
字节流InputStream、OutputStream可以用来读取 二进制文件。
字符流Reader、Writer能够高效的读取文本文件。
Java提供了字节流向字符流的转换: InputStreamReader、OutputStreamWriter。
PrintWriter能够对通往输出流的数据进行格式化。