8.0 java IO输入输出流
1.gbk 编码中文占用2个字节,英文占用1个字节。
2、utf-8编码中文占用3个字节,英文占用1个字节。
Java是双字节编码,utf-16be编码。即char占用2个字节。
注意:当你的字节序列是某种编码时,这个时候想把字节序列变成字符串,也需要用这种编码方式。否则会出现乱码。
文本文件就是字节序列,可以是任意编码的字节序列。但是如果我们在中文的机器上直接创建文件,那么该文件只认识ANSI编码。
8.1 File类常用的API介绍
Java.IO.File类用于表示文件(目录)
File类只用于表示文件(目录)的信息(大小,名称)等,不能用于文件内容的访问。
常用的API
booleanexists();判断文件是否存在
创建File对象:File file=new File(String path);这里path就是文件的绝对位置,如:c:\\file\\dooc 或者c:/file/dooc.txt都可以。
file.mkdir();创建目录
file.isDirectory();测试此抽象路径名表示的文件是否是一个目录。
file.isfile();测试此抽象路径名表示的文件是否是一个文件。
file.delete();删除这个文件或者目录
file.creatNewFile();创建新文件
file.getName();获取文件名或者目录的名称
file.getAbsolutepath();获取绝对路径
file.getParent();获取父级路径,如果没有则返回null
String[] list();返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
File[] listfiles();返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
File类中的list()方法用于列出当前的目录下的子目录和文件,返回的是字符串数组。直接列出子目录的文件,但不包含子目录的文件内容。
代码如下:
//实现一个遍历File对象的指定文件目录下的所有文件
public static void listDirectory(File dir) throws IOException{ //判断dir目录存不存在 try { if(dir.exists()){ System.out.println("该目录存在"); }else{ throw new IllegalArgumentException("这个目录不存在"); } } catch (Exception e) { // TODO: handle exception System.out.println(e); } //判断目录下是否有文件 try { if(dir.isDirectory()){ System.out.println("该目录存在文件夹"); }else{ throw new IllegalArgumentException("该目录不存在文件"); } } catch (Exception e) { // TODO: handle exception System.out.println(e); } //方法一是调用list()方法来遍历,该方法返回的是一个字符串类型的数组 //我们依次遍历看看看结果 // String[] strs=dir.list(); // //使用foreach语句来遍历 // for (String string : strs) { // System.out.println(dir+"\\"+string);//加上根目录显示 // } // // System.out.println("上面的方法只能显示到子文件类型,既不能显示具体" // + "的文件名称,也不能显示子文件下的文件"); System.out.println(""); //下面调用listFile()方法,该方法返回的是File对象的数组。同时可以直接获取file下的所有文件 File[] files=dir.listFiles(); if(files!=null && files.length>0){//获取的数组即不为空,也不为0长度数组 for (File file : files) { if(file.isDirectory()){//查看是否还有文件在下面 listDirectory(file);//递归调用,直到没有子文件为止 } else{ System.out.println(file); } } } }
总结:创建工具类:FileUtil包装了一些File的常用操作,例如过滤和遍历等:
1、列出指定目录下的(包含子目录)的所有文件。
如果传进来的目录不存在或者不是文件夹,则应该抛出异常。这时我们需要用到判断语句。
2、如:file.list()方法;该方法返回当前目录下的文件名的字符串数组,但是不包含子目录下的文件和目录。
3、File[] files=file.listFile();可以直接获取file文件下的所有文件或者目录。然后以File对象数组的形式返回。然后可以调用递归就可以把所有的目录下的文件路径读出来,或者获取文件。代码如上。
8.2RandomAccessFile类介绍
RandomAccessFile类对文件进行访问读写文件。随机访问文件即文件的任意的位置。
java文件模型在硬盘上的文件时byte byte byte存储的,是数据的集合。
打开文件
有2种模式可以打开文件:rw 读写模式和r只读模式
如:RandomAccessFile raf=new RandomAccessFile(file,”rw”);
这里file的初始化如下:File file=new File(String path);
其中在读写文件时会有文件指针的存在,打开文件时文件的指针在开头,即pointer=0;
写方法
raf.write(int);当写一个int型数据时只写一个字节(即最后8位),同时文件指针pointer指向下一个位置准备再次写入:
读方法
//读取指定长度的字节内容
raf.seek(0);//将文件指针指向最开始的头部
byte[] buf=new byte[(int)raf.length()];
raf.read(buf);//读取指定长度的字节内容,并将内容存储在buf数组中
//读取一个字节
raf.seek(0);//将文件指针指向最开始的头部
int b=raf.read();//只读取一个字节
文件读写完毕后,一定要记得关闭文件
raf.close();
代码如下:
package com.ll.iofile; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.util.Arrays; /** * 此方法用来测试RandomAccessFile类,用于读写文件 * @author LULEI * */ public class testRandomAccessFile { public static void main(String[] args) throws IOException{ // TODO Auto-generated method stub File file=new File("Demo");//判断相对路径中是否存在指定的目录 if(!file.exists()){ file.mkdir();//新建一个Demo目录 } File file2=new File(file,"wq.bat");//将指定的文件实例化给file2对象 if(!file2.exists()){ file2.createNewFile();//新建一个wq.bat文件 } //创建一个从中读取和向里面写入的一个随机访问的文件流.该文件要有指定的名称 RandomAccessFile raf=new RandomAccessFile(file2,"rw");//设置为读写模式 //首先观察一下文件指针的位置 System.out.println("文件指针的初始化位置在:"+raf.getFilePointer()); //向文件流中进行写,注意一次只写一个字节 raf.write('A');//注意char型字符占两个字节 System.out.println("文件指针的位置在:"+raf.getFilePointer()); String s="中"; byte[] sTObyte=s.getBytes("gbk");//设置为国标 raf.write(sTObyte); System.out.println("添加中文后的文件指针的位置:"+raf.getFilePointer()); int iNum=89; raf.write(iNum>>>24); raf.write(iNum>>>16); raf.write(iNum>>>8); raf.write(iNum>>>0); System.out.println("普通方法添加int型数据后的文件指针的位置:"+raf.getFilePointer()); byte[] bt={1,2,3,4}; //可以写数组 raf.write(bt); System.out.println("添加byte数组后的文件指针的位置:"+raf.getFilePointer()); //可以直接写一个Int类型的数据 raf.writeInt(20);//int占4个字节 System.out.println("添加int型数据后的文件指针的位置:"+raf.getFilePointer()); /* * 向文件流进行读操作 */ //一次只读一个字节的内容 raf.seek(0);//读取数据之前一定要将文件指针指向头部 int num=raf.read(); System.out.println("只读一个字节返回的内容:"+Integer.toString(num)); int num2=raf.read(); System.out.println("只读一个字节返回的内容(十六进制显示):"+Integer.toHexString(num2&0xff)); /*读取一定长度的字节的内容 * 读取文件前,一定要把文件指针指向开头 */ raf.seek(0); int n=(int)raf.length();//获取文件流中内容的字节长度 //创建一个同样长度大小的byte数组 byte[] buf=new byte[n]; raf.read(buf);//读取指定长度的字节内容,并将内容复制到buf数组中 System.out.println("读取一定长度返回的内容"); System.out.println(Arrays.toString(buf)); for (byte b : buf) { System.out.print(Integer.toHexString(b & 0xff)+" "); } /* * 最后关掉文件 */ raf.close(); } }
8.3 字节流
1、IO流(输入流、输出流)
字节流
InputStream、OutputStream
InputStream抽象了应用程序读取数据的方式
OutputStream抽象了应用程序写出数据的方式
EOF=EndOf File,表示已经读完。读到-1时表示读到文件的结尾。
输入流基本的操作方法
int b=in.read();读一个字节,无符号填充到int低八位,-1表示EOF。
in.read(byte[]buf);读取数据填充到字节数组buf中
in.read(byte[]buf,int start,int size);读取数据到字节数组buf。然后从buf的start位置开始存放size长度的数据
输出流本操作
out.write(intb);写一个byte到流中,写的内容是b的低8位
out.write(byte[]buf);将一个buf字节数组都写入到流
out.write(byte[]buf,int start,int size);字节数组buf从start位置开始写size长度的字节到流。
2、FileInputStream 具体实现了文件上的读取文件
注:1>单字节的读取即不用数组,在读取大文件时效率较低。
2>批量的读取,对于大文件而言效率较高,也是我们最常用的读取文件的方式。
3>byte类型8位,int类型为32位,为了避免数据类型的转换的错误。通过0xff将高24为清零。
4>read()适合单字节的读取大小
in.read(byte[] buf,int start,int size);字节数组适合读取大文件
3、FileOutputStream实现向文件中写出byte数据的方法。
文件输出流的写法:
1>FileOutputStream output=new FileOutputStream(file,true);//这个方法表示文件若不存在,则创建新的文件,若存在则在后面添加内容。
2>FileOutputStream output=new FileOutputStream(file);//这个方法表示文件不存在就创建新文件,若文件存在则先删除文件然后再创建文件。
3>在执行完output.write(byte[] buf,int start,int size)之后,一定要调用output.flush()方法来刷新。
代码如下:
package com.ll.iofile; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; /** * 这个方法是用来测试字符流的 * 主要用到是InputStreamReader 字符输出流 * OutputStreamWriter * @author LULEI * */ public class testInputStreamReaderAndOutputStreamWriter { public static void main(String[] args) throws IOException{ // TODO Auto-generated method stub /*这是测试第一个例子 * 就是将gbk编码的文件复制成utf-8格式的文件 FileInputStream in=new FileInputStream("DEMO\\fileio1.txt"); InputStreamReader isr=new InputStreamReader(in);//此处默认项目的编码是gbk的 */ /*这是测试第一个例子 * 就是将gbk编码的文件复制成utf-8格式的文件 FileOutputStream out=new FileOutputStream("Demo\\OutputStreamUTF8.txt"); OutputStreamWriter osw=new OutputStreamWriter(out,"utf-8"); */ FileInputStream in=new FileInputStream("C:\\Users\\Administrator\\Desktop\\OutputStreamUTF8.txt"); InputStreamReader isr=new InputStreamReader(in,"utf8");//这样的写法就是设置为utf8编码 FileOutputStream out=new FileOutputStream("Demo\\OutputStreamGBK.txt"); OutputStreamWriter osw=new OutputStreamWriter(out);//默认的编码就是gbk int c=0; /*这是单字节的输出 while((c=isr.read())!=-1){ System.out.print((char)c); } */ char[] buf=new char[20*1024]; while((c=isr.read(buf, 0, buf.length))!=-1){ // String str=new String(buf); // System.out.println(str); osw.write(buf,0,c); osw.flush(); } isr.close(); osw.close(); } }
8.4 数据输入输出流
它是字节流的一个拓展。它是用来帮助方便操作类型数据的。
1> 包含DataOutputStream和DataInputStream
2> 对“流“功能的扩展,可以更加方便的读取int,long,字符等类型数据。
3> DataOutputStream的方法:
writeInt()/writeDouble()/writeUTF()
4> DataInputStream的方法:
readInt()/readDouble()/readUTF()
代码如下:
package com.ll.iofile; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Array; import java.util.Arrays; /** * 这个类用于测试数据的输入输出流 * 即DataOutputStream 和DataInputStream * @author LULEI * */ public class testDataOutputStreamAndDataInputStream { public static void main(String[] args) throws IOException{ // TODO Auto-generated method stub //测试DataOutputStream类 String str="Demo\\wq77.txt"; DataOutputStream dos=new DataOutputStream( new FileOutputStream(str));//实例化一个对象 dos.write(10);//占一个字节 dos.writeInt(-10);//写一个int型整数,占4个字节 dos.writeDouble(10.8);//占8个字节 //以UTF-8的格式写入字符串 dos.writeUTF("中国");//一个汉子占3个字节 //以utf-16be的格式写入字符串 dos.writeChars("中国");//一个汉字占2个字节 dos.close(); //打印输出的文件的字节 IOUtils.printHexByByte(str); System.out.println(); //实例化数据输入流对象 DataInputStream dif=new DataInputStream(new FileInputStream(str)); int a=dif.read(); System.out.println(a); int b=dif.readInt(); System.out.println(b); double d=dif.readDouble(); System.out.println(d); String s1=dif.readUTF(); System.out.println(s1); byte[] bytes=new byte[6]; dif.read(bytes); System.out.println(Arrays.toString(bytes));//转换为字符串显示 dif.close(); } }
8.4BufferedInputStream&BufferedOutputStream
这两个流位于IO提供了带有缓冲区的操作,一般打开文件进行写入或读取操作时,都会加上缓冲,这种流模式提高了IO的性能。从应用程序中把输入放入文件,相当于将一缸水倒入另一个缸中。
1> FileOutputStream----》write方法相当于一滴一滴的把水转移过去。
2> DataOutputStream--àwriteXXX方法会方便一些,相当于一瓢一瓢的把水转移过去
3> BufferedOutputStreamàwrite()方法会更方便一些,相当于一瓢一瓢先放入水桶中,在从桶中倒入缸中,性能提高了。
代码如下:
package com.ll.iofile; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /* * 这个函数是为了测试BufferedOutputStream、FileOutputStream、DataOutputStream * 这三个类在copy文件时的速度快慢 */ public class testBufferedOutputStreamAndBufferedInputStream { public static void main(String[] args) throws IOException{ // TODO Auto-generated method stub File file=new File("C:\\Users\\Administrator\\Desktop\\浪潮之巅.pdf"); long start1=System.currentTimeMillis(); FileToCopyByByte(file); long end1=System.currentTimeMillis(); System.out.println(end1-start1); long start2=System.currentTimeMillis(); FileToCopy(file); long end2=System.currentTimeMillis(); System.out.println(end2-start2); long start3=System.currentTimeMillis(); DataToCopy(file); long end3=System.currentTimeMillis(); System.out.println(end3-start3); long start4=System.currentTimeMillis(); bufferedFileToCopy(file); long end4=System.currentTimeMillis(); System.out.println(end4-start4); } public static void FileToCopyByByte(File file)throws IOException{ if(!file.exists()){ System.out.println("文件"+file+"不存在"); } if(!file.isFile()){ System.out.println("文件"+file+"不是文件"); } FileInputStream fis=new FileInputStream(file);//实例化读取字节的文件流 //实例化写字节文件流 FileOutputStream fos =new FileOutputStream("Demo\\fileIoByByte1.pdf"); int b=0; while((b=fis.read())!=-1){ fos.write(b); } fis.close(); fos.close(); } public static void FileToCopy(File file)throws IOException{ if(!file.exists()){ System.out.println("文件"+file+"不存在"); } if(!file.isFile()){ System.out.println("文件"+file+"不是文件"); } FileInputStream fis=new FileInputStream(file);//实例化读取字节的文件流 //实例化写字节文件流 FileOutputStream fos =new FileOutputStream("Demo\\fileio1.pdf"); int length=0; byte[] buf=new byte[20*1024]; while((length=fis.read(buf, 0, buf.length))!=-1){ fos.write(buf); // fos.flush(); } fis.close(); fos.close(); } public static void DataToCopy(File dateFile)throws IOException{ if(!dateFile.exists()){ System.out.println("文件"+dateFile+"不存在"); } if(!dateFile.isFile()){ System.out.println("文件"+dateFile+"不是文件"); } //实例化一个读取文件的对象 DataInputStream dis=new DataInputStream(new FileInputStream(dateFile)); //实例化一个写文件的对象 DataOutputStream dos=new DataOutputStream(new FileOutputStream("Demo\\datafile1.pdf")); int length=0; byte[] buf=new byte[20*1024]; while((length=dis.read(buf, 0, buf.length))!=-1){ dos.write(buf); // dos.flush(); } //关闭文件 dis.close(); dos.close(); } public static void bufferedFileToCopy(File bufferedFile)throws IOException{ if(!bufferedFile.exists()){ System.out.println("文件"+bufferedFile+"不存在"); } if(!bufferedFile.isFile()){ System.out.println("文件"+bufferedFile+"不是文件"); } BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("Demo\\bufferedfile1.pdf")); BufferedInputStream bis=new BufferedInputStream(new FileInputStream(bufferedFile)); int length=0; byte[] buf=new byte[20*1024]; while((length=bis.read(buf, 0, buf.length))!=-1){ bos.write(buf); bos.flush(); } bis.close(); bos.close(); } }
8.5 字符流
1.编码问题(看前面所描述的)。
2.认识文本与文本文件
Java的文本(char型)是16为无符号编码,是字符的Unicode编码(双字节编码)
文本是byte byte byte的数据序列。
文本文件是文本(char)序列按照某种编码方案(utf-8,utf-16be,gbk)序列化为byte的存储。
3.字符流分为输入流(writer)和输出流(reader)。操作的是文本、文本文件字符的处理,一次处理一个字符。
字符的底层还是基本的字节序列。
字符流的基本实现:
InputStreamReader:完成byte流解析为char流,按照编码解析
InputStreamWriter:完成char流到byte流的解析,按照编码处理
4、FileReader&FileWriter:
可以直接写文件名的路径。与InputStreamReader相比坏处:无法指定读取和写出的编码,容易出现乱码。
FileReader fr=new FileReader(“Demo\\im.txt”);//输出流
FileWriter fw=new FileWriter(“Demo\\im2.txt”);输入流
8.6字节流的过滤器
BufferedReader--àreadLine();一次读取一行,但不能识别换行。。
BufferedWriter/PrintWriter--à一次写一行
如:一次写入一行
BufferedWriter PrintWriter
bw.wrire(line) pw.println(line);//自动换行,不加ln不换行
bw.newLine();//单独换行 pw.flush();//刷新数据
bw.flush();//刷新数据
代码如下:
package com.ll.iofile; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; /** * 这个例子是用来测试字节流的过滤器 * BufferedReader和BufferedWriter/PrintWriter类的使用 * @author LULEI * */ public class testBufferedReaderAndBufferedWriter { public static void main(String[] args) throws IOException{ // TODO Auto-generated method stub //实例化一个BufferedReader的对象 BufferedReader br=new BufferedReader(new InputStreamReader( new FileInputStream("C:\\Users\\Administrator\\Desktop\\搜狗.txt"))); //实例化一个BufferedWriter的对象 BufferedWriter wr=new BufferedWriter( new OutputStreamWriter( new FileOutputStream("Demo\\immoc1.txt"))); //实例化一个PrintWriter的对象 PrintWriter pw=new PrintWriter( new OutputStreamWriter( new FileOutputStream("Demo\\imooc2.txt"))); String line=new String(); while((line=br.readLine())!=null){ /*测试BufferedWriter的write方法 wr.write(line);//这样直接输入的只会在一行显示 wr.newLine();//这句话起到读取一行就换行的作用 wr.flush(); */ //System.out.println(line);//每读取一行字节,直接输出 //测试PrintWriter的方法 pw.println(line);//输出一行字节的内容,且加ln自动换行 pw.flush(); } wr.close(); br.close(); pw.close(); } }
8.7对象的序列化与反序列化
1、对象的序列化是指将object对象转换成byte序列,反之将byte序列转换为object对象称之为反序列化。
2、序列化流(objetcOutputStream),是过滤流---writeObject
反序列化流(objectInputStream),readObject的使用需要进行强制类型的转换。
3、序列化接口(serializable)
对象必须实现序列化接口才能进行序列化,否则将会出现异常。这个接口没有任何的方法,只是一个标准。
代码如下:
package com.ll.iofile; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * 这个类是用于测试对象的序列化和反序列化 * 调用ObjectOutputSrteam 和ObjectInputStream类的使用 * @author LULEI * */ public class testObjectSerializableDemo { public static void main(String[] args) throws Exception{ // TODO Auto-generated method stub //1、实现对象的序列化流的对象 String file="Demo/object.txt"; ObjectOutputStream oos=new ObjectOutputStream( new FileOutputStream(file)); //实例化一个MobilePhone对象 MobilePhone mp=new MobilePhone(4, 5.5f, "红米Note"); //开始写对象 oos.writeObject(mp); //刷新缓冲区数据 oos.flush(); oos.close(); //2实现对象的反序列化流对象 ObjectInputStream ois=new ObjectInputStream( new FileInputStream(file)); //必须进行强制类型转换 MobilePhone mps=(MobilePhone)ois.readObject(); System.out.println(mps); ois.close(); } } package com.ll.iofile; import java.io.Serializable; /** * 这个类是用于参与测试对象的序列化和反序列化 * ObjectOutputSrteam 和ObjectInputStream类的使用 * @author LULEI * */ //这里必须要继承serializable接口 public class MobilePhone implements Serializable { private int cpu; private float screen; private String name; public MobilePhone(){ } public MobilePhone(int cpu, float screen, String name) { super(); this.cpu = cpu; this.screen = screen; this.name = name; } public int getCpu() { return cpu; } public void setCpu(int cpu) { this.cpu = cpu; } public float getScreen() { return screen; } public void setScreen(float screen) { this.screen = screen; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "MobilePhone [cpu=" + cpu + ", screen=" + screen + ", name=" + name + "]"; } }
8.8 transient关键字
transient关键字修饰的属性默认是不能序列化的,但是可以使用writeObject自己完成这个元素的序列化。ArrayList就是用了此方法进行了优化的操作。ArrayList最核心的容器Object[] elementData使用了transient修饰,但是在writeObject自己实现对elementData数组的序列化。只能序列化数组中真实存在的元素,对于数组中的空的元素时不能进行序列化的。
如:
private void writeObject(java.io.ObjectOutputStream s) throws
java.io.IOException{
}
private void readObject(java.io.ObjectOutputStream s) throws
java.io.IOException,classNotFoundException{
}
代码如下:
package com.ll.iofile; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * 这个类是用于测试对象的序列化和反序列化 * 调用ObjectOutputSrteam 和ObjectInputStream类的使用 * 1、首先实例化ObjectOutputSrteam 和ObjectInputStream类的对象oos和ois * 2、实例化将要序列化的对象qq * 3、对象oos调用writeObject()方法来对对象qq进行序列化流的输出操作。 * 4、对象ois调用readObject()方法来进行反序列化的输入操作。同时要使用强制类型转换来转化 * 赋值给相应的实例化对象x。 * 4、最后直接输出x的内容 * @author LULEI * */ public class testTransient { public static void main(String[] args) throws IOException{ // TODO Auto-generated method stub //1、实例化首先实例化ObjectOutputSrteam 和ObjectInputStream类的对象 String file=new String("Demo\\testTransient"); ObjectOutputStream oos=new ObjectOutputStream( new FileOutputStream(file)); ObjectInputStream ois=new ObjectInputStream( new FileInputStream(file)); //2、实例化将要被序列化的对象MobilePhone MobilePhone2 mp=new MobilePhone2(4, 4.0f, "华为"); //3、oos对象调用writeObject()方法来进行序列化 oos.writeObject(mp); oos.flush();//刷新缓冲区 oos.close();//关闭文件流 //4、ois对象调用readObject方法来进行反序列化的操作,同时赋值给相应类型的对象 try { MobilePhone2 mps=(MobilePhone2)ois.readObject(); System.out.println(mps); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } ois.close(); } } package com.ll.iofile; import java.io.Serializable; /** * 这个类是用于参与测试对象的序列化和反序列化 * ObjectOutputSrteam 和ObjectInputStream类的使用 * 同时检测了transient关键字的使用 * @author LULEI * */ //这里必须要继承serializable接口 public class MobilePhone2 implements Serializable { private int cpu; //使用transient关键字修饰,这时screen的值不会被序列化。这时 //如果想进行序列化,只能够自己人为的进行序列化 private transient float screen; private String name; public MobilePhone2(){ } public MobilePhone2(int cpu, float screen, String name) { super(); this.cpu = cpu; this.screen = screen; this.name = name; } /*这里是自己认为的完成序列化的操作 //人工的进行序列化 private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ s.defaultWriteObject();//则是执行默认的序列化操作 s.writeFloat(screen);//自己人工的进行screen序列化操作 } //人工的进行反序列化的操作 private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject();//执行默认的反序列化的操作 this.screen=s.readFloat();//自己完成screen的反序列化的操作 } */ public int getCpu() { return cpu; } public void setCpu(int cpu) { this.cpu = cpu; } public float getScreen() { return screen; } public void setScreen(float screen) { this.screen = screen; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "MobilePhone [cpu=" + cpu + ", screen=" + screen + ", name=" + name + "]"; } }
8.9序列化过程中子父类构造函数的问题
1>父类实现了serializable接口,子类继承父类就可以序列化了。
2>但子类在进行反序列化的时候,父类 实现了序列化接口,则不会递归调用其构造函数。
3>父类未实现了serializable接口,子类自己实现了接口,子类可以自行实现可序列化。
4>子类在反序列化时,父类没有实现序列化的接口,则会递归调用其构造函数。
2015年3月29日 XXiaoLEI整理