流
I/O介绍
I/O的挑战:
- 与不同的源和接收端进行交互,包括文件、控制台、网络连接等
- 以不同的方式与它们进行通信(顺序、随机存取、缓冲、二进制、按照字符、按行、按字节等)
- 大多数I/O需要进行异常处理
java流式输入/输出原理
流是用来读写数据的,java有一个类叫File,它封装的是文件的文件名,只是内存里面的一个对象,真正的文件是在硬盘上的一块空间,在这个文件里面存放着各种各样的数据
想读文件里面的数据,需要通过一个流的方式来读。因为如果想从程序数据,对于计算机来说,无论读什么类型的数据都是以01010010这样的形式来读取的
输入输出流分类
java.io包中定义了多个流类型(类或抽象类)来实现I/O功能:可以从不同的角度对其进行分类:
- 按数据流的方向不同可以分为输入流和输出流
- 按处理数据单位不同可以分为字节流和字符流
- 按照功能不同可以分为节点流和处理流
字符流是一个字符一个字符地往外读取数据。一个字符是2个字节 字节流是最原始的一个流,读出来的数据就是010101这种最底层的数据表示形式,只不过它是按照字节来读的,一个字节是8位。
J2SDK所提供的所有流类型位于包java.io内都分别继承自以下四种抽象流类型 这四个类都是抽象类,可以把这四个类想象成四根不同的管道。一端接着你的程序,另一端接着数据源,你可以通过输出管道从数据源里面往外读数据,也可以通过输入管道往数据源里面输入数据。总之通过这四根管道可以让数据流进来和流出去
输入流和输出流都是站在程序的角度上来说的
节点流和处理流
节点流为可以从一个 特定的数据源(节点)读写数据(如:文件,内存) 处理流是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写能力
节点流的类型
节点流就是一根管道直接插到数据源上面,直接读数据源里面的数据,或者是直接往数据源里面写入数据
典型的节点流是文件流:文件的字节输入流(FileInputStream),文件的字节输出流(FileOutputStream)、文件的字符输入流(FileReader)、文件的字符输出流(FileWriter)
处理流的类型
处理流是包在别的流上面的流,相当于是包到别的管道上面的管道
InputStream(输入流)
继承来自InputStream(以流InputStream结尾)的,都是以字节的形式向我们的程序输入数据
InputStream的基本方法
- int read() throws IOException
//读取一个字节并以整数的形式返回(0~255) //如果返回-1表示已经到输入流的末尾 - int read (byte[] buffer) throws IOException
//读取一个字节并存储到一个数组buffer //返回实际读取的字节数,如果读取前已到输入流的末尾返回-1 - int read(byte[] buffer,int offset,int length) throws IOException
//读取length个字节,并存储到一个字节数组buffer,从数组offset位置开始 //返回实际读取的字节数,如果读取前已到输入流的末尾返回-1 - void close() throws IOException
//关闭流释放内存资源 - long skip (long n) throws IOException
//跳过n个字节不读,返回实际跳过的字节数
代码展示
int read() 方法展示
package InputStream;
import java.io.*;
public class First {
public static void main(String[] args) {
int b = 0;
FileInputStream in = null;
try{
in = new FileInputStream("D:\\java网络编程\\第二章\\test.txt");
}catch(FileNotFoundException e){
System.out.println("系统找不到指定文件!");
System.exit(-1);
}
long num = 0;
try{
while((b = in.read()) != -1){
System.out.print((char)b+"\t");
num++;
}
in.close();
System.out.println();
System.out.println("总共读取了"+num+"个字节的文件");
}catch (IOException e1){
System.out.println("文件读取错误!");
}
}
}
读取的文件内容: 输出结果: 这是因为中文是2个字节,而read()方法只能读取一个字节,于是展示出来的是乱码
int read(byte[]) 方法展示
byte[] arr = new byte[10];
try{
while((b = in.read(arr)) != -1){
System.out.println("总共读取了"+b+"个字节的文件");
for(int i = 0;i < arr.length;i++){
System.out.print((char)arr[i]+"\t");
}
System.out.println();
}
in.close();
System.out.println();
}catch (IOException e1){
System.out.println("文件读取错误!");
}
结果展示:
int read(byte[],off,len)方法展示:
byte[] arr = new byte[20];
try{
while( (b = in.read(arr,3,10) )!= -1) {
System.out.println("总共读取了" + b + "个字节的文件");
for (int i = 0; i < arr.length; i++) {
System.out.print((char) arr[i] + "\t");
}
System.out.println();
}
in.close();
System.out.println();
}catch(IOException e1){
System.err.print("文件读取错误");
}
注意,这里的offset是数组的,所以前面使用的10长度对于这里的3off和10len就不够用了,设成20后可行 结果展示:
void close()方法上面都有展示这里就跳过了 long skip(long)方法展示:
byte[] arr = new byte[20];
try{
long c = in.skip(3);
System.out.println("总共跳过"+c+"个字节");
while( (b = in.read(arr,3,10) )!= -1) {
System.out.println("总共读取了" + b + "个字节的文件");
for (int i = 0; i < arr.length; i++) {
System.out.print((char) arr[i] + "\t");
}
System.out.println();
}
in.close();
System.out.println();
}catch(IOException e1){
System.err.print("文件读取错误");
}
结果展示:
OutputStream输出流
OutputStream 继承自outputs team的流是用于程序中输入数据,且数据的单位为字节(8 bit);下图中深色为节点流,浅色为处理流
OutputStream的基本方法
- void write(int b)throws IOException
向输出流中写入一个字节数据,该字节数据为参数b的低8位 - void write(byte[] b)throws IOException
将一个字节类型的数组中的数据写入输出流 - void write (byte[] b ,int off , int len)throws IOException
将一个字节类型的数组中的从指定位置(off)开始的C,len个字节写入到输出流 - void close() throws IOException
关闭流释放内存资源 - void flush() throws IOException
将输出流中缓冲的数据全部写入到目的地
代码展示
write(int b)方法代码展示:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class write {
public static void main(String[] args){
int b =0;
FileOutputStream out = null;
try{
out = new FileOutputStream("D:\\java网络编程\\第二章\\test1.txt");
}catch(FileNotFoundException e){
System.err.println(e.getMessage());
}
Scanner scan = new Scanner(System.in);
try{
out.write(scan.nextInt());
}catch(IOException e){
System.out.println(e.getMessage());
}
}
}
结果: 输入了123,然后输出了},这是因为}的ASCII码是123
同理,用scan.nextByte输入也是同样的结果
write(Byte[])方法展示
byte[] c = new byte[10];
for(int i = 0;i<10;i++){
Scanner scan1 = new Scanner(System.in);
c[i] = scan1.nextByte();
}
try{
out.write(c);
out.flush();
out.close();
}catch(IOException e){
System.out.println(e.getMessage());
}
这里输入了长度为10的byte数组c之后,可以在test1文件中读到输入的对应ASCII码的结果
flush():清空缓冲区。 进行流的操作时,数据先被读到内存时,然后再将数据写到文件中,那么当你数据读完时,调用close()关闭读写流,这时就可能造成数据丢失。原因是:读入数据完成时不代表写入数据完成,一部分数据可能会留在缓冲区中,flush()方法就是去解决这个问题的,把最后缓冲区中的数据写入到文件中,这样就保证了数据的完整性。所以之后再调用close()方法关闭读写流。
Reader流
和InputStream一模一样,唯一的区别就在于读的数据单位不同
继承自Reader的流都是用于向程序中输入数据,且数据的单位为字符(16bit),下图中深色的为节点流,浅色的为处理流
Reader流的基本方法
- int read() throws IOEXception
//读取一个字符并以整数的形式返回(0~65535) //如果返回-1则代表已经到输入流的末尾 - int read(char[] cbuf)throws IOException
//读取一系列字符并存储到一个数组cbuf //返回实际读取的字符数,如果读取前已到输入流的末尾,则返回-1 - int read(char[] cbuf,int offset,int length)throws IOException
//读取length个字符,并存储到一个数组cbuf,从cbuf的offset位置开始存储 //返回实际读取的字符数,如果读取前已到输入流的末尾,则返回-1 - void close() throws IOException
//关闭流释放内存资源 - long skip (long n)throws IOException
跳过n个字符不读,返回实际跳过的字节数
代码展示
read() 方法展示:
package Reader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class ReaderDemo2 {
public static void main(String[] args) throws IOException {
Reader r = new FileReader("D://java网络编程//第二章//reader.txt");
int num = 0;
while((num = r.read())!= -1){
System.out.println(num);
}
r.close();
}
}
结果:
read(char[]) 方法展示:
package Reader;
import java.io.*;
import java.util.*;
public class ReaderDemo1 {
public static void main(String[] args) throws IOException{
Reader r = new FileReader("D://java网络编程//第二章//reader.txt");
char[] i = new char[3];
int num = 0;
while((num = r.read(i))!= -1){
System.out.println(new String(i));
}
r.close();
}
}
结果:
**read(char[],offset,len)**方法展示:
public class ReaderDemo3 {
public static void main(String[] args) throws IOException {
Reader r = new FileReader("D://java网络编程//第二章//reader.txt");
char[] i = new char[3];
int num = 0;
while((num = r.read(i,0,3))!= -1){
System.out.println(new String(i));
}
r.close();
}
}
结果: long skip(int)方法展示:
public static void main(String[] args) throws IOException {
Reader r = new FileReader("D://java网络编程//第二章//reader.txt");
char[] i = new char[3];
int num = 0;
long num1 = 0;
num1 = r.skip(3);
System.out.println(num1);
while((num = r.read(i))!= -1){
System.out.println(new String(i));
}
r.close();
}
结果:
Writer流
继承自Writer的流都是用于程序中输出数据,且数据的单位为字符(16bit);下图中深色为节点流,浅色为处理流
Writer流的基本方法
- void write(int c) throws IOException
//向输出流中写入一个字符数据,该字节数据为参数b的低16位 - void write (char[] cbuf)throws IOException
//将一个字符类型的数组中的数据写入输出流 - void write(char[] cbuf,int offset,int length)throws IOException
//将数组中的从指定位置(offset)开始的length个字符写入到输出流 - void write (String string)throws IOException
//将一个字符串中的字符写入到输出流 - void write(String string,int offset,int length) throws IOException
//将一个字符串从数组的offset开始的length个字符写入到输出流 - void close() throws IOException
//关闭流释放内存资源 - void flush() throws IOException
//将输出流中缓存的数据全部写入到目的地
代码展示
同上面的OutputStream类似 write() 方法展示:
FileWriter write= null;
try{
write = new FileWriter("D:\\java网络编程\\第二章\\test1.txt");
}catch(Exception e){
System.err.println(e.getMessage());
}
Scanner scan = new Scanner(System.in);
try{
write.write(scan.nextInt());
write.flush();
write.close();
}catch(Exception e1){
System.out.println(e1.getMessage());
}
在控制栏中输入了121,也就是y的ASCII码,得到结果:
write(char[]) 方法展示:
FileWriter write = null;
try{
write = new FileWriter("D:\\java网络编程\\第二章\\test1.txt");
}catch(Exception e){
System.out.println(e.getMessage());
}
char[] c = new char[3];
for(int i = 0;i<3;i++){
Scanner scan = new Scanner(System.in);
c[i] = scan.next().charAt(0);
}
try{
write.write(c);
write.flush();
write.close();
}catch(Exception e1){
System.out.println(e1.getMessage());
}
由于Scanner的返回值是String类型,无法直接放入char数组c中,所以这里用.charAt()方法,将String的第一位输入到c中
在控制栏中输入,你,我,他,(中间是回车)得到结果: 同理write(char[],offset,len)方法,这里就不多展示
write(String string) 方法展示:
Scanner scan = new Scanner(System.in);
try{
write.write(scan.next());
write.flush();
write.close();
}catch(Exception e1){
System.out.println(e1.getMessage());
}
在控制台中输入你我他123abc(连续的) 得到结果:
write(String ,offset,len方法同理,不予演示
节点流
以File这个类型作为讲解节点流的典型代表
FileInputStream和FileoutputStream分别继承自InputStream和OutputStream用于向文件中输入和输出字节
注意
- 在实例化FileInputStream和FileOutputStream流时要用try-catch语句以处理其可能抛出的FileNotFoundException
- 在读写数据时也要用try-catch语句以处理可能抛出的IOException
- FileNotFoundException是IOException的子类
常用构造方法
- public FileInputStream(File file);
//通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的File对象file指定 - public FileInputStream (String name);
//通过打开一个到实际文件的链接来创建一个FileInputStream,该文件通过文件系统中的路径名name指定 - public FileOutputStream(File file);
创建一个向指定File对象表示的文件中写入数据的文件输出流 - public FileOutputStream(File file ,boolean append);
创建一个向指定File对象表示的文件中写入数据的文件输出流,如果第二个参数为true,则将字节写入文件末尾处,而不是写入文件开始处 - public FileOutputStream(String name);
创建一个具有指定名称的文件中写入数据的输出文件流 - public FileOutputStream(String name,boolean append);
创建一个向具有指定name的文件中写入数据的输出文件流。如果第二个参数为true,则将字节写入文件的末尾处,而不是写入文件开始处
同理,这些基本方法也可以套用到FileWriter和FileReader里
代码实现
public class FileInputStreamDemo {
public static void main(String[] args) throws IOException {
File file = new File("D://java网络编程//第二章//test.txt");
File file1 = new File("D://java网络编程//第二章//test1.txt");
FileInputStream in = new FileInputStream(file);
FileOutputStream out = new FileOutputStream(file,true);
byte[] b = new byte[in.available()];
int length = 0;
while ((length = in.read(b)) != -1) {
System.out.print(new String(b));
}
in.close();
}
}
实例测试
FileInputStream读取文件
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TestFileInputStream {
public static void main(String args[]) {
int b = 0;
FileInputStream in = null;
try {
in = new FileInputStream("D://java网络编程//第二章//test.txt");
} catch (FileNotFoundException e) {
System.out.println("系统找不到指定文件!");
System.exit(-1);
}
long num = 0;
try {
while ((b = in.read()) != -1) {
System.out.print((char) b);
num++;
}
in.close();
System.out.println();
System.out.println("总共读取了" + num + "个字节的文件");
} catch (IOException e1) {
System.out.println("文件读取错误!");
}
}
}
FileOutputStream往一个文件里面写入数据
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFileOutputStream {
public static void main(String args[]) {
int b = 0;
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("D://java网络编程//第二章//test.txt");
out = new FileOutputStream("D://java网络编程//第二章//test1.txt");
while ((b = in.read()) != -1) {
out.write(b);
}
in.close();
out.close();
} catch (FileNotFoundException e) {
System.out.println("文件读取失败");
System.exit(-1);
} catch (IOException e1) {
System.out.println("文件复制失败!");
System.exit(-1);
}
System.out.println("TestFileInputStream.java文件里面的内容已经成功复制到文件TestFileOutStream1.java里面");
}
}
就是简单的把内容从文件a复制到文件b中
用FileWriter(字符流)向指定文件中写入数据,用FileReader(字符流)读取指定文件里面的内容
import java.io.FileReader;
import java.io.FileWriter;
public class TestFile_WR {
public static void main(String args[]) {
FileWriter fw = null;
try {
fw = new FileWriter("D://java网络编程//第二章//test1.txt");
for (int c = 0; c <= 60000; c++) {
fw.write(c);
}
fw.close();
int b = 0;
long num = 0;
FileReader fr = null;
fr = new FileReader("D://java网络编程//第二章//test1.txt");
while ((b = fr.read()) != -1) {
System.out.print((char) b + "\t");
num++;
}
fr.close();
System.out.println();
System.out.println("总共读取了" + num + "个字符");
} catch (Exception e) {
e.printStackTrace();
}
}
这里写入的是16位的整数,查看文件时会发现都是按一定规律排序的,而不是数字,可以把这里的write方法理解为多了一步,将数字转换为字符的步骤
处理流
缓冲流(Buffering)
定义
- 带有缓冲区的,缓冲流就是内存里面的一小块区域,读写数据时都是先把数据放到这块缓冲区域里面,减少IO对硬盘的访问次数,保护我们的硬盘
- 先把数据放置到缓冲区上,等到缓冲区满了以后,再一次吧缓冲区里面的数据写入到硬盘上或者读出来,这样可以有效地减少对硬盘的访问次数,有利于保护我们的硬盘
- 缓冲输入流支持其父类的mark和reset方法
- BufferedReader提供了readLine方法用于读取一行字符串(以\r或\n分隔),BufferedWriter提供了newLine用于写入一个行分隔符。
- 缓冲输出流,使用flush方法将会使内存中的数据立刻写出
缓冲流实例解析
- 往文件写入数据时,直接从节点流FileWriter写入觉得不好写,因此在节点流的外部报了一层处理流BufferedWriter,这样写入数据时是先通过处理流把数据写入到缓冲区(Buffer)里面,再通过节点流写入到文件
- 读取文件里面的数据时,通过节点流FileReader,直接读取数据是一个一个字符地读取,这样读取的效率太慢了,因此在节点流FileReader外部包了一层处理流BufferedReader处理流存放到内存的缓冲区里面,然后再使用flush()方法把缓冲区里面的数据立刻写出来
- 缓冲流要“套接”在相应的节点流之上,对读写的数据提供了级冲的功能,提高了读写的效率,同时增加了一些新的方法
代码演示
BufferedInputStream类实例
package BufferStream;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class TestBufferStream {
public static void main(String args[]) {
FileInputStream fis = null;
try {
fis = new FileInputStream("D://java网络编程//第二章//test.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
int c = 0;
System.out.println((char) bis.read());
System.out.println((char) bis.read());
bis.mark(23);
for (int i = 0; i <= 35 && (c = bis.read()) != -1; i++) {
System.out.print((char) c);
}
System.out.println();
bis.reset();
for (int i = 0; i <= 15 && (c = bis.read()) != -1; i++) {
System.out.print((char) c);
}
bis.reset();
bis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
没搞懂这个mark里面的readlimit有啥用
BufferedWriter与BufferedReader实例
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class TestBufferStream1 {
public static void main(String args[]) {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter("D://java网络编程//第二章//test.txt"));
String s = null;
for (int i = 0; i < 100; i++) {
s = String.valueOf(Math.random());
bw.write(s);
bw.newLine();
}
bw.flush();
BufferedReader br = new BufferedReader(new FileReader("D://java网络编程//第二章//test.txt"));
while ((s = br.readLine()) != null) {
System.out.println(s);
}
bw.close();
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
static String valueOf(double) 方法可以将double类型变成String Math.Random()方法不加参数,范围是0~1 newLine()方法使得每写入一个字符就换一次行
转换流
- InputStreamReader和OutputStreamWriter用于字节数据数据之间转换
- InputStreamReader需要和InputStream套接,OutputStreamWriter需要和OutputStream套接
- 转换流在构造时可以指定其编码集合
- 转换流有两种,一种叫InputStreamReader,另一种叫OutputStreamWriter。
- 如果用一个FileOutputStream流往文件里面写东西, 得要一个字节一个字节地写进去,但是如果我们在FileOutputStream流上面套上一个字符转换流,那我们就可以一个字符串一个字符串地写进去
代码实例
OutputStreamWriter实例
public class TestOutputStreamWriter {
public static void main(String args[]) {
try {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D://java网络编程//第二章//test.txt"));
osw.write("MircosoftsunIBMOracleApplet");
System.out.println(osw.getEncoding());
osw.close();
osw = new OutputStreamWriter(new FileOutputStream("D://java网络编程//第二章//test.txt", true), "ISO8859_1");
osw.write("MircosoftsunIBMOracleApplet");
System.out.println(osw.getEncoding());
osw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用getEncoding()方法获取当前系统的默认字符编码 在调用FileOutputStream的构造方法时,可以指定字符的编码方式
InputStreamReader实例
package 转换流;
import java.io.*;
public class TestInputStreamReader{
public static void main(String args[]){
try{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = null;
s = br.readLine();
while(s != null){
System.out.println(s.toUpperCase());
s = br.readLine();
if(s.equalsIgnoreCase("exit")){
break;
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
equalsIgnoreCase()方法可以对比变量的内容是否和预设的内容相同
数据流
- DataInputStream和DataOutputStream分别继承自InputStream和OutputStream,它属于处理流需要分别“套接”在InputStream和OutputStream类型的节点流上
- DataInputStream和DataOutputStream提供了可以存取与机器无关的JAVA原始类型数据等方法
代码实现
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
public class TestDataStream {
public static void main(String args[]) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
try {
dos.writeDouble(Math.random());
dos.writeBoolean(true);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
System.out.println(bais.available());
DataInputStream dis = new DataInputStream(bais);
System.out.println(dis.readDouble());
System.out.println(dis.readBoolean());
dos.close();
bais.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
在调用构造方法时,datastream就会在内存里面创建一个数组,类型应该取决于data使用的类型和流的类型(猜测) 在这里ByteArrayOutputStream就是创建一个Byte类型的字节数组,套接在OutputStream上可以处理int、double等类型的数据 用writeDouble()方法可以把double类型的数据写入Byte数组中 用writeBoolen()方法可以把boolen类型的数据写入Byte数组中 在调用ByteArrayInputStream的构造方法时,通过toByteArray()方法访问之前baos的数组 再调用read方法读取存储在数组中的数据,这里的读取顺序不能更改,一定要什么先放入数组,先读什么,否则会打印出不正确的结果
打印流(Print)
- PrintWriter和PrintStream都属于输出流,分别针对于字符和字节。PrintWriter和PrintStream提供了重载的print
- Println方法用于多种数据类型的输出
- PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息
- PrintWriter和PrintStream有自动flush功能
代码实现
import java.io.FileOutputStream;
import java.io.PrintStream;
public class TestPrintStream {
public static void main(String args[]) {
PrintStream ps = null;
try {
FileOutputStream fos = new FileOutputStream("D:/CS/tmp/log.txt");
ps = new PrintStream(fos);
if (ps != null) {
System.setOut(ps);
}
for (char c = 0; c <= 60000; c++) {
System.out.print(c + "\t");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
setOut()方法将原本System.out.print()方法输出的位置改成了我们选择的路径 打印流不将结果打印在命令行界面,而是直接将结果打印到设置的路径 可以用于多种数据类型的输出 会自动flush()
对象流(Object)
直接将Object写入或读出
- transient关键字:transient透明的,用它来修饰的成员变量在序列化的时候不予考虑。也就是当成不存在
- serializable接口:标志性接口,通过这个接口标记的类的对象可以被序列化,并且是由JKD帮控制这个类的对象怎么序列化
- externalizable接口:通过这个接口标记的类就可以自己控制对象的序列化
代码实现
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class TestObjectIo {
public static void main(String args[]) {
T t = new T();
t.k = 8;
try {
FileOutputStream fos = new FileOutputStream("D:/CS/tmp/TestObjectIo.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(t);
oos.flush();
oos.close();
FileInputStream fis = new FileInputStream("D:/CS/tmp/TestObjectIo.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
T tRead = (T) ois.readObject();
System.out.print(tRead.i + "\t" + tRead.j + "\t" + tRead.d + "\t" + tRead.k);
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class T implements Serializable {
int i = 10;
int j = 9;
double d = 2.3;
int k = 15;
}
Serializable接口意思为可序列化的,要想将一个类的对象序列化成一个字节流就必须实现该接口 该接口没有定义方法,只能用作标记,只给编辑器看 在构造了一个对象t后,用writeObject()方法写入到文件中,用readObject()方法读出,新建一个T类型对象接收,通过访问他的变量,即可得到结果 如果将结果前加上transient关键词,则被当做不存在,在访问时,结果会返回0
|