文件:File类

Java就提供了一个File类,以抽象的方式代表文件名和目录路径名。该类主要用于文件和目录的创建、文件的查找和文件的删除等。是我们后面学习IO流的基础和前提

File对象代表磁盘中实际存在的文件和目录,我们可以通过递归算法知道磁盘中某一个目录下嵌套了多少文件。

递归算法(英语:recursion algorithm):程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用在计算机科学中,指一种通过重复将问题分解为同类的子问题而解决问题的方法。递归式方法可以被用于解决很多的计算机科学问题,因此它是计算机科学中十分重要的一个概念。绝大多数编程语言支持函数的自调用,在这些语言中函数可以通过调用自身来进行递归。计算理论可以证明递归的作用可以完全取代循环,因此在很多函数编程语言(如Scheme)中习惯用递归来实现循环。

递归算法解决问题的特点:

1)递归就是方法里调用自身。

2)在使用递增归策略时,必须有一个明确的递归结束条件,称为递归出口。

3)递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。

package com.liudm.demo13;

import java.io.File;
import java.io.IOException;
import java.net.PasswordAuthentication;

public class FileDemo {
	public static void main(String[] args) throws IOException {
		File file = new File("D:\\bxk");   //两个“\”:第一个“\”是用来转义第二个“\”
		System.out.println(file.exists());   //判断文件是否存在
		System.out.println(file.isFile());   //判断是否是一个文件
		System.out.println(file.isDirectory());  //判断是否是一个文件夹
		System.out.println(file.getAbsolutePath());  //返回file文件的绝对路径
		System.out.println(file.getPath());  //返回相对路径
		
		File [] files = file.listFiles();
		for (int i = 0; i < files.length; i++) {
			System.out.println(files[i]);  //列举该目录下这一级的所有文件/文件夹
		}

		if (file.createNewFile()) {
			System.out.println("文件创建成功");  //到D盘查看,aa.txt已创建
		}
		
		if (file.mkdir()) {   //只创建自己
			System.out.println("文件夹创建成功");
		}
		
		File file1 = new File("D:\\bxk1\\bkx2\\bxk3");
		if (file1.mkdirs()) {   //创建目录,包括父目录
			System.out.println("子文件夹创建成功");
		}
		
		//delete():只能删除空文件夹,即该文件夹中不能有内容
		file.delete();
		file1.delete();   //只删除了最下层子文件夹
	}
}

 

package com.liudm.demo13;

import java.io.File;

public class FileDemo1 {
	
	//递归,列举该目录下包括子目录下的所有文件
	public static  void  listFile(File file){
		//File file=new File(pathName);
		if(file.exists()){
			if(file.isDirectory()){
				File  [] files=file.listFiles();
				for (int i = 0; i < files.length; i++) {
					listFile(files[i]);
//					System.out.println(files[i]);
				}
			}else{
				System.out.println(file.getPath());  //打印名字
			}
		}else{
			System.out.println("该目录不存在");
		}
	}
	public static void main(String[] args) {
		
		listFile(new File("D:\\7-Zip"));
		
//		File file = new File("D:\\soft");
//		File  [] files=file.listFiles();
//		for (int i = 0; i < files.length; i++) {
//			System.out.println(files[i]);
//		}
	}
}

java 关闭在打开的excel java文件关闭_递归

 实验:编写代码实现遍历本地目录(自己定义一个存在的目录)下的所有文件,并打印文件的名字在控制台

1. 打开终端切换目录到/data/目录下,创建文件夹file

java 关闭在打开的excel java文件关闭_java 关闭在打开的excel_02

2.进入file目录,使用wget命令,下载实验需要的数据

java 关闭在打开的excel java文件关闭_System_03

java 关闭在打开的excel java文件关闭_System_04

3、解压所需要的数据     

unzip data.zip
package com.liudm.test7;

import java.io.File;

public class FileTest {
	public static void main(String[] args) {
		File file = new File("/data/java3/file");
		FileTest ft = new FileTest();
		ft.GetFileName(file);
	}

