基本IO操作
我们编写的程序除了自身会定义一些数据信息外,经常还会引用外界的数据,或是将自身的数据发送到外界。比如,我们编写的程序想读取一个文本文件,又或者我们想将程序中的某些数据写入到一个文件中。这时我们就要使用输入与输出。
InputStream是所有字节输入流的父类,其定义了基础的读取方法,常用的方法如下: int read()
读取一个字节,以int形式返回,该int值的”低八位”有效,若返回值为-1则表示EOF。
int read(byte[] d)
尝试最多读取给定数组的length个字节并存入该数组,返回值为实际读取到的字节量。
OutputStream是所有字节输出流的父类,其定义了基础的写出方法,常用的方法如下:
void write(int d)
写出一个字节,写的是给定的int的”低八位”
void write(byte[] d)
将给定的字节数组中的所有字节全部写出。
FileInputStream是文件的字节输入流,我们使用该流可以以字节为单位读取文件内容。
FileInputStream有两个常用的构造方法:
①FileInputStream(File file):
创建用于读取给定的File对象所表示的文件FIS
例如:
File file =newFile("demo.dat");
FileInputStream fis
=newFileInputStream(file);//创建一个用于读取demo.dat文件的输入流
②FileInputStream(String name):
创建用于读取给定的文件系统中的路径名name所指定的文件的FIS
例如
//创建一个用于读取demo.dat文件的输入流
=newFileInputStream("demo");
FileOutputStream是文件的字节输出流,我们使用该流可以以字节为单位将数据写入文件。
构造方法:
①FileOutputStream(File file):
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
例如:
FIle file =newFile("demo.dat");
FileOutputStream fos =newFileOutputStream(file);
②FileOutputStream(String filename):
创建一个向具有指定名称的文件中写入数据的输出文 件流。
例如:
FileOutputStream fos =newFileOutputStream("demo.dat");
通过上一节的构造方法创建的FOS对文件进行写操作时会覆盖文件中原有数据。若想在文件的原有数据之后追加新数据则需要以下构造方法创建FOS
构造方法:
①FileOutputStream(File file,boolean append):
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
例如:
File file =newFile("demo.dat");
FileOutputStream fos =newFileOutputStream(file,true);
②FileOutputStream(String filename,boolean append):
创建一个向具有指定名称的文件中写入数据的输出文 件流。
例如:
FileOutputStream fos =newFileOutputStream("demo.dat",true);
FileInputStream继承自InputStream,其提供了以字节为单位读取文件数据的方法read。
int read()
从此输入流中读取一个数据字节,若返回-1则表示EOF(End Of File).
FileOutputStream继承自OutputStream,其提供了以字节为单位向文件写数据的方法write。
void write(int d)
将指定字节写入此文件输出流。,这里指写给定的int值的”低八位”
例如
fos.write(‘A‘);//这里要注意,char占用2个字节,但这里只写入了1个字节。
FileInputStream也支持批量读取字节数据的方法:
int read(byte[] b)
从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中
FileOutputStream也支持批量写出字节数据的方法:
void write(byte[] d)
将 b.length 个字节从指定 byte 数组写入此文件输出流中。
例如:
FileOutputStream fos =newFileOutputStream("demo.txt");
byte[] data ="HelloWorld".getBytes();
fos.write(data);//会将HelloWorld的所有字节写入文件。
void write(byte[] d,int offset,int len)//将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
例如:
FileOutputStream fos =newFileOutputStream("demo.txt");
byte[] data ="HelloWorld".getBytes();
fos.write(data,5,5);//只会将world这5个字节写入文件。
在读取数据时若以字节为单位读取数据,会导致读取次数过于频繁从而大大的降低读取效率。为此我们可以通过提高一次读取的字节数量减少读写次数来提高读取的效率。
与缓冲输入流相似,在向硬件设备做写出操作时,增大写出次数无疑也会降低写出效率,为此我们可以使用缓冲输出流来一次性批量写出若干数据减少写出次数来提高写 出效率。
使用缓冲流来实现文件复制:
FileInputStream fis =newFileInputStream("java.zip");
BufferedInputStream bis =newBufferedInputStream(fis);
FileOutputStream fos =newFileOutputStream("copy_java.zip");
BufferedOutputStream bos =newBufferedOutputStream(fos);
int d =-1;
while((d = bis.read())!=-1){
bos.write(d);
}
bis.close();//读写完毕后要关闭流,只需要关闭最外层的流即可
bos.close();
使用缓冲输出流可以提高写出效率,但是这也存在着一个问题,就是写出数据缺乏即时性。有时我们需要需要在执行完某些写出操作后,就希望将这些数据确实写出,而非在缓冲区中保存直到缓冲区满后才写出。这时我们可以使用缓冲流的一个方法flush。
void flush()
清空缓冲区,将缓冲区中的数据强制写出。
例如:
BufferedOutputStream bos
=newBufferedOutputStream(
newFileOutputStream("demo.dat")
);
bos.write(‘a‘);//并没有向磁盘写出,而是写入到了BOS的缓存中
bos.flush();//强制将缓存中的数据一次性写出,这时‘a’才会被写入磁盘
bos.close();//实际上,close()方法在变比缓冲流前也调用了flush()
对象是存在于内存中的。有时候我们需要将对象保存到硬盘上,又有时我们需要将对象传输到另一台计算机上等等这样的操作。这时我们需要将对象转换为一个字节序列,而这个过程就称为对象序列化。相反,我们有这样一个字节序列需要将其转换为对应的对象,这个过程就称为对象的反序列化。
ObjectOutputStream是用来对对象进行序列化的输出流。
其实现对象序列化的方法为:
void writeObject(Object o)
该方法可以将给定的对象转换为一个字节序列后写出。
例如:
Emp emp =newEmp("张三",12,"男");
FileOutputStream fos =newFileOutputStream("Emp.obj");
ObjectOutputStream oos =newObjectOutputStream(fos);
oos.writeObject(emp);//将emp对象序列化后写入文件
oos.close();
ObjectInputStream是用来对对象进行反序列化的输入流。
其实现对象反序列化的方法为:
ObjectreadObject()
该方法可以从流中读取字节并转换为对应的对象。
例如:
FileInputStream fis =newFileInputStream("Emp.obj");
ObjectInputStream ois =newObjectInputStream(fis);
Emp emp =(Emp)ois.readObject();//将Emp对象从文件中读取并反序列
....
ois.close();
ObjectOutputStream在对对象进行序列化时有一个要求,就是需要序列化的对象所属的类必须实现Serializable接口。
实现该接口不需要重写任何方法。其只是作为可序列化的标志。
publicclass Emp implements Serializable{
privatestaticfinal long serialVersionUID =1L;
privateString name;
private int age;
privateString gender;
//getter and setter and other
...
}
对象在序列化后得到的字节序列往往比较大,有时我们在对一个对象进行序列化时可以忽略某些不必要的属性,从而对序列化后得到的字节序列”瘦身”。
关键字 transient
被该关键字修饰的属性在序列化时其值将被忽略.
例如:
publicclass Emp implements Serializable{
privatestaticfinal long serialVersionUID =1L;
privateString name;
privatetransient int age;//该属性在序列化时会被忽略
privateString gender;
//getter and setter and other
...
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u010111458/article/details/46969583