谈谈Java的IO操作

1.方便的IO操作是每个成功的语言所必须具有的,但是要有好的IO库可不是件容易的事情,

因为不仅有三种不同的种类的IO需要考虑(文件、控制台、网络连接),而且需要通过大量不同的方式与它们通信(顺序、随机访问、二进制、字符、按行、按字等等)。
 
2.Java库的IO类分割为输入与输出两个部分,
通过继承,从InputStream(输入流)衍生的所有类都拥有名为read()的基本方法,用于读取单个字节或者字节数组。类似地,从OutputStream衍生的所有类都拥有基本方法write(),用于写入单个字节或者字节数组。然而,我们通常不会用到这些方法;它们之所以存在,是因为更复杂的类可以利用它们,以便提供一个更有用的接口。因此,我们很少用单个类创建自己的系统对象。一般情况下,我们都是将多个对象重叠在一起,提供自己期望的功能。我们之所以感到Java的流库(Stream Library)异常复杂,正是由于为了创建单独一个结果流,却需要创建多个对象的缘故。
很有必要按照功能对类进行分类。库的设计者首先决定与输入有关的所有类都从InputStream继承,而与输出有关的所有类都从OutputStream继承
 
3.InputStream 的类型
1) ByteArrayInputStream (字节数组)
允许内存中的一个缓冲区作为InputStream使用 从中提取字节的缓冲区/作为一个数据源使用。通过将其同一个FilterInputStream对象连接,可提供一个有用的接口

(2) StringBufferInputStream    (String对象)
将一个String转换成InputStream 一个String(字串)。基础的实施方案实际采用一个StringBuffer(字串缓冲)/作为一个数据源使用。通过将其同一个FilterInputStream对象连接,可提供一个有用的接口

(3) 文件
 
FileInputStream 用于从文件读取信息 代表文件名的一个String,或者一个File或FileDescriptor对象/作为一个数据源使用。通过将其同一个FilterInputStream对象连接,可提供一个有用的接口

(4) “管道”,它的工作原理与现实生活中的管道类似:将一些东西置入一端,它们在另一端出来。 (5) 一系列其他流,以便我们将其统一收集到单独一个流内。
(6) 其他起源地,如Internet
 
4.OutputStream的类型
(1).ByteArrayOutputStream 在内存中创建一个缓冲区。我们发送给流的所有数据都会置入这个缓冲区。 可选缓冲区的初始大小/用于指出数据的目的地。若将其同FilterOutputStream对象连接到一起,可提供一个有用的接口
(2).FileOutputStream 将信息发给一个文件 用一个String代表文件名,或选用一个File或FileDescriptor对象/用于指出数据的目的地。若将其同FilterOutputStream对象连接到一起,可提供一个有用的接口
 
5.FilterInputStream类型
(1).DataInputStream ,与DataOutputStream搭配使用,可以按照可移植方式从流读取基本数据类型,其构造函数参数为InputStream;
(2).BufferedInputstream, 可以防止每次读取是都得进行实际的写操作,代表"使用缓冲区",构造函数参数仍为InputStream;
 
6.FilterOutputStream类型
(1).DataOutputStream.....
(2).PrintStream,用于产生格式化输出,其中DataOutputStream处理数据的存储,PrintStream处理显示,构造函数参数为OutputStream;
(3).BufferedOutputStream.....
 
5.Reader和Writer(提供兼容Unicode与面向字符的IO功能)
(1).为了关联"字节"层次结构和"字符"层次结构需要适配器
InputStreamReader 可以把 InputStream 转换为Reader,
OutputStreamReader 可以把OutputStream 转换为 Writer
 
(2).
 
FileInputStream 对应  FileReader;
FileOutputStream 对应 FileWriter;
StringBufferInputStream 对应  StringReader;
 
(3).
FilterInputStream 对应 FilterReader
FilterOutputStream 对应 FilterWriter
BufferedInputStream 对应 BufferedReader
BufferedOutputStream 对应 BufferedWriter
PrintStream 对应  PrintWriter
StreamTokenizer 对应 StreamTokenizer
 
 
 
6..操作Java的IO的一般步骤:
(1).首先创建数据源IO,
(2).然后根据需要创建需要包装的IO类,其构造函数参数为已创建的数据源IO;
(3).操作得到的IO句柄;
示例程序:
 
