Javo IO专题

来源:互联网 发布:高斯混合模型 java 编辑:程序博客网 时间:2024/05/19 17:50

Java IO 专题  

一、编码问题

从联通.txt和联.txt显示不正常,进而找到编码问题。
0xff 就是16进制数,前面全是0,后8位全为1。

import java.io.UnsupportedEncodingException;public class EncodeDemo  {public static void main(String[] args) throws UnsupportedEncodingException{String s = "慕课ABC";//获得本地默认的编码byte[] bytes1 = s.getBytes();for(byte b : bytes1){//把字节转换成int,以16进制的方式显示System.out.print(Integer.toHexString(b & 0xff)+"  ");}System.out.println();//转换成gbk编码byte[] bytes2 = s.getBytes("gbk");//gbk编码中文占用2个字节,英文占用1个字节for(byte b : bytes2){System.out.print(Integer.toHexString(b & 0xff)+"  ");}System.out.println();//utf-8 中,中文占3个字节,英文占1个字节,一个字节8bitbyte[] bytes3 = s.getBytes("utf-8");for(byte b : bytes3){System.out.print(Integer.toHexString(b & 0xff)+"  ");}//System.out.println();byte[] byte5 = new byte[]{(byte) 01110111,(byte) 11100101};String str0 = new String(byte5,"utf-16be");System.out.println(str0);//ystem.out.println(Integer.toHexString(0xa1+0xa2+0xb4+0xff),"GBK");//java是双字节编码 utf-16be//utf-16be 中文占用两个字节,英文也是占用两个字节byte[] bytes4 = s.getBytes("utf-16be");for(byte b : bytes4){System.out.print(Integer.toHexString(b&0xff)+"  ");}System.out.println();/* * 当你的字节序列是某种编码时,这个时候想把字节序列变成 * 字符串,也需要用这种编码方式,否则会出现乱码 */String str1 = new String(bytes4);//用项目默认的编码System.out.println(str1);String str2 = new String(bytes4,"unicode");System.out.println(str2);//使用java的双字节编码,utf-16beSystem.out.println(s);/* * 文本文件 就是字节序列 * 可以是任意编码的字节序列 * 如果我们在中文机器上直接创建文本文件,那么该文本文件只认识ANSI编码,别的不认识,但是文本文件本身可以放任何编码 * 联通,联  这是一种巧合,他们正好符合了utf-8编码的规则。纯属巧合 * 直接粘贴过来的都认识  * 什么编码项目认识什么样的东西  如果复制内容过去,会自动做转换。 */}}

输出如下:



二、File类的使用

注意:java.io.File类用于表示文件(目录)

File类只用于表示文件(目录)的信息(名称,大小等),不能用于进行文件的访问。

package com.Imooc;import java.io.File;import java.io.IOException;public class FileDemo {public static void main(String[] args){//了解构造函数的情况,查帮助   alt+///   ctrl+ // 得到的是注释这行File file = new File("E:\\kankan\\联通.txt");System.out.println(file.exists());if(!file.exists())file.mkdir();//file.mkdirs() 创建多级目录elsefile.delete();//是否是一个目录,如果是目录返回true,不是或不存在,返回falseSystem.out.println(file.isDirectory());//是否是一个文件System.out.println(file.isFile());File file2 = new File("E:\\kankan\\1.txt");if(!file2.exists())try {file2.createNewFile();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}elsefile2.delete();//常用的File对象的APISystem.out.println(file);//直接打印file.toString()内容,打印出来的是文件String名System.out.println(file.getName()+" 的绝对路径为::"+file.getAbsolutePath());System.out.println(file.getName());System.out.println(file2.getName());System.out.println(file.getParent());System.out.println(file2.getParent());System.out.println(file2.getParentFile());System.out.println(file.getParentFile().getAbsolutePath());System.out.println(file.getParentFile().getName());}}


System.out.println();快捷键,syso+Alt+/ 。 下面的程序,用来展示list的用法

先写一个类,用来写测试函数:

    下面方法中的递归,直接把函数再一次加进去,这样就达到了无限次的递归的原理,这样可以统计一个文件夹里共有多少个文件。

package com.Imooc;import java.io.*;//功能,列出File的一些常用操作,比如过滤,遍历目录等操作,包装成一个工具类public class FileUtils {/* * 列出指定目录下(包括其子目录)的所有文件 */public static void listDirectory(File dir) throws IOException{if(!dir.exists()){//写一半可以使用alt+/获取帮助throw new IllegalArgumentException("目录"+dir+"不存在");}if(!dir.isDirectory()){throw new IllegalArgumentException(dir+"不是目录");}/*//foreach出名字  list()返回一个String数组String[] filenames = dir.list();//list()方法用于列出当前目录下的子目录和文件,返回字符串数组,直接子的名称,不包含子目录下的内容for(String filename : filenames){System.out.println(dir+"\\"+filename);}*///需要增加判断。拿到文件名,再构造成一个File对象,递归遍历下面的内容。File提供了直接返回File对象的APIFile[] files = dir.listFiles();//返回的直接子目录(文件)的抽象if(files!=null && files.length>0){for(File file:files){if(file.isDirectory()){//递归listDirectory(file);}else{System.out.println(file);}}}/*for(File filename : files){//foreach语句if(filename.isDirectory()){//对下面的文件继续递归listDirectory(filename);//方法嵌套}elseSystem.out.println(filename);}*/}}
给一段加注释,①加//这样的注释,选中按“Ctrl+/”。②加/*   */ 这样的注释,按“Shift+Ctrl+/”。

下面再写一个测试类:

package com.Imooc;import java.io.*;public class FileUtilTest1 {public static void main(String[] args) throws IOException  {FileUtils.listDirectory(new File("E:\\java\\codes\\12"));}}
这样就把 “E:\java\codes\12”下的所有文件(包括子目录里的文件)全部列出

三、RandomAccessFile

RandomeAccessFile java提供的对文件内容的访问,即可以读文件,也可以写文件。RandomeAccessFile支持随机访问文件,可以访问文件的任意位置。

1、java文件模型

在硬盘上的文件是byte byte byte存储的,是数据的集合

2、打开文件
两种模式“”“rw”(读写),“r”(只读)
RandomeAccessFile raf = new RandomeAccessFile(file,"rw")
因为是随机访问文件,所以会包含一个文件指针,打开文件时,指针在开头,pointer=0; 这个指针会移动。
3、写方法
raf.write(int) ---> 只写一个字节(后8位),同时指针指向下一个位置。
4、读方法:
int b = raf.read() ---> 读一个文件,从指针出开始
5、file.close();
文件读写完后以后一定要关闭(否则会有意想不到的错误)
下面写一个类,完成的功能就是打开文件,然后RandomeAccessFile进行读写操作。
里面的0x7fffffff是int最大的,01111111111111111111111111111111,首位0是符号位,表示是正数。很多方法都可以边学编写。不用把所有的API都看一遍。
package com.Imooc;import java.io.*;import java.util.Arrays;public class RafDemo  {public static void main(String[] args) throws IOException{File file1 = new File(".");System.out.println(file1.getAbsolutePath());File demo = new File("demo");if(!demo.exists())demo.mkdir();File file = new File(demo,"raf.dat");if(!file.exists())//不存在就创建file.createNewFile();RandomAccessFile raf = new RandomAccessFile(file,"rw");//查看指针位置System.out.println(raf.getFilePointer());raf.write('A');//写一个字节,写入后八位,也有可能后八位代表System.out.println(raf.getFilePointer());//输出1raf.write('B');System.out.println(raf.getFilePointer());//输出2int i = 0x7fffffff;//一个字节是8位,一共四个字节//用write方法每次只能写一个字节,如果要把i写进去就得写4次raf.write(i>>>24);raf.write(i>>>16);raf.write(i>>>8);raf.write(i);System.out.println(raf.getFilePointer());//输出6//可以直接写一个int进去raf.writeInt(i);//又写了4个System.out.println(raf.getFilePointer());//输出10String s = "吕泽正";//6个字节byte[] gbk = s.getBytes("gbk");raf.write(gbk);System.out.println("现在文件中内容长度为(按照字节数来说):"+raf.length());//读文件,必须把指针移动到头部raf.seek(0);///移动到10的时候,他能正确读到 吕泽正 这个字//一次性读取,吧文件中的内容都读到字节数组中byte[] buf = new byte[(int)raf.length()];raf.read(buf);//方法read(byte[] buf) 读取到buf数组中去System.out.println(raf.getFilePointer());//这就读取到16位了System.out.println(Arrays.toString(buf));String s1 = new String(buf);System.out.println(s1+"  ");for(byte b : buf){System.out.print(Integer.toHexString(b & 0xff)+"  ");}raf.close();//记得关闭}}

IO流,Java做输入输出的基础,分为输入流/输出流。又分为字节流,字符流。可以以字节为单位,可以以字符为单位。

四、字节流

两个抽象父类

1、InputStream、OutputStream

InputStream抽象了应用程序读取数据的方式
OutputStream抽象了应用程序写出数据的方式。

2、EOF = End 读到-1就读到结尾了。

重要方法:

3、输入流:基本方法主要是读

int b = in.read(); 读取一个字节,无符号填充到int的低8位,高8位补零。读到-1 EOF结束。
in.read(byte[] buf) 读取数据填充到字节数组buf
int.read(byte[] buf,int start,int size)。读取数据到字节数组buf。从buf的start位置开始,存放size长度的数据
4、输出基本方法
out.write(int b); 写出一个byte到流,b的低8位。
out.write(byte[] buf); 将buf字节数组都写入到流
out.write(byte[] buf,int start,int size);字节数组buff从start位置开始,写size长度的字节到流。

5、FileInputStream子类 继承勒InputStream  ----> 具体实现了在文件上读取数据

package com.Imooc;import java.io.*;public class IOUtil {/* * 读取指定文件内容,按照16进制输出到控制台 * 并且每输出10byte字节,我们就换行 */public static void printHex(String fileName) throws IOException{//调用的时候传入//把文件作为字节流进行读操作FileInputStream in = new FileInputStream(fileName);int b;//4个字节。int i=1;while((b=in.read())!=-1){//如何读,如何读到结束,其实b的值每次都刷新//in.read():读取一个字节,一个字节是8bitif(b<=0xf){//单位数前面补0System.out.print("0");}//toHexString是进制转换System.out.print(Integer.toHexString(b)+"  ");//将整型b转换为16进制表示的字符串if(i++%10==0){System.out.println();}}in.close();}public static void printHexByByteArray(String fileName) throws IOException{FileInputStream in = new FileInputStream(fileName);byte[] buf = new byte[1];//从in这个文件中批量读取字节,放到buf这个字节数组中,//从第0个位置开始放,最多放buf.length个,//返回的是独到的字节的个数/*int bytes  = in.read(buf,0,buf.length);//一次性读完,说明字节数组足够大,这里返回的就是字节长度。所以下面是 i<bytes。int j=1;for(int i=0;i<bytes;i++){if(buf[i]<=0xf){System.out.print(0);}System.out.print(Integer.toHexString(buf[i])+" ");if(j++%10==0)System.out.println();}*/int bytes = 0;int j=1;while((bytes = in.read(buf,0,buf.length))>=0){for(int i = 0;i< buf.length;i++){if(buf[i]<0xf){System.out.print("0");}System.out.print(Integer.toHexString(buf[i] & 0xff)+"  ");//byte类型为8位,int类型为32位,为了避免数据转换错误,通过&0xff将高24位清零if(j++%10 == 0){System.out.println();}}}in.close();}//写一个文件复制的程序 利用读操作和写操作,字节批量读取,直接字节数组public static void copyFile(File srcFile,File desFile) throws IOException{if(!srcFile.exists()){//文件不存在不行throw new IllegalArgumentException("文件:"+srcFile+"不存在!");}if(!srcFile.isFile()){//不是文件不行throw new IllegalArgumentException(srcFile+"不是文件");}FileInputStream in = new FileInputStream(srcFile);FileOutputStream out = new FileOutputStream(desFile);byte[] buf = new byte[1024];//这里的大小很重要,大的话才是整体输入int b;while ((b=in.read(buf,0,buf.length))>0){out.write(buf, 0, b);out.flush();//最好加上}//关闭文件in.close();out.close();}/* * 使用带缓冲的字节流,进行文件的拷贝 */public static void copyFileByBuffer(File srcFile,File destFile) throws IOException{if(!srcFile.exists()){//文件不存在不行throw new IllegalArgumentException("文件:"+srcFile+"不存在!");}if(!srcFile.isFile()){//不是文件不行throw new IllegalArgumentException(srcFile+"不是文件");}BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));//参数必须是字节流,不能使文件,就是要包装成字节流。//FileInputStream是节点字节流,必须跟物理节点相连接。BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));int c;while((c = bis.read())!=-1){bos.write(c);bos.flush();//刷新缓冲区,必须}bis.close();bos.close();}/* * 单字节不带缓冲进行文件拷贝 */public static void copyFileByByte(File srcFile,File destFile)throws IOException{if(!srcFile.exists()){//文件不存在不行throw new IllegalArgumentException("文件:"+srcFile+"不存在!");}if(!srcFile.isFile()){    //不是文件不行throw new IllegalArgumentException(srcFile+"不是文件");}FileInputStream in = new FileInputStream(srcFile);FileOutputStream out = new FileOutputStream(destFile);int c;while((c=in.read())!=-1){out.write(c);out.flush();//缓冲的必须要flush}in.close();out.close();}}

下面写一个测试类:
package com.Imooc;import java.io.*;public class IOUtilTest1 {public static void main(String[] args)throws IOException{//IOUtil.printHex("E:\\workspace\\com.Imooc\\Telphone.java");System.out.println();System.out.println("===================================");//IOUtil.printHexByByteArray("E:\\workspace\\com.Imooc\\Telphone.java");long s =System.currentTimeMillis();IOUtil.copyFile(new File("E:\\workspace\\com.Imooc\\Telphone.java"),new File("E:\\workspace\\com.Imooc\\CopyTelphone.java"));long start1 = System.currentTimeMillis();IOUtil.copyFileByBuffer(new File("E:\\workspace\\com.Imooc\\Telphone.java"),new File("E:\\workspace\\com.Imooc\\BufferedCopyTelphone.java"));long end1_start2 = System.currentTimeMillis();IOUtil.copyFileByByte(new File("E:\\workspace\\com.Imooc\\Telphone.java"), new File("E:\\workspace\\com.Imooc\\SingleCopyTelphone.java"));long end2 = System.currentTimeMillis();System.out.println("-------------------------------------------");System.out.println(start1-s);System.out.println(end1_start2-start1);System.out.println(end2-end1_start2);//测试时间}}


输出结果:
这是注释掉的部分,必须 byte[] buf = new byte[1024],足够大,才行,因为是一次性读取


这是用下面方法的输出。

6、FileOutputStream 实现了向文件中写入byte数据的方法

package com.Imooc;import java.io.*;public class FileOutDemo1 {public static void main(String[] args)throws IOException{//如果该文件不存在,则直接创建,如果存在,删除后创建FileOutputStream out = new FileOutputStream("demo/out.dat");//new FileOutputStream("demo/out.dat",true);//如果这样的话,就是追加,不会删除后创建了out.write('A');//写出A字符的低8位out.write('B');//写出B的低八位int a = 10;//write只能写8位,那么写一个整数需要写4次,每次8位out.write(a>>>24);out.write(a>>>16);out.write(a>>>8);out.write(a);byte[] gbk="中国".getBytes("gbk");out.write(gbk);out.close();IOUtil.printHex("demo/out.dat");//调用前面的,将写入的内容输出到控制台}}
输出:
41 A 42 B 00 00 00 0a 10   因为整型是4字节,32位。写四次  d6 

7、DataOutputStream/DataInputStream

对流功能的扩展,可以更加方便读取int long,字符,等类型数据。主要操作类型数据。
DataOutputStream
writeInt()/writeDouble()/writeUTF()/
package com.Imooc;import java.io.*;public class DosDemo {public static void main(String[] args)throws IOException{String file = "demo/dos.dat";DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));//用fileOutputSream的方法,写几次dos.writeInt(10);//执行了4次write()dos.writeInt(-10);dos.writeLong(10l);dos.writeDouble(10.5);//采用UTF-8编码写出dos.writeUTF("中国");//采用utf-16be编码写dos.writeChars("中国");dos.close();IOUtil.printHex(file);}}

package com.Imooc;import java.io.*;public class DisDemo {public static void main(String[] args)throws IOException{String file = "demo/dos.dat";IOUtil.printHex(file);DataInputStream dis = new DataInputStream(new FileInputStream(file));int i = dis.readInt();//读取了4次 long是8次System.out.println(i);i=dis.readInt();System.out.println(i);long l = dis.readLong();System.out.println(l);double d = dis.readDouble();System.out.println(d);String s =  dis.readUTF();System.out.println(s);}}

8、 BufferedInputStream&BufferedOutputStream


这两个流泪为IO提供了带缓冲区的操作,一般打开文件进行写入或读取操作时,都会加上缓冲,这种流模式提高了IO的性能。
从应用程序中输入放入文件,相当于将一缸水倒入另一缸水中:
FileOutputStream ---->write()方法  相当于一滴一滴的把水转移过去。
DataOutputStream ----->writeXxx()方法会方便一些。一下写4个字节、8个  相当于一瓢一瓢的转移
BufferedOutputStream---->write()方法更方便,相当于一瓢一瓢水先放入桶中(缓存区),再从桶倒入到另一个缸中。

五、字符流

1、编码问题要清楚

2、认识文本和文本文件

Java的文本(char)是16位无符号整数,是字符的unicode编码(双字节编码)
文件是byte byte byte .....的数据序列
文本文件是文本(char)序列按照某种编码方法(utf-8,uft-16be,gbk)序列化为byte的存储结果

3、字符流(Reader Writer)------>操作的是文本 文本文件

字符的处理,一次处理一个字符

字符的底层仍然是基本的字节序列。

字符流的基本实现

InputStreamReader 完成byte流解析为char流,按照编码解析

OutputStreamWriter 提供char流到byte流,按照编码存储

package com.Imooc;import java.io.*;public class IsrAndOswDemo {public static void main(String[] args) throws IOException{FileInputStream in = new FileInputStream("E:\\workspace\\com.Imooc\\imoocutf-8");InputStreamReader isr = new InputStreamReader(in,"utf-8");//这里默认是gbk,可以省略FileOutputStream out = new FileOutputStream("E:\\workspace\\com.Imooc\\imoocutf-81.txt");OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8");/*int c;while((c=isr.read())!=-1){System.out.print((char)c);}*/char[] buffer = new char[8];int c;//批量读取,放入buffer这个字符数组,从第0个位置开始防止,最多放buffer.lengthwhile((c = isr.read(buffer,0,buffer.length))!=-1){//System.out.print(c);//System.out.println("-----");String s = new String(buffer,0,c);System.out.print(s);osw.write(buffer,0,c);osw.flush();}isr.close();osw.close();}}

4、FileReader 和 FileWriter   

可以不用上上面的InputStreamReader 这样的嵌套,直接可以写文件地址,直接对物理资源操作。

package com.Imooc;import java.io.*;public class FrAndFwDemo {public static void main(String[] args) throws IOException{//FileInputStream in = new FileInputStream("E:\\workspace\\com.Imooc\\imoocutf-8");//InputStreamReader ins = new InputStreamReader(in,"utf-8");//FileReader fr1 = new FileReader(new InputStreamReader(new FileInputStream("")));//File in = new File("E:\\workspace\\com.Imooc\\imoocutf-8.txt");FileReader fr = new FileReader("E:\\workspace\\com.Imooc\\imoocutf-8.txt");//没有放编码格式的例如“gbk”FileWriter fw = new FileWriter("E:\\workspace\\com.Imooc\\imoocutf1-8.txt");//如果名字一样的话,这样会删掉原来的东西//FileWriter fw = new FileWriter("E:\\workspace\\com.Imooc\\imoocutf-8.txt",true);//追加内容,带个true。char[] buffer = new char[1];int c;while((c=fr.read(buffer, 0, buffer.length))!=-1){//System.out.println("+++++++++++");System.out.print(new String(buffer,0,c));fw.write(buffer,0,c);fw.flush();}fr.close();fw.close();}}

5、字符流可以加过滤,具备更强大的功能。

BufferedReader ----> readLine 一次读一行 

BufferedWriter/(结合)PrintWriter ----> writeLine 一次写一行


FileReader fr = new FileReader("E:\\workspace\\com.Imooc\\imoocutf-8.txt");BufferedReader br = new BufferedReader(fr); 等同于下面BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("E:\\workspace\\com.Imooc\\imoocutf-8.txt")));

package com.Imooc;import java.io.*;public class BrAndBwOrPwDemo {public static void main(String[] args)throws IOException{//对文件进行读写操作//FileReader fr = new FileReader("E:\\workspace\\com.Imooc\\imoocutf-8.txt");//BufferedReader br = new BufferedReader(fr); 等同于下面BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("E:\\workspace\\com.Imooc\\imoocutf-8.txt")));/*BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\\workspace\\com.Imooc\\bwutf-8")));*/FileWriter pw2 = new FileWriter("E:\\workspace\\com.Imooc\\bwut");//PrintWriter pw = new PrintWriter("E:\\workspace\\com.Imooc\\bwutf-8");PrintWriter pw1 = new PrintWriter(pw2,true);//自动刷新String line;while((line = br.readLine())!=null){System.out.println(line);//一次读一行,并不能识别换行,所以写为println 而不是printpw1.println(line);/*bw.write(line);//不认识换行,单独写出胡按行操作bw.newLine();bw.flush();*//*pw.println(line);//换行方便pw.flush();*/}br.close();pw2.close();//bw.close();//pw.close();}}

六、对象的序列化和反序列化

1、对象序列化:将Object转换成byte序列,反之叫对象的反序列化。
2、序列化流(ObjectOutputStream),是过滤流  ----writeObject
反序列化(ObjectInputStream) ------readObject 
3、序列化接口(Serializable)
对象必须实现序列化接口,才能进行序列化,否则将出现异常。
这个接口,没有任何方法,只是一个标准。
private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException
private void readObject(java.io.ObjectInputStream s)throws java.io.IOException,ClassNotFoundException
package com.Imooc;import java.io.Serializable;import java.util.ArrayList;public class Student implements Serializable {private String studo;//String类实现了Serializableprivate String stuname;private transient int stuage;//该元素不会进行jvm默认的序列化,也可以自己完成这个元素的序列化//ArrayList a = new ArrayList();public Student(){}public Student(String studo,String stuname,int stuage){super();//直接通过成员变量,生成构造方法this.studo = studo;this.stuname = stuname;this.stuage = stuage;}public String getStudo(){return studo;}public void setStudo(String studo){this.studo = studo;}public String getStuname(){return stuname;}public void setStuname(String stuname){this.stuname = stuname;}public int getStuage(){return stuage;}public void setStuage(int stuage){this.stuage = stuage;}public String toString(){return "Student[stuno="+studo+",stuname="+stuname+",stuage="+stuage+"]";}private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{s.defaultWriteObject();//把jvm能默认序列化的元素进行序列化操作s.writeInt(stuage);//自己完成stuage的序列化}private void readObject(java.io.ObjectInputStream s)throws java.io.IOException,ClassNotFoundException{s.defaultReadObject();//把jvm能默认反序列化的元素进行反序列化操作this.stuage = s.readInt();//自己完成stuage的反序列化操作}//用这个又能看到了}
package com.Imooc;import java.io.*;public class ObjectSeriaDemo1 {public static void main(String[] args)throws IOException, ClassNotFoundException{//对象序列化就是把对象进行一个保存String file = "E:/"+ "workspace/com.Imooc/obj.dat";//把这个对象存在路径下//1、对象的序列化/*ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));Student stu = new Student("10001","张三",20);//吧student对象保存起来oos.writeObject(stu);oos.flush();oos.close();*/ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));Student stu =(Student)ois.readObject();//读出来的都是Ibjectr,所以强制类型转换System.out.println(stu);ois.close();//打印出来,说明对对象进行了存储}}
4、分析ArrayList源码中序列化和反序列化的问题。  里面有一个  private transient Object[] elementData;
因为ArrayList不一定放满元素,序列化可以提高利用率。只是对有限元素做序列化。transient修饰,提高性能。将来自己做序列化的优化问题。
5、序列化中  子类和父类 构造函数的调用问题
对子类对象进行反序列化操作时,如果其父类没有实现序列化接口,那么其父类的构造函数会被显示调用。
package com.Imooc;import java.io.*;public class ObjectSeriaDemo2 {public static void main(String[] args) throws IOException, ClassNotFoundException{/*ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\workspace\\com.Imooc\\imoocutf-8"));Foo2 foo2 = new Foo2();//序列化完成了oos.writeObject(foo2);oos.flush();oos.close();*///反序列化是否递归调用父类的构造函数/*ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\workspace\\com.Imooc\\imoocutf-8"));Foo2 foo2 = (Foo2)ois.readObject();System.out.println(foo2);ois.close();*//*ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\workspace\\com.Imooc\\imoocutf-8"));Bar2 bar2 = new Bar2();//序列化完成了oos.writeObject(bar2);oos.flush();oos.close();*/ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\workspace\\com.Imooc\\imoocutf-8"));Bar bar2 = (Bar2)ois.readObject();System.out.println(bar2);ois.close();//这里表示父类构造函数被调用了  因为没有实现Implements调用了/* * 对子类对象进行反序列化操作时, * 如果其父类没有实现序列化接口, * 那么其父类的构造函数会被显示调用。实现的接口及其子类不会调用。 */}}class Foo implements Serializable{//一个类实现了序列化接口,那么其子类都可以进行序列化public Foo(){System.out.println("foo...");}}class Foo1 extends Foo{public Foo1(){System.out.println("foo1...");}}class Foo2 extends Foo1{public Foo2(){System.out.println("foo2...");}}class Bar{public Bar(){System.out.println("Bar");}}class Bar1 extends Bar{// implements Serializable{public Bar1(){System.out.println("bar1...");}}class Bar2 extends Bar1 implements Serializable{public Bar2(){System.out.println("bar2...");}}



0 0
原创粉丝点击