	private void GetFileName(File file) {
		// TODO Auto-generated method stub
		if (file.isDirectory()) {
			File [] fs = file.listFiles();
			for (int i = 0; i < fs.length; i++) {
				GetFileName(fs[i]);
			}
		} else {
			System.out.println(file.getName());
		}
	}
}


流:主要应用场景是上传下载

字符流操作文件:

java中的流是指一连串流动的字符,是以先进先出方式发送信息的通道

流架构:

流分类:

  • 按照流向区分:输入流和输出流(输入输出流是相对于计算机内存来说的)
  • 按照内存单元划分:字节流和字符流

字符流:处理包含大量中文的文本文件

  • 字符输入流:Reader(父)---》FileReader(低级流)-->BufferedReader(高级流)
  • 字符输出流:Writer(父)---》FileWriter(低级流)-->BufferedWriter(高级流)

低级流:也称节点流,节点流类型常见的有:对文件操作的字符流有FileReader/FileWriter,字节流有FileInputStream/FileOutputStream

高级流:也称缓冲流,缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写效率,同时增加了一些新的方法,常用缓冲流有BufferedReader、BufferedWriter

注意:

1.只需要 关闭高级流即可:关高级流,其实就是关低级流,关流的时候,自动刷新缓冲区

bw.flush();

2.高级流构造器中传入低级流构,体现了 装饰者 模式,让高级流功能更加强大

FileWriter fw = new FileWriter("F:/fw.txt");// 低级流

BufferedWriter bw = new BufferedWriter(fw);  //高级流,有缓冲

3.输出流向外写数据的时候,如果目标地址不存在,自动创建

字节流:字节流是 8 位通用字节流,常用来处理图片、视频、文件

字节输入流:InputStream(父)---》FileInputStream(子):常用方法:read() 、read(byte[])

字节输出流:OutputStream(父)----》FileOutputStream(子):常用方法:write(int byte) 、 write(byte[])

注意:

1.输出流向外写数据的时候,如果目标地址不存在,自动创建

2.不管是字节输入流还是字节输出流,在读写数据完成之后,一定要手动关闭流资源,一般在finally代码中完成,垃圾回收机制不会自动回收物理资源

3.在用流操作文件的时候,有很多异常需要处理

