Java中I/O的分析
Java中I/O的原理:
在java程序中,对于数据的输入/输出操作以”流“的方式进行的。
流是内存中一组有序数据序列
Java将数据从源读入到内存当中,形成了流,然后这些流可以写到目的地。
Java中流按功能分为:节点流(原始流)和处理流(包裹流)
处理流是在节点流的基础上提供了更加强大的读写功能
Java中流按处理数据的不同分为字节流和字符流
字节流:以字节为单位来处理数据的,字节流数据为8位,一般用于对二进制的数据的读写,例如声音,图像等。
字符流:以字符为单位来处理数据的,一般用于读写文本文件的
字节流
- 字节流的基类是抽象类InputStream和OutpuStream。
- InputStream用于输入,OutputStream用于输出。
1 package src; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileNotFoundException; 6 import java.io.FileOutputStream; 7 import java.io.IOException; 8 9 public class Test { 10 11 public static void main(String[] args) { 12 //输入外->内,读入数据,输出:内->外,写数据 13 14 //任务:从file1文件读取数据到内存,a.输出到控制台验证,b.输出到file2文件中 15 //1,创建一个给予file1的文件对象,,创建一个给予file2的文件对象, 16 File f1=new File("c:\\file1.txt"); 17 18 File f2=new File("c:\\file2.txt"); 19 //2、 建立一个基于c:\\file1.txt文件的输入通道fis,建立一个基于c:\\file2.txt文件的输 出通道fos, 20 try { 21 FileInputStream fis=new FileInputStream(f1); 22 FileOutputStream fos=new FileOutputStream(f2); 23 //3、把通道fis数据读入到内存,从内存写到file2文件 24 int m; 25 while((m=fis.read())!=-1) 26 { 27 fos.write(m); 28 } 29 30 31 32 } catch (FileNotFoundException e) { 33 // TODO 自动生成的 catch 块 34 e.printStackTrace(); 35 } catch (IOException e) { 36 // TODO 自动生成的 catch 块 37 e.printStackTrace(); 38 } 39 40 41 42 } 43 }
InputStream类:InputStream类是一个输入流,同样也是一个字节流。
InputStream类是表示字节输入流的所有类的超类。其中定义了一些基本的读取字节数据流的方法,由其子类继承并扩展。
OutputStream类是所有输出流的父类,它是一个抽象类,不能被实例化。它提供了一系列和写数据有关的方法。
OutputStream类最重要的方法是写入数据的write()方法。
其它方法:
void close():当完成写操作后,应该关闭输出流。
void flush():OutputStream类本身的flush()方法不执行任何操作,它的一些带有缓冲区的子类(比如BufferedOutputStream和PrintStream类)覆盖了flush()方法。通过带缓冲区的输出流写数据时,数据先保存在缓冲区中,积累到一定程度才会真正写到输出流中。缓冲区通常用字节数组实现,实际上是指一块内存空间。flush()方法强制把缓冲区内的数据写到输出流中
字节流子处理流
缓冲字节流: BufferedInputStream和BufferedOutputStream是缓冲字节流,它们通过减少读写I/O设备次数来加快输入输出速度。
缓冲流不能独立存在。
数据流类:DataInputStream,DateOutputStream,可以按照与平台无关的方式从流中读取基本类型(int,char和long等)的数据.
FileInputStream和FileOutputStream只能读写字节,基本类型数据和字符串用数据流进行包装。
数据流不能独立读写。
处理流不能独立存在,必须依附于结点流
字符流
字符流的基类是抽象类Reader和Writer。Reader负责输入,Writer负责输出。
Reader类是一个输入流,同样也是一个字符流。Reader类是所有输入字符流的超类,也就是说所有的输入字符流都派生自Reader类,其中提供了很多关于字符流输入操作的方法
1 package src; 2 3 import java.io.File; 4 import java.io.FileNotFoundException; 5 import java.io.FileReader; 6 import java.io.FileWriter; 7 import java.io.IOException; 8 9 public class Test { 10 11 public static void main(String[] args) { 12 13 File f1=new File("d:\\file1.txt"); 14 15 File f2=new File("d:\\file2.txt"); 16 17 try { 18 FileReader fis=new FileReader(f1); 19 FileWriter fos=new FileWriter(f2); 20 21 int m; 22 while((m=fis.read())!=-1) 23 { 24 //输出到控制台上 25 //System.out.print((char)(m)); 26 //输出到file2.txt文件上 27 fos.write((char)(m)); 28 } 29 30 } catch (FileNotFoundException e) { 31 // TODO 自动生成的 catch 块 32 e.printStackTrace(); 33 } catch (IOException e) { 34 // TODO 自动生成的 catch 块 35 e.printStackTrace(); 36 } 37 } 38 }
字符流之处理流
和字节流一样,字符流也有处理流
缓冲流:BufferedReader输入流,BufferedWriter输出流
转换流:将字节流转换成字符流,InputStreamReader输入流,InputStreamWriter。、
处理流不能独立存在,必须依附于结点流。
系统类及流的概念
System类是Java语言中一个功能强大、非常有用的类,它提供了
标准输入/输出及运行时的系统信息。从System类不能创建对象,也
就是说,System类的所有属性和方法都是静态的,引用时要以
System作为前缀。System.in与System.out是System类的两个静态
属性,分别对应系统的标准输入/输出流。
其中,System.in称为标准输入流,用于程序输入,通常读取用户
从键盘输入的信息;System.out称为标准输出流,用于程序输出,
通常向用户显示信息;System.err称为标准错误流,用于向用户显示
出错信息。
System.in其实也是一个字节输入流。
System.in继承自InputStream类,所以InputStream类中的方法在System.in中都有。
1 package src; 2 3 import java.io.IOException; 4 5 public class Test { 6 7 public static void main(String[] args) { 8 9 System.out.println("请输入数据:"); 10 try { 11 int i = System.in.read(); 12 System.out.println("输入的数据为:"+(char)i); 13 } catch (IOException e) { 14 // TODO Auto-generated catch block 15 e.printStackTrace(); 16 } 17 } 18 }
1 //读取控制台信息到文件中去,当输入“q”时退出 2 package src; 3 4 import java.io.File; 5 import java.io.FileNotFoundException; 6 import java.io.FileOutputStream; 7 import java.io.IOException; 8 9 public class Test { 10 11 public static void main(String[] args) { 12 13 File f = new File("d:\\file1.txt"); 14 try { 15 FileOutputStream fop = new FileOutputStream(f); 16 while(true){ 17 //创建缓冲数组 18 byte[] b = new byte[1024]; 19 System.out.println("请输入数据:"); 20 //将输入的数据放入缓冲区中,返回输入的字符串 21 int len = System.in.read(b); 22 if(b[0]=='q'){ 23 System.out.println("退出"); 24 break; 25 }else{ 26 //将数据从0偏移开始读取len个字符 27 fop.write(b, 0, len); 28 } 29 } 30 } catch (FileNotFoundException e) { 31 // TODO Auto-generated catch block 32 e.printStackTrace(); 33 } catch (IOException e) { 34 // TODO Auto-generated catch block 35 e.printStackTrace(); 36 } 37 38 } 39 }
数据流
FileInputStream和FileOutputStream只能读写字节,如果我们要读写int、double或者字符串类型就要使用数据流进行包装。
数据流用DataInputStream和DataOutputStream类,不能独立读写,必须对字节流进行包装后才能读写数据。数据流也是一种字节流。
DataInputStream类
构造方法
DataInputStream(InputStream in)
成员方法
boolean readBoolean() //从输入流读取一个布尔值。
byte readByte() //从输入流读取一个byte值。
char readChar() //从输入流读取一个char值。
double readDouble() //从输入流读取一个double值。
float readFloat() //从输入流读取一个float值。
int readInt() //从输入流中读取一个int值。
String readUTF() //将输入流放回UTF字符串。
缓冲流(字符流)
BufferedReader和BufferedWriter类的作用与BufferedInputStream和BufferedOutputStream一样,通过内存缓冲区来减少I/O设备读写响应次数来提高输入输出速度。
BufferedReader和BufferedWriter是针对字符的缓冲输入输出流。同样它也不能独立读写数据必须包装字符流进行读写工作。
转换流
有时候我们需要将字节流转换成字符流,并且将字节流中读取到的字节按照指定字符集转换成字符并输入显示,或者将要写入的字符按照指定字符集转换成字节输出存储。这个时候就需要用到转换流。
JavaSE API提供了两个转换流:InputStreamReader和OutputStreamWriter。前者用于字节输入流的转换,后者用于字节输出流的转换。