1.File
- File類代表文件或者文件的類
- 創(chuàng)建文件類的對象芦岂,在創(chuàng)建對象的過程中沒有檢測路徑的信息是否存在,會把路徑信息放在對象的身上。即若路徑信息不存在垫蛆,創(chuàng)建對象的語句編譯和運行都不會報錯禽最。
File file=new File(路徑);
- 新建文件,新建文件為空文件,若路徑信息的指定文件已經(jīng)存在的話袱饭,返回值將會為false
boolean b=file.createNewFile();
- 創(chuàng)建文件夾(多級)
File f1=new File("E:\\IDEA\\workspace\\JAVASE2007\\Day18\\src\\cn\\tedu\\file\\a\\b\\c");
//創(chuàng)建文件夾(多級)
boolean b1=f1.mkdirs();
System.out.println(b1);
- 刪除文件川无,無論文件是否有內(nèi)容均可以刪除,但是只能刪除空文件夾虑乖,該方法操作需要慎重懦趋,刪除文件無法還原。
boolean b2=file.delete();
- 獲取文件或是文件夾的名稱疹味,若為文件時仅叫,將會返回文件名+后綴名字/文件夾名字
File file=new File(路徑信息);
//文件名+后綴名/文件夾名字
System.out.println(file.getName());
- 返回當前所在文件夾
System.out.file(file.getParent());
- 返回對象所在的路徑信息
System.out/println(file.getPath());
- 返回文件上次修時間----即從1970年1月1日0時0分0秒到現(xiàn)在的毫秒值
System.out.println(file.lastModified());
- 設(shè)置文件上一次修改時間
file.setLastModified(233333333L);
- 返回文件抽象路徑表示的長度,如果file表示的是一個具體的文件佛猛,則返回的文件的字節(jié)大小惑芭,如果File表示一個目錄,則返回值不能確定继找,如果目錄或是文件不存在,則返回為0L.
System.out.println(file.length());
- 返回文件夾下的所有文件,把當前文件夾下的所有信息當作File對象放入到數(shù)組中
File[] fs=file.listFiles();
- 過濾文件逃沿,根據(jù)一定的過濾規(guī)則篩選出符合條件的文件,下面為不同的兩種方法
File f=new File("E://");
//把E盤下含有數(shù)字的文件或者文件夾進行輸出
//把過濾之后的File類對象返回到數(shù)組中
File[] fs=f.listFiles(new FileFilter() {
//重寫方法--過濾規(guī)則
@Override
public boolean accept(File pathname) {
//正則語法----匹配字符串中含有數(shù)字
return pathname.getName().matches(".*\\d.*");
}
});
//遍歷數(shù)組
for(File f1:fs)
System.out.println(f1);
//
File[] fss=file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.matches(".*\\d.*");
}
});
- 重命名文件的抽象路徑名
//創(chuàng)建代表文件類的對象
File file=new File("E:\\IDEA\\workspace\\JAVASE2007\\Day18\\src\\cn\\tedu\\file\\123.txt");
//重命名
//底層是由剪切來實現(xiàn)的
boolean b=file.renameTo(new File("E:\\IDEA\\workspace\\JAVASE2007\\Day18\\src\\cn\\tedu\\file\\a\\七夕.txt"));
System.out.println(b);
- 判斷是否是文件夾
System.out.println(file.isDirectory());
- 判斷是否是文件
System.out.println(file.isFile());
- 練習(xí):刪除文件夾下的所有文件內(nèi)容(包括文件以及文件夾)
package cn.tedu.test;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
File file=new File("E:\\IDEA\\workspace\\JAVASE2007\\Day18\\src\\cn\\tedu\\file\\a");
//調(diào)用方法刪除文件
deleteFiles(file);
}
//定義刪除文件方法
public static void deleteFiles(File file){
//判斷是否是文件夾
if(file.isDirectory()){
//說明是文件夾婴渡,需要展開當前文件夾所有信息
//獲取當前文件夾所有信息
//放入到數(shù)組中
File [] fs=file.listFiles();
//遍歷當前數(shù)組
for(File f:fs){
//遞歸調(diào)用
deleteFiles(f);
}
}
//刪除文件以及空文件夾
file.delete();
}
}
- 統(tǒng)計工程里.java文件的個數(shù)以及.class文件個數(shù)
package cn.tedu.test;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
public class TestDemo1 {
//表示java文件的個數(shù)
private static int countJava=0;
//表示class文件的個數(shù)
private static int countClass=0;
public static void main(String[] args) throws IOException {
File file = new File("E:\\IDEA\\workspace\\JAVASE2007");
//統(tǒng)計方法統(tǒng)計文件數(shù)
countFiles(file);
//輸出java文件的個數(shù)
System.out.println("java文件個數(shù):"+countJava);
System.out.println("class文件個數(shù):"+countClass);
}
//定義方法來統(tǒng)計文件數(shù)
public static void countFiles(File file){
//判斷文件是否是文件夾
if(file.isDirectory()){
//說明是文件夾
//獲取文件夾里的信息
File [] fs=file.listFiles();
//遍歷數(shù)組
for(File f:fs){
countFiles(f);
}
}
//統(tǒng)計java文件個數(shù)
if(file.getName().endsWith(".java")){
countJava++;
}
//統(tǒng)計class文件的個數(shù)
if(file.getName().endsWith(".class")){
countClass++;
}
}
}
2.IO流
1)概念:本質(zhì)上是一套數(shù)據(jù)傳輸?shù)臋C制
2)圖例:若將A文件寫入到B文件中將會涉及到數(shù)據(jù)傳輸機制幻锁,即涉及到IO流。
3)三要素:將內(nèi)存看作是參照物
- 根據(jù)傳輸?shù)姆较?br>
?輸入流:往內(nèi)存來傳輸數(shù)據(jù)
?輸出流:從內(nèi)存往外傳輸數(shù)據(jù) - 根據(jù)傳輸?shù)姆绞?br>
?字符流:傳輸字符形式的數(shù)據(jù)
?字節(jié)流:傳輸字節(jié)形式的數(shù)據(jù) - 根據(jù)數(shù)據(jù)存放/獲取的位置
?硬盤边臼、內(nèi)存哄尔、網(wǎng)絡(luò)、外設(shè)設(shè)備
4)四大基本流(下面的四個類均為抽象類)
- 字符輸入流:Reader
- 字符輸出流:Writer
- 字節(jié)輸入流:InputStream
- 字節(jié)輸出流:OutputStream
5)硬盤
- 字符流
A柠并、給硬盤上.txt文件寫入數(shù)據(jù)-----文件字符輸出流--FileWriter
package cn.tedu.test;
import java.io.*;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
//創(chuàng)建文件字符輸出流對象
//創(chuàng)建對象的過程中會檢測路徑信息是否存在
//若存在會創(chuàng)建新的空文件進行覆蓋
//當未指定append的值時岭接,append的值將會默認為false
//當append為true時,不會會覆蓋文件的原有內(nèi)容臼予,若為false鸣戴,將會覆蓋原有內(nèi)容
FileWriter fw=new FileWriter("Test\\src\\file\\a.txt",true);
//寫入數(shù)據(jù)
//寫入int數(shù)據(jù)
fw.write(1);
//寫入char數(shù)組數(shù)據(jù)
char c[]={'a','b','c'};
fw.write(c,1,2);
//寫入String數(shù)據(jù)
fw.write("你好");
}
}
但是,當我們這樣的寫程序的時候會發(fā)現(xiàn)粘拾,文件中并未存在我們寫入的內(nèi)容窄锅,原因是什么呢?接下來缰雇,我們看一下FileWriter的大致寫入過程入偷。
?由上圖可知,我們上述程序未寫入的原因就是緩沖區(qū)并未存放滿械哟,那么緩沖區(qū)的容量大概是多少疏之?又如何將未存放滿的數(shù)據(jù)存放到文件中。
?由資料查找可知暇咆,緩沖區(qū)的容量為8kb,而當我們需要將數(shù)據(jù)從緩沖區(qū)中拿取出來時可以采用flush()函數(shù)來沖刷緩沖區(qū)体捏。完整程序代碼如下:
package cn.tedu.test;
import java.io.*;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
//創(chuàng)建文件字符輸出流對象
//創(chuàng)建對象的過程中會檢測路徑信息是否存在
//若存在會創(chuàng)建新的空文件進行覆蓋
//當未指定append的值時,append的值將會默認為false
//當append為true時糯崎,不會會覆蓋文件的原有內(nèi)容几缭,若為false,將會覆蓋原有內(nèi)容
FileWriter fw=new FileWriter("Test\\src\\file\\a.txt",true);
//寫入數(shù)據(jù)
//寫入int數(shù)據(jù)
fw.write(1);
//寫入char數(shù)組數(shù)據(jù)
char c[]={'a','b','c'};
fw.write(c,1,2);
//寫入String數(shù)據(jù)
fw.write("你好");
//底層為了提高和保證數(shù)據(jù)傳輸效率沃呢,會提供緩沖區(qū)來傳輸數(shù)據(jù)并且要求緩沖區(qū)
//存滿了才會進行數(shù)據(jù)傳輸年栓。若此時數(shù)據(jù)沒有充滿緩沖區(qū)且并未沖刷緩沖區(qū)
//數(shù)據(jù)將會滯留在緩沖區(qū)并且丟失
//沖刷緩沖區(qū)
fw.flush();
//關(guān)流
//含有自動沖刷的過程
fw.close();
//將流對象置為null,等待系統(tǒng)進行回收
fw=null;
}
}
B薄霜、從硬盤上的.txt文件讀取數(shù)據(jù)-----文件輸入流---FileReader
package cn.tedu.test;
import java.io.*;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
//創(chuàng)建文件輸入流對象
FileReader fr=new FileReader("Test\\src\\file\\a.txt");
//返回單個字符的編碼值
/*System.out.println(fr.read());
System.out.println(fr.read());
//當讀取完畢之后將會返回-1
System.out.println(fr.read());*/
//采用循環(huán)來實現(xiàn)上述過程
int i=-1;
while((i=fr.read())!=-1){
System.out.println(i);
}
//關(guān)流
fr.close();
}
}
?在上述過程中某抓,我們采用了read()方法讀取單個字符的編碼值,但是很明顯單個字符進行讀取的時候數(shù)據(jù)傳輸效率并不是很高惰瓜,但是在底層我們也沒有像字符輸出流一樣擁有緩沖區(qū)否副,那么我們該怎樣提高數(shù)據(jù)傳輸效率?答案就是自建緩沖區(qū)崎坊,代碼實例如下:
public static void main(String[] args) throws IOException {
//創(chuàng)建文件輸入流對象
FileReader fr=new FileReader("Test\\src\\file\\a.txt");
//自建緩沖區(qū)
//創(chuàng)建新數(shù)組备禀,存放我們要讀取的數(shù)據(jù)就
char cs[]=new char[5];
//把讀取到的數(shù)據(jù)存放到數(shù)組中
while(fr.read(cs)!=-1){
System.out.println(cs);
}
//關(guān)流
fr.close();
}
接下來我們查看一下文檔內(nèi)容是否和輸出內(nèi)容一致。
?很明顯,結(jié)果不相同曲尸,那么原因又是什么呢赋续?我們來看一下該段程序的大致執(zhí)行過程。
?由圖可知另患,我們想要解決這個問題纽乱,必須對輸出的數(shù)據(jù)進行截取,只能截取文件內(nèi)容輸出完畢昆箕,即文件內(nèi)容輸出完畢鸦列,數(shù)據(jù)同樣也輸出相同長度。代碼見如下:
package cn.tedu.test;
import java.io.*;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
//創(chuàng)建文件輸入流對象
FileReader fr=new FileReader("Test\\src\\file\\a.txt");
//自建緩沖區(qū)
//創(chuàng)建新數(shù)組鹏倘,存放我們要讀取的數(shù)據(jù)就
char cs[]=new char[5];
int len=-1;
//把讀取到的數(shù)據(jù)存放到數(shù)組中
//方法返回值就是讀取字符的個數(shù)薯嗤,返回-1讀取完畢
while((len=fr.read(cs))!=-1){
//輸出數(shù)組內(nèi)容
System.out.println(new String(cs,0,len));
}
//關(guān)流
fr.close();
}
}
- 字節(jié)流(常見)
A、給硬盤上.txt文件寫入數(shù)據(jù)(txt文件較為特殊第股,可以把字節(jié)轉(zhuǎn)字符应民,也可以把字符轉(zhuǎn)為字節(jié))---文件字節(jié)輸出流----FileOutputStream
package cn.tedu.test;
import java.io.*;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
//創(chuàng)建文件字節(jié)輸出流對象
//底層不存在緩沖區(qū)
FileOutputStream fos=new FileOutputStream("Test\\src\\file\\a.txt");
//寫出數(shù)據(jù)
fos.write("你好".getBytes());
//關(guān)流
fos.close();
}
}
B、從硬盤上.txt文件讀取數(shù)據(jù)----文件字節(jié)輸入流--FileInputStream
package cn.tedu.test;
import java.io.*;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
//創(chuàng)建文件字節(jié)輸入流對象
FileInputStream fis=new FileInputStream("Test\\src\\file\\a.txt");
//返回一個字節(jié)對應(yīng)的編碼值
/*文件存放內(nèi)容為:你好
編碼方式為utf-8
故對應(yīng)字節(jié)為6個夕吻,所以應(yīng)該讀取六次讀取完畢
*/
/*System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
//讀取完畢返回-1
System.out.println(fis.read());*/
//采用自建緩沖區(qū)的方式來讀取數(shù)據(jù)
byte [] bs=new byte[15];
int len=-1;
//返回的是讀取到的字節(jié)數(shù)诲锹,遇到-1讀取完畢
while((len=fis.read(bs))!=-1){
//輸出可能出現(xiàn)?的原因是:相應(yīng)的字節(jié)數(shù)可能無法組成一個漢字
System.out.println(new String(bs,0,len));
}
//關(guān)流
fis.close();
}
}
6)IO流中異常捕獲
?我們都知道處理異常的方式有兩種涉馅,一是拋出归园,而是捕獲,那IO中的異常又是如何捕獲的稚矿?
package cn.tedu.test;
import java.io.*;
public class TestDemo1 {
public static void main(String[] args){
//由于在創(chuàng)建IO流對象時可能會拋出異常庸诱,所以IO流對象對象的初始化過程需要放在
//try塊里,但是不論流對象是否真正的初始化成功晤揣,我們都需要把流對象
//置為null以及關(guān)流桥爽,故該對象需要再finally中使用,所以我們將IO流對象
//的創(chuàng)建過程分為初始化和聲明兩個過程昧识。
//1.聲明流對象钠四,并且賦值為null
FileWriter fw=null;
try{
//流對象進行初始化
fw=new FileWriter("Test\\src\\file\\a.txt");
//寫入數(shù)據(jù)
fw.write("你好");
//雖然我們關(guān)流時會進行自動沖刷緩沖區(qū),但是同樣的關(guān)流也同樣有可能會發(fā)生異常
//所以我們需要添加手動沖刷的過程跪楞,兩者一起發(fā)生錯誤的幾率還是很小的
//4.手動沖刷
fw.flush();
}catch (IOException e){
}finally {
//2.判斷流對象是否成功初始化
if(fw!=null)
//成功初始化
//關(guān)流
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}finally{
//3.無論關(guān)流成功與否都要把流對象置為null
fw=null;
}
}
}
}
7)緩沖流(給IO流提供緩沖區(qū))
?在之前缀去,當我們一次性傳輸多個數(shù)據(jù)時,我們會采用自建緩沖區(qū)的方式甸祭,但是選取一個合適的緩沖區(qū)長度將會是一個問題缕碎,這時Java提供給我們一個緩沖流,用來給IO流提供緩沖區(qū)池户。
- BufferedReader---給字符輸入流提供緩沖區(qū)
readLine()讀取一行數(shù)據(jù)
package cn.tedu.test;
import java.io.*;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
//創(chuàng)建緩沖流對象
//BufferedReader和FileReader都是Reader的子類---同類
//br對象具有FileReader的所有功能咏雌,但是還在此基礎(chǔ)上增加了別的功能
//所以凡怎,若將FileReader看作本類對象,BufferedReader作為同類對象
//同類對象給本類對象增強(完善)功能---稱為裝飾者設(shè)計模式
BufferedReader br=new BufferedReader(new FileReader
("Test\\src\\file\\a.txt"));
//讀取數(shù)據(jù)
//讀取一行數(shù)據(jù)
/*
文件中內(nèi)容:你好
helloworld
總共分為兩行
*/
/*System.out.println(br.readLine());
System.out.println(br.readLine());
//當內(nèi)容讀取完畢之后將會返回null
System.out.println(br.readLine());*/
//使用循環(huán)實現(xiàn)上述功能
String str="";
while((str=br.readLine())!=null){
System.out.println(str);
}
//關(guān)流
br.close();
}
}
- BufferedWriter--給字符輸出流提供緩沖區(qū)(雖然字符輸出流自帶緩沖區(qū)处嫌,但是BufferedWriter能夠提供更大的緩沖區(qū))
newLine():換行
package cn.tedu.test;
import java.io.*;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
//創(chuàng)建緩沖流對象
BufferedWriter bw=new BufferedWriter(new FileWriter(
"Test\\src\\file\\a.txt",true
));
//寫出數(shù)據(jù)
bw.write("你好");
//換行
bw.newLine();
bw.write("加油");
//關(guān)流
bw.close();
}
}
8)轉(zhuǎn)換流
?在數(shù)據(jù)傳輸?shù)倪^程中栅贴,我們有時候會遇到這樣的情況:比如我們需要得到字符流的數(shù)據(jù)斟湃,但是現(xiàn)在我們所擁有的只有字節(jié)流對象熏迹,或是我們可能會遇到需要字節(jié)流但是只有字符里的情況。那么凝赛,在這種情況下注暗,我們就需要將字節(jié)流和字符流進行相互轉(zhuǎn)換,這時我們會用到我們的轉(zhuǎn)換流墓猎。
- OutputStreamWriter----字符流轉(zhuǎn)成字節(jié)流
package cn.tedu.test;
import java.io.*;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
//創(chuàng)建轉(zhuǎn)換流對象
//轉(zhuǎn)換對象是由文件字節(jié)輸出流對象構(gòu)建
//底層真正進行傳輸數(shù)據(jù)的是文件字節(jié)輸出流對象
//接受準備數(shù)據(jù)時需要用的是字符形式數(shù)據(jù)捆昏,底層真正往外寫出數(shù)據(jù)的是字節(jié)流形式
//所以O(shè)utputStreamWriter轉(zhuǎn)換流是將字符流轉(zhuǎn)換成字節(jié)流
OutputStreamWriter ow=new OutputStreamWriter(new FileOutputStream(
"Test\\src\\file\\a.txt"
));
//寫出數(shù)據(jù)
//當我們需要寫出數(shù)據(jù)時,我們需要提前準備字符形式的數(shù)據(jù)
ow.write("你好");
//g關(guān)流
ow.close();
}
}
- InputStreamReader----字節(jié)流轉(zhuǎn)成字符流
package cn.tedu.test;
import java.io.*;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
//創(chuàng)建轉(zhuǎn)換流對象
//轉(zhuǎn)換流對象是由文件自建輸入流對象來提供的
//底層真正讀取數(shù)據(jù)的是文件字節(jié)輸入流
//先根據(jù)文件字節(jié)輸入流來讀取數(shù)據(jù)毙沾,再根據(jù)字符流來展示數(shù)據(jù)
//所以InputStreamReader是將字節(jié)流數(shù)據(jù)轉(zhuǎn)換成為字符流
InputStreamReader isr=new InputStreamReader(new FileInputStream(
"Test\\src\\file\\a.txt"
));
//讀取數(shù)據(jù)
char [] cs=new char[10];//自建緩沖區(qū)
int len=-1;
//展示數(shù)據(jù)為字符形式數(shù)據(jù)
//展示的數(shù)據(jù)由字符流來提供
while((len=isr.read(cs))!=-1){
System.out.println(new String(cs,0,len));
}
//關(guān)流
isr.close();
}
}
9)系統(tǒng)流
?我們首先來看下面的代碼:
package cn.tedu.test;
import java.io.*;
import java.util.Scanner;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
//輸出正確結(jié)果
//out---字節(jié)輸出流對象
System.out.println(1);
//輸出錯誤結(jié)果
//err---字節(jié)輸出流對象
System.err.println(1);
//in---字節(jié)輸入流對象
Scanner sc=new Scanner(System.in);
int num=sc.nextInt();
System.out.println(num);
}
}
?由上面程序可知骗卜,out、err左胞、in都是字節(jié)流寇仓。那么由之前的操作我們可以得知,流對象是可以關(guān)閉的烤宙,那么我們能否對其進行關(guān)閉呢遍烦?
package cn.tedu.test;
import java.io.*;
import java.util.Scanner;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
Scanner sc=new Scanner(System.in);
int num=sc.nextInt();
System.out.println(num);
//關(guān)流
sc.close();
Scanner sc1=new Scanner(System.in);
int num1=sc1.nextInt();
System.out.println(num1);
}
}
?結(jié)果如下:
?有結(jié)果來看,很明顯是不可以的躺枕,而發(fā)生這種情況的原因就是服猪,在底層代碼中in是靜態(tài)流對象,如果關(guān)閉了拐云,其他地方無法使用罢猪。所以,我們需要注意的是:系統(tǒng)流都是靜態(tài)的流對象叉瘩,使用完畢之后不能關(guān)流(且系統(tǒng)流不會占用太多內(nèi)存)
10)打印流
?在上一塊代碼中膳帕,我們可以看到out以及err都是PrintStream的對象,PrintStream稱為打印流房揭,是字節(jié)輸出流备闲。
package cn.tedu.test;
import java.io.*;
import java.util.Scanner;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
//創(chuàng)建打印流對象
PrintStream pw=new PrintStream( "Test\\src\\file\\a.txt");
//寫出數(shù)據(jù)
pw.print("123");
pw.println();
pw.print(123);
//關(guān)流
pw.close();
}
}
?我們的print以及println方法都是定義在打印流中的,我們之前之所以能夠?qū)?shù)據(jù)打印到控制臺中捅暴,是因為在System中指定了路徑信息為打印臺恬砂,所以同樣的,我們也可以采用一樣的方式將信息打印到我們的文件中蓬痒。
12)序列化與反序列化
?在我們的日常生活中泻骤,我們面對數(shù)據(jù)傳輸時我們往往是需要將大量的數(shù)據(jù)信息進行傳輸,更具Java一切皆對象的思想,我們可以將數(shù)據(jù)封裝對象來進行傳輸或是接收狱掂,這樣過的過程我們稱之為序列化與反序列化
- 序列化:把對象以及相關(guān)信息轉(zhuǎn)成字節(jié)數(shù)組
反序列化:把字節(jié)數(shù)組轉(zhuǎn)成相應(yīng)的對象 - 注意:
1.類實現(xiàn)了Serializable接口產(chǎn)生的對象才能被序列化
2.如果屬性被static/transient來修飾不能被序列化過去,方法不會被序列化過去
3.serialVersionUID(序列化版本號):在序列化之前會根據(jù)類里的屬性和方法來計算出一個版本號演痒,隨著對象一起序列化過去。在反序列化之前會再次根據(jù)類里的屬性和方法來計算出一個版本號趋惨,根據(jù)前后兩個版本號進行對比鸟顺,如果對比結(jié)果一致可以進行正常的反序列化,如果對比結(jié)果不一致則反序列化失敗器虾。(解決方法----提供版本號)
4.集合對象和映射對象都不能直接進行序列化讯嫂,只能依次遍歷元素對象一一進行序列化。(其存放內(nèi)容的屬性均被static修飾兆沙,無法被序列化過去) - 實例代碼
序列化:
package cn.tedu.test;
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
public class TestDemo1 {
public static void main(String[] args) throws IOException {
//創(chuàng)建對象
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(
"Test\\src\\file\\person.data"
));
//提供對象
Person p=new Person("愛麗絲",12);
//把對象轉(zhuǎn)換成字節(jié)數(shù)組進行序列化
oos.writeObject(p);
//關(guān)流
}
}
//定義代表人的類
class Person implements Serializable{
//java自動提供的序列化版本號
private static final long serialVersionUID = -109039264791201202L;
//提供版本號--java就不再計算版本號
//private static final long serialVersionUID=1555555555L;
//屬性
private String name;
private int age;
//屬性會被序列化過去
//靜態(tài)屬性不會被序列化過去
//強制屬性不會被序列化過去
transient double weight;
//靜態(tài)屬性
private static String classroom;
//方法不會被序列化過去
//定義有參構(gòu)造
public Person(String name,int age){
this.name=name;
this.age=age;
}
//提供get方法
public String getName() {
return name;
}
public int getAge() {
return age;
}
//重寫toString
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
反序列化
package cn.tedu.test;
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
public class TestDemo1 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//創(chuàng)建對象
ObjectInputStream o=new ObjectInputStream(new FileInputStream(
"Test\\src\\file\\person.data"
));
//讀取相應(yīng)的字節(jié)數(shù)組轉(zhuǎn)換成對應(yīng)的對象---反序列化
Person p=(Person)o.readObject();
//關(guān)流
o.close();
//輸出
System.out.println(p);
}
}