谈谈Java的IO操作
1.方便的IO操作是每个成功的语言所必须具有的,但是要有好的IO库可不是件容易的事情,
因为不仅有三种不同的种类的IO需要考虑(文件、控制台、网络连接),而且需要通过大量不同的方式与它们通信(顺序、随机访问、二进制、字符、按行、按字等等)。
2.Java库的IO类分割为输入与输出两个部分,
通过继承,从InputStream(输入流)衍生的所有类都拥有名为read()的基本方法,用于读取单个字节或者字节数组。类似地,从OutputStream衍生的所有类都拥有基本方法write(),用于写入单个字节或者字节数组。然而,我们通常不会用到这些方法;它们之所以存在,是因为更复杂的类可以利用它们,以便提供一个更有用的接口。因此,我们很少用单个类创建自己的系统对象。一般情况下,我们都是将多个对象重叠在一起,提供自己期望的功能。我们之所以感到Java的流库(Stream Library)异常复杂,正是由于为了创建单独一个结果流,却需要创建多个对象的缘故。
很有必要按照功能对类进行分类。库的设计者首先决定与输入有关的所有类都从InputStream继承,而与输出有关的所有类都从OutputStream继承
很有必要按照功能对类进行分类。库的设计者首先决定与输入有关的所有类都从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) “管道”,它的工作原理与现实生活中的管道类似:将一些东西置入一端,它们在另一端出来。 (5) 一系列其他流,以便我们将其统一收集到单独一个流内。
(6) 其他起源地,如Internet
4.OutputStream的类型
(1).ByteArrayOutputStream 在内存中创建一个缓冲区。我们发送给流的所有数据都会置入这个缓冲区。 可选缓冲区的初始大小/用于指出数据的目的地。若将其同FilterOutputStream对象连接到一起,可提供一个有用的接口
(2).FileOutputStream 将信息发给一个文件 用一个String代表文件名,或选用一个File或FileDescriptor对象/用于指出数据的目的地。若将其同FilterOutputStream对象连接到一起,可提供一个有用的接口
(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即是具有缓冲的文件输入流
// 创建一个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();
{
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();
}
{
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有非常复杂的关系
一:对象序列化可以实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。
二:java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。
java序列化比较简单,通常不需要编写保存和恢复对象状态的定制代码。实现java.io.Serializable接口的类对象可以转换成字节流或从字节流恢复,不需要在类中增加任何代码。只有极少数情况下才需要定制代码保存或恢复对象状态。这里要注意:不是每个类都可序列化,有些类是不能序列化的,例如涉及线程的类与特定JVM有非常复杂的关系
(2).序列化的实例(过段时间给出集合容器方面知识的小程序)