我们以创建一个具有缓冲的文件输入流为例,假定需要从磁盘读取文件“E://Java/data.txt”:
// 创建一个FileInputStream:
FileInputStream fileInput = new FileInputStream(“E://Java/data.txt”);
// 创建一个BufferedInputStream:
BufferedInputStream bufferedInput = new BufferedInputStream(fileInput); 
// 现在得到的bufferedInput即是具有缓冲的文件输入流 
  或者进一步简写如下:
InputStream input = new BufferedInputStream(
new FileInputStream(“E://Java/data.txt”));
// 现在得到的input即是具有缓冲的文件输入流
 
6.常见读写示例:
(1).读写文本文件,
程序功能:读取一文本文件到内存中的String类型变量中,在终端显示内容,并复制内容到另外的文本文件中

package MyJava.Base;
import java.io.*;
public class TextReaderDemo

 public static void main(String[] args) throws IOException
 { 
  //读取文件中内容到BufferedReader;
  
  BufferedReader in=new BufferedReader(new FileReader("E://Java//JCreator2.5//加密解密.txt"));
  String str=new String();
  String s=new String();
  while((s=in.readLine())!=null)
   str+=s+"/n";
   
  in.close();
  
  System.out.println(str);
  
  
  
  PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter("E://Java//JCreator2.5//加密解密(copyt).txt")));
  
  BufferedReader outbfreader=new BufferedReader(new StringReader(str));
  while((s=outbfreader.readLine() )!=null)
   out.println(s);
  
  out.close();
 
}
 
(2).从控制台输入,
Java中从控制台输入比起C++好像复杂多了,毕竟C++只需要cin和cout就行了,Java有点复杂
BufferedReader stdin=new BufferedReader(new InputStreamReader(System.in));
String str=stdin.readLine();
 
(3).从内存中读取
StringReader in2=new StringReader(str); //其中str为String类型
int ch;
while((ch=in2.read())!=-1)
   System.out.printl((char)ch);
 
(4).读取二进制文件,读写二进制文件主要是通过字节流,而不是字符流,二进制文件可是图片之类的,下面的程序功能是复制一副图片

package MyJava.Base;
import java.io.*;
public class BinaryReaderDemo

 public static void main(String[] args) throws IOException
 { 
 //读取图片文件数据到InputStream;
 // byte bt[1024];
 // FileInputStream in=new FileInputStream(new File("E://Java//JCreator2.5//加密解密.txt"));
  File file=new File("C://Documents and Settings//luliuyan_1985//My Documents//My Pictures//cs.jpg"); 
  
  if(!file.exists() && !file.canRead())
  { 
   System.out.println("file don't exist or file cannot read!!");
   System.exit(1);
  }
  long len=file.length();
  byte[] buffer=new byte[(int)len];
  
  FileInputStream filein=new FileInputStream(file);
  
  
  //////////////////////////////////////////////////////////
  File file2=new File("E://Java//JCreator2.5//cs(copy).jpg");
  if(!file2.exists())
  { 
   file2.createNewFile();
  }
  
  FileOutputStream fileout=new FileOutputStream(file2,true);
  
  
  int ch=0;
  
  ///////////////////////////////
  //方式一:
  /*
  
  
  
  while((ch=filein.read())!=-1)
  { 
   fileout.write(ch);
  }
  */
  
  
  //方式二,执行效率比方式一高:
  /*
  while((ch=filein.read(buffer))!=-1)
  { 
   fileout.write(buffer);
  }
  */
  //方式三:
  while((ch=filein.read(buffer,0,(int)len))!=-1)
  { 
   fileout.write(buffer,0,(int)len);
  }
  filein.close();
  fileout.close();
 }
}
 
7.Java的序列化
(1).序列化的过程就是对象写入字节流和从字节流中读取对象。将对象状态转换成字节流之后,可以用java.io包中的各种字节流类将其保存到文件中,管道到另一线程中或通过网络连接将对象数据发送到另一主机。对象序列化功能非常简单、强大,在RMI、Socket、JMS、EJB都有应用。对象序列化问题在网络编程中并不是最激动人心的课题,但却相当重要,具有许多实用意义。
一:对象序列化可以实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。
二:java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。
  
    java序列化比较简单,通常不需要编写保存和恢复对象状态的定制代码。实现java.io.Serializable接口的类对象可以转换成字节流或从字节流恢复,不需要在类中增加任何代码。只有极少数情况下才需要定制代码保存或恢复对象状态。这里要注意:不是每个类都可序列化,有些类是不能序列化的,例如涉及线程的类与特定JVM有非常复杂的关系
 
(2).序列化的实例(过段时间给出集合容器方面知识的小程序)
posted @ 2012-03-22 17:31  yunxiange  阅读(243)  评论(0编辑  收藏  举报