package com.liudm.demo13;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class ByteInDemo {
	public static void main(String[] args) {
		//字节输入流:一个字节一个字节地读,读中文汉字会乱码,一个中文?字节
		//将D:\\FileDemo.java → JVM:内存 → 读进来
		File file = new File("D:\\FileDemo.java");
		FileInputStream in = null;
		try {
			in = new FileInputStream(file);
			int data = 0;
			
			//读取文件内容:方法一
			while ((data = in.read()) != -1) {   //  ==-1:读到最后一个字符
				//System.out.print(data);  //ASCII码
				System.out.print((char)data);   //强制转换
			}
			
			//读取文件内容:方法二
			byte [] bs = new byte[in.available()];  //bs数组长度为:这个文件内容的大小,用available()获取
			data = in.read(bs);
			System.out.println(new String(bs));
		} catch (FileNotFoundException e) {
			// TODO: handle exception
			e.printStackTrace();
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			//流:物力资源,一定要手动关闭
			if (in != null) {
				
			}
		}
	}
}
package com.liudm.demo13;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class ByteInDemo1 {
	public static void main(String[] args) throws IOException {
		//字节输出流
		//往外写文件的时候,如果不存在,则创建
		//如果存在不会追加,直接覆盖
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(new File("D:/bxk.txt"));
			out.write(98);
			out.write(97);
			out.write(96);
			System.out.println("写入成功。。");
		} catch (FileNotFoundException e) {
			// TODO: handle exception
			e.printStackTrace();
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}
}
package com.liudm.demo13;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class CharDemo {
	//字符流,基类:Reader,Writer
	//字节流,基类:InPutStream,OutPutStream
	public static void main(String[] args) {
		//在外面声明,里面赋值
		FileReader fr = null;
		BufferedReader br = null;
		try {
			//模式:装饰者模式
			
			fr = new FileReader(new File ("D:\\FileDemo.java"));  //低级流
			br = new BufferedReader(fr);  //高级流:缓冲区,效率高
			
			String line = null;
			br.readLine();  //一行一行地读
			while ((line = br.readLine()) != null) {
				System.out.println(line);
			}
			
			int data = 0;  //fr.read()
			while ((data = fr.read()) != -1) {
				System.out.println((char)data);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (br != null) {
				try {
					br.close();  //关闭高级流,低级流就不用关闭了
				} catch (Exception e2) {
					// TODO: handle exception
				}
			}
		}
	}
}
package com.liudm.demo13;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class CharDemo1 {
	//字符输出流
	public static void main(String[] args) {
		FileWriter fw = null;
		BufferedWriter br = null;
		try {
			fw = new FileWriter(new File("D:\\study.txt"),true);  //在低级流后面加true,表示追加
			br = new BufferedWriter(fw);
			
			char [] c = {'A','B','C','D'};
			br.write("张三");
			br.write(98);
			br.write(c);
			
			br.flush();
			//刷新缓冲区,当没有关流的时候需要读流时,需要刷新缓冲区先读出来
			//读流自动刷新缓冲区
			
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			if (br != null) {
				try {
					br.close();  //关流的时候会自动刷新缓冲区
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
package com.liudm.demo13;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyDemo {
	public static void main(String[] args) throws IOException {
		CopyDemo.copy("D:\\FileDemo.java","C:\\FileDemo.java");
	}
	
	//图片,视频等,都用字节流
	public static void copy(String start,String end) throws FileNotFoundException{
		FileInputStream in = new FileInputStream(new File(start));
		FileOutputStream out = new FileOutputStream(new File(end));
		
		int data = 0;
		try {
			while ((data = in.read()) != -1) {
				//System.out.println((char)data);
				out.write(data);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

实验1:利用字符流完成文件的读写操作

package com.liudm.test1;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import com.liudm.test1.FileTest;

public class FileTest {
	public static void main(String[] args) throws IOException {
		FileTest.WritrDoc("/data/liudm.txt");
	}
	
	public static void WritrDoc (String file1) throws IOException{
		FileWriter fw = null;
		BufferedWriter bw = null;
		try {
			fw = new FileWriter(new File(file1));
			bw = new BufferedWriter(fw);
			bw.write("写入++++");
			bw.write("追加++++");
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			if (bw != null) {
				bw.close();
			}
		}
	}
	
	public static void ReadDoc (String file1) throws FileNotFoundException {
		FileReader fr = null;
		BufferedReader br = null;
		try {
			fr = new FileReader(new File(file1));
			br = new BufferedReader(fr);
			int data = 0;
			while ((data = br.read()) != -1) {
				System.out.println((char)data);
			}
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			if (br != null) {
				try {
					br.close();   //关闭高级流的时候---》默认关闭的就是低级流
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

java 关闭在打开的excel java文件关闭_递归_05

读文件:在该类中,定义一个方法,用来实现文件的读取,并打印在控制台输出。

首先声明一个字节流BufferedReader,构造一个BufferedReader对象,构造器中传入FileReader对象,因为FileReader是字符流,所以其构造器中需传入file对象,最终获得BufferedReader对象,使用read方法返回读取的字符,当文件读到末尾的时候返回-1.所以借助whille循环,不断的读取文件中的内容,最后打印输出。

注意:在编写代码的时候,只要记住两个类:FileReader、BufferedReader和read方法,在写代码时,根据提示传入所需要的内容即可。

public static void ReadFileByZifu(String address){  
    FileReader fr=null;//低级流  
    BufferedReader br=null;//高级流:缓冲  
    try {  
        fr=new FileReader(new File(address));//FileReader是字符流  
                br=new BufferedReader(fr);//BufferedReader是字符高级流,有缓冲区  
                int data=0;  
                while((data=br.read())!=-1){  
                    System.out.print((char)data);  
                }  
            } catch (FileNotFoundException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }finally{  
                try {  
                    br.close();//关闭高级流的时候---》默认关闭的就是低级流  
                } catch (IOException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
        }

在读文件的时候,也可以把br.read换成br.readLine方法,这样表示读取一行数据:

String data=null;  
                while((data=br.readLine())!=null){  
                    System.out.println(data);  
                }

写文件:写文件用字符输出流来实现,使用FileWrite、BufferedWriter类和write方法,和字符输入流是一样的。在使用高级流读写文件的时候,一定要注意刷新高级流的缓冲区,即调用flush方法,流关闭的时候,默认刷新缓冲区。

package my.iodemo1;  
import java.io.BufferedReader;  
import java.io.BufferedWriter;  
import java.io.File;  
import java.io.FileNotFoundException;  
import java.io.FileReader;  
import java.io.FileWriter;  
import java.io.IOException;  
    public class ZiFu {  
        public static void main(String[] args) {  
            //ZiFu.ReadFileByZifu("/data/FileDemo.java");  
            ZiFu.WriteFileByZiFu("/data/outzifu.txt");  
  
        }  
  
        public static void WriteFileByZiFu(String address){  
            FileWriter fw=null;  
            BufferedWriter bw=null;  
            try {  
                fw=new FileWriter(new File(address));  
                bw=new BufferedWriter(fw);  
                bw.write("大家一定要认真学习。。");  
                //bw.flush();//刷新缓冲区  
  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }finally{  
                try {  
                    bw.close();//关闭流资源之前 ,先刷新缓冲区  
                } catch (IOException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
        }  
  
  
        public static void ReadFileByZifu(String address){  
            FileReader fr=null;//低级流  
            BufferedReader br=null;//高级流:缓冲  
             try {  
                fr=new FileReader(new File(address));//FileReader是字符流  
                br=new BufferedReader(fr);//BufferedReader是字符高级流,有缓冲区  
                int data=0;  
                while((data=br.read())!=-1){  
                    System.out.print((char)data);  
                }  
               // String data=null;  
               //while((data=br.readLine())!=null){  
                //  System.out.println(data);  
                //}  
            } catch (FileNotFoundException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }finally{  
                try {  
                    br.close();//关闭高级流的时候---》默认关闭的就是低级流  
                } catch (IOException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
        }  
}

实验2:利用字节流完成文件的读写操作

读文件:在该类中,定义一个方法,用来实现文件的读取,并打印在控制台输出。首先声明一个字节流FileInputStream,构造一个FileInputStream对象,构造器中传入file文件,获得字节输入流FileInputStream对象,因为流是携带信息的通道,使用read方法返回读取的字节,当文件督导末尾的时候返回-1.所以借助whille循环,不断的读取文件中的字节内容,最后打印输出。

package my.iodemo1;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.IOException;  
public class ZiJie {  
    public static void main(String[] args) {  
        ZiJie.ReadFile("/data/FileDemo.java");  
    }  
  
    public static void ReadFile(String address){  
        File file=new File(address);  
        FileInputStream in=null;  
        //流来读  
        try {  
            in=new FileInputStream(file);//把信息放在流中  
            byte [] bs=new byte[in.available()]; //信息总共的字节大小  
            int data=0; //in.read()读到的其实就是字符对应的AS码值  
            while((data=in.read(bs))!=-1){// -1表示文件读到末尾了  
               System.out.print(new String(bs));  
            }  
        } catch (FileNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }finally{  
            try {  
                in.close();  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
    }  
  
    public static  void ReadFile2(String address){  
        File file=new File(address);  
        FileInputStream in=null;  
        //流来读  
        try {  
            in=new FileInputStream(file);//把信息放在流中  
            int data=0; //in.read()读到的其实就是字符对应的AS码值  
            while((data=in.read())!=-1){// -1表示文件读到末尾了  
               System.out.print((char)data);  
            }  
        } catch (FileNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }finally{  
            try {  
                in.close();  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
    }  
}

写文件:同理,使用FileOutPutStream类中的write方法写内容,定义WriteFile方法,在FileOutputStream构造器中传入file对象,new出FileOutputStream对象,调用他的write方法写入字节数据,当然也可以借助字节数组完成数据的写入。

public static void WriteFile(String address){  
        FileOutputStream  out=null;  
        try {  
            out=new FileOutputStream(new File(address));  
            out.write(97);  //97  -->a  //98  -->b  
            out.write(98);  
  
            byte []bs=new byte[10];//借助字节数组  
            bs[0]='A';  
            bs[1]='A';  
            bs[2]='A';  
            bs[3]='A';  
            out.write(bs);  
        } catch (FileNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }finally{  
            try {  
                out.close();  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
    }

 在main方法中调用:

public static void main(String[] args) {  
    ZiJie.WriteFile("/data/out.txt");  
  
}
package com.liudm.demo2;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileTest {
	public static void main(String[] args) throws IOException {
		FileTest.WriteDoc("/data/liudmm.txt");
		FileTest.ReadDoc("/data/liudmm.txt");
	}
	
	public static void WriteDoc(String f) throws IOException {
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(f);
			out.write(65);
			out.write(115);
			out.write(104);
			out.write(32);
			out.write(105);
			out.write(115);
			out.write(32);
			
			byte [] bs = new byte [20];
			bs[0] = 't';
			bs[1] = 'h';
			bs[2] = 'e';
			bs[3] = ' ';
			bs[4] = 'p';
			bs[5] = 'u';
			bs[6] = 'r';
			bs[7] = 'e';
			bs[8] = 's';
			bs[9] = 't';
			out.write(bs);
			
		} catch (FileNotFoundException e) {
			// TODO: handle exception
			e.printStackTrace();
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}
	
	public static void ReadDoc(String f) throws IOException {
		FileInputStream in = null;
        //流来读
		try {
			in = new FileInputStream(f);   //把信息放在流中
			int data = 0;   //in.read()读到的其实就是字符对应的AS码值
			while ((data = in.read()) != -1) {   // -1表示文件读到末尾了
				System.out.println((char)data);
			}
		} catch (FileNotFoundException e) {
			// TODO: handle exception
			e.printStackTrace();
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			if (in != null) {
				in.close();
			}
		}
	}
}

java 关闭在打开的excel java文件关闭_java 关闭在打开的excel_06

练习1:编码实现从C盘拷贝一张图片到D盘

package com.liudm.demo13;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test1 {
	public static void main(String[] args) throws IOException {
		Test1.copy("C:\\subwaymap.jpg","D:\\subwaymap.jpg");
	}

	private static void copy(String start, String end) throws IOException {
		// TODO Auto-generated method stub
		FileInputStream in = new FileInputStream(new File(start));
		FileOutputStream out = new FileOutputStream(new File(end));
		int data = 0;
		try {
			while ((data = in.read()) != -1) {
				out.write(data);
			}
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}
}

 

java 关闭在打开的excel java文件关闭_递归_07

    

java 关闭在打开的excel java文件关闭_System_08

练习2:编码实现将一个包含大量中文的文件从C盘copy到D盘

package com.liudm.demo13;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Test2 {
	public static void main(String[] args) throws IOException {
		FileReader fr = null;
		FileWriter fw = null;
		try {
			fr = new FileReader("C:\\IO流.txt");  //该含有大量中文字符的文件已存在
			fw = new FileWriter("D:\\IO流.txt");
			int data =0;
			while((data = fr.read()) != -1){
				fw.write(data);
			}
		} catch (FileNotFoundException e) {
			// TODO: handle exception
			e.printStackTrace();
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			if (fw != null) {
				fw.close();
			}
		}
	}
}

序列化和反序列化

概念:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,将数据分解成字节流以便存储在文件中或在网络上传输。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。

分类:序列化分为两大部分:序列化和反序列化。

  • 序列化:将数据分解成字节流,以便存储在文件中或在网络上传输。即:序列化是将对象的状态存储到特定存储介质中的过程,由ObjectOutputStream类的writeObject实现
  • 反序列化:打开字节流并重构对象。即:反序列化则是从特定存储介质中的数据重新构建对象的过程 ,由ObjectInputStream类的readObject()方法实现

步骤:序列化的实现步骤:

1.将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,生成一个 serialVersionUID = -3780517487765653944L;

2.然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象

3.接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流

4.关闭流资源

注意:

1.static属性不会被序列化出去:--》static属于类的,不属于对象

2.如果一个对象的某个属性不想被序列化出去,那么该属性可以用transient修饰

3.序列化不可追加

4.如果某个类能够被序列化,其子类也可以被序列化

实验1:编写代码实现,将老师对象(stu("张老师",23))序列化到本地文件teachers.txt中,再反序列化回来将其信息打印在控制台。

让Teacher类实现Serializable接口,生成serialVersionUID,表明teacher对象可以被序列化出去并唯一标识该类,并封装Teacher类:

package my.seriobject;  
import java.io.Serializable;  
public class Teacher  implements Serializable{  
    private static final long serialVersionUID = 1L;  
    private String name;  
    private int age;  
    private  transient String course;  
  
    public Teacher() {  
        // TODO Auto-generated constructor stub  
    }  
    public Teacher(String name, int age, String course) {  
        super();  
        this.name = name;  
        this.age = age;  
        this.course = course;  
    }  
  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
    public int getAge() {  
        return age;  
    }  
    public void setAge(int age) {  
        this.age = age;  
    }  
    public String getCourse() {  
        return course;  
    }  
    public void setCourse(String course) {  
        this.course = course;  
    }  
    public static long getSerialversionuid() {  
        return serialVersionUID;  
    }  
}

在SeriObject类中定义序列化的方法,实现序列化的类是ObjectOutputStream,该类构造器中需传入一个输出流,所以我们构建一个字节输出流FileOutputStream对象传入其构造器中,然后调用ObjectOutputStream的writeObject方法将对象持久化保存在本地文件中。

在处理异常的时候,大家注意:如果代码爆红线,鼠标放在上面时,弹出这种界面,说明我们要处理异常,可以点击:Add throws declaration,声明异常;Surround with try/catch,捕获异常。在开发中一般使用try-catch捕获异常。在main方法中调用该序列化方法。因为是将对象转换成流的形式保存起来,所以使用cat命令查看的时候,是乱码的。编写反序列代码,定义一个方法,将我们序列化出去的对象反序列化回来并将信息打印在控制台。

package my.seriobject;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.ObjectInputStream;  
import java.io.ObjectOutputStream;  
  
  
public class SeriObject {  
    public static void main(String[] args) throws IOException, ClassNotFoundException {  
        SeriObject.seriz("/data/teachers.txt");  
        SeriObject.fseriz("/data/teachers.txt");  
    }  
  
    //反序列化对象回来  
    public static void fseriz(String address) throws FileNotFoundException, IOException, ClassNotFoundException{  
        ObjectInputStream in=new ObjectInputStream(new FileInputStream(address));  
        Teacher stu=  (Teacher) in.readObject();  
        System.out.println(stu.getName()+"   "+stu.getAge()+"  "+stu.getCourse());  
        in.close();  
    }  
    //序列化对象出去  
    public static void seriz(String address){  
        File file=new File(address);  
        FileOutputStream fo = null;  
        ObjectOutputStream obj=null;  
        try {  
            fo = new FileOutputStream(file);  
            obj=new ObjectOutputStream(fo);  
            Teacher s1=new Teacher("张老师",12,"java");  
            obj.writeObject(s1);//把对象写到本地:序列化  
        } catch (FileNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }finally{  
            try {  
                fo.close();  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
            try {  
                obj.close();  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
    }  
}

在控制台查看读取到的信息内容:

发现tea.getCourse()返回null,说明Teacher类中被关键字transient修饰的属性没有被序列化出去。