1神年、File
1)構(gòu)造方法
2)創(chuàng)建
3)判斷、獲取
4)刪除
2行嗤、字節(jié)流
1)字節(jié)流寫數(shù)據(jù)的3種方式
FileOutputStream fos = new FileOutputStream("e:\\a.txx");
//將字符轉(zhuǎn)為字節(jié)
Bytes[] bytes = "abcdefffjdlsajflasdfjklasdf".getBytes();
fos.write(bytes,0,bytes.length);
//關(guān)閉資源
fos.close();
2)字節(jié)流寫數(shù)據(jù)實(shí)現(xiàn)換行
fos.write("\rn\".getBytes());
windows:\r\n
linux:\n
mac:\r
3)字節(jié)流寫數(shù)據(jù)實(shí)現(xiàn)追加
FileOutputStream fos = new FileOutputStream("e:\\a.txx",true);
//加上true之后已日,就是從文件的末尾寫入,不加true栅屏,默認(rèn)是從文件的開頭寫入
4)異常處理
FileOutputStream fos = null;
try{
fos = new FileOutputStream("e:\\a.txx",true);
}catch(IOExcetion p){
e.printStackTrace();
}finally{
//不管文件讀寫有沒有出錯飘千,最后一定要 close資源
if(fos !=null)?fos.close();
}
3、讀寫文件
1)讀取文件
//讀取文件的數(shù)據(jù)栈雳,讀物1024整數(shù)個字節(jié)
public static? void readFile2()throws IOException {
FileInputStream input =new FileInputStream("e:\\file.txt");
//讀取1024字節(jié)及其整數(shù)倍
? ? byte[]bytes =new byte[1024];
//單次讀取的長度
? ? int len;
while ((len =input.read(bytes)) != -1){
System.out.println("長度:"+len);
System.out.println(new String(bytes,0,len));
}
2)寫入文件护奈,讀1024整數(shù)倍個字節(jié)
//實(shí)現(xiàn)將file.txt內(nèi)容寫入到file2.txt,讀取1024整數(shù)倍個字節(jié)
? ? public static void? readAndWrite() throws IOException {
? ? ? //先創(chuàng)建file2.txt
? ? ? FileOutputStream out = new FileOutputStream("e:\\file2.txt",true);
? ? ? //獲得file.txt,用于讀取文件
? ? ? FileInputStream input? = new FileInputStream("e:\\file.txt");
? ? ? //裝讀取文件的流
? ? ? ? byte[] b? = new byte[1024];
? ? ? ? //裝單次讀入大小
? ? ? ? int? len;
? ? ? ? //讀取文件數(shù)據(jù)
? ? ? ? while((len = input.read(b)) != -1){
? ? ? ? ? ? //將數(shù)據(jù)寫入到file2.txt
? ? ? ? ? ? out.write(b,0,len);
? ? ? ? }
? ? ? ? out.close();
? ? ? ? input.close();
? ? }
3)讀取1個字節(jié)就寫入一個字節(jié)
4哥纫、復(fù)制圖片
//復(fù)制圖片
? ? public? static? void readPicture() throws IOException {
? ? ? ? //圖片目的地
? ? ? ? FileOutputStream out = new FileOutputStream("e:\\pic.png");
? ? ? ? //圖片原始位置
? ? ? ? FileInputStream inputStream =new FileInputStream("e:\\25.png");
? ? ? ? //存取單次讀入的數(shù)據(jù)
? ? ? ? byte[] bytes = new byte[1024];
? ? ? ? //存取單次讀取的數(shù)據(jù)的長度
? ? ? ? int len;
? ? ? ? //讀數(shù)據(jù)
? ? ? ? while ((len = inputStream.read(bytes)) != -1){
? ? ? ? //寫數(shù)據(jù):bytes
? ? ? ? ? ? out.write(bytes,0,len);
? ? ? ? }
? ? ? ? out.close();
? ? ? ? inputStream.close();
? ? }
5霉旗、字節(jié)緩沖流
1)寫入數(shù)據(jù)
2)讀取數(shù)據(jù),一次讀取一個字節(jié)
3)讀取數(shù)據(jù)蛀骇,一次讀取一個字節(jié)數(shù)組
4)復(fù)制視頻
public static void readVedio()throws IOException {
? ? ? ? //1.找到視頻文件
? ? ? ? BufferedInputStream bis = new BufferedInputStream(new FileInputStream("e:\\08.avi"));
? ? ? ? //2.創(chuàng)建目標(biāo)文件
? ? ? ? BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("e:\\09.avi"));
? ? ? ? byte[] b =new byte[1024];
? ? ? ? int len;
? ? ? ? //3.讀取厌秒、寫入
? ? ? ? while ((len = bis.read(b)) !=-1) {
? ? ? ? ? bos.write(b,0,len);
? ? ? ? }
? ? ? ? //4.關(guān)閉流
? ? ? ? bos.close();
? ? ? ? bis.close();
? ? }
4、字符流
對于漢字的存儲擅憔,如果是GBK進(jìn)行編碼鸵闪,占用的是2個字節(jié);如果是UTF-8進(jìn)行編碼雕欺,占用3個字節(jié)岛马。
1)為什么出現(xiàn)字符流?
字節(jié)流操作中文不是特別方便屠列,Java提供了字符流
? ? 字符流=字節(jié)流+編碼表
在進(jìn)行漢字存儲時啦逆,無論哪一種編碼存儲,第一個字節(jié)都是負(fù)數(shù)笛洛。
2)字符串中的編碼與解碼
編碼:
byte[] getBytes?():使用平臺的默認(rèn)字符集將該 String編碼為一系列字節(jié)夏志,將結(jié)果存儲到新的字節(jié)數(shù)組中
byte[] getBytes?(String charsetName):使用指定的字符集將該 String編碼為一系列字節(jié),將結(jié)果存儲到新的字節(jié)數(shù)組中
解碼:
String?(byte[]? bytes):通過使用平臺的默認(rèn)字符集解碼指定的字節(jié)數(shù)組來構(gòu)造新的 String
String?(byte[]? bytes, String charsetName):通過指定的字符集解碼指定的字節(jié)數(shù)組來構(gòu)造新的String
2)字符流中的編碼與解碼
字符流抽象基類
Reader:字符輸入流的抽象類
Writer:字符輸出流的抽象類
字符流中和編碼解碼問題相關(guān)的兩個類:
InputStreamReader
OutputStreamWriter
//使用默認(rèn)編碼寫入
//? OutputStreamWriter osw =? new OutputStreamWriter(new FileOutputStream("e:\\file.txt"));
//使用指定編碼寫入
? OutputStreamWriter osw =new OutputStreamWriter(new FileOutputStream("e:\\file.txt"),"UTF-8");
osw.write("中國");
osw.close();
//使用默認(rèn)編碼讀取
//? InputStreamReader isr = new InputStreamReader(new FileInputStream("e:\\file.txt"));
? //使用指定編碼讀取
? InputStreamReader isr =new InputStreamReader(new FileInputStream("e:\\file.txt"),"UTF-8");
int len;
while ((len =isr.read())!=-1){
System.out.print((char)len);
}
//使用指定編碼讀取
isr.close();
3)字符流寫數(shù)據(jù)
//字符流寫數(shù)據(jù):方式一:void write(int c)
? ? OutputStreamWriter osw =new OutputStreamWriter(new FileOutputStream("e:\\file.txt"),"UTF-8");
//方式一:void write(int c)
? ? osw.write(97);
osw.write("\r\n");
//方式二:void write(char[] cbuf)
? ? char[]c =new char[]{'1','2','3'};
osw.write(c);
osw.write("\r\n");
//方式三:void write(char[] cbuf, int off, int len)
? ? char[]c2 =new char[]{'1','2','3','4','5','6','7'};
//從下標(biāo)為0開始寫苛让,寫入3個沟蔑,也就是1、2狱杰、3
? ? osw.write(c2,0,3);
osw.write("\r\n");
//方式四:void write(String str)
? ? String str ="zhangsan";
osw.write(str);
osw.write("\r\n");
//方式四:void write(String str, int off, int len)
? ? osw.write(str,0,3);//zha
? ? osw.write("\r\n");
osw.close();
4)字符流讀數(shù)據(jù)
InputStreamReader isr =new InputStreamReader(new FileInputStream("e:\\file.txt"));
//方式一:int read()
int len;
while ((len =isr.read())!=-1){
System.out.print((char)len);
}
// 方式二:int read(char[] cbuf)
char[]c =new char[1024];
while ((len =isr.read(c))!=-1){
System.out.print(new String(c,0,len));
}
isr.close();
5)復(fù)制文件
方式一:
方式二:使用FileReader與FileWriter
5瘦材、字符緩沖流
字符緩沖流:
BufferedWriter:將文本寫入字符輸出流,緩沖字符仿畸,以提供單個字符食棕,數(shù)組和字符串的高效寫入朗和,可以指定緩沖區(qū)大小,或者可以接受默認(rèn)大小簿晓。默認(rèn)值足夠大眶拉,可用于大多數(shù)用途
BufferedReader:從字符輸入流讀取文本,緩沖字符憔儿,以提供字符忆植,數(shù)組和行的高效讀取,可以指定緩沖區(qū)大小谒臼,或者可以使用默認(rèn)大小朝刊。
默認(rèn)值足夠大,可用于大多數(shù)用途
構(gòu)造方法:
BufferedWriter?(Writer out)
BufferedReader?(Reader in)
BufferedReader br =new BufferedReader(new FileReader("e:\\file.txt"));
BufferedWriter bw=new BufferedWriter(new FileWriter("e:\\file4.txt"));
int len;
char[]c =new char[1024];
while ((len =br.read(c))!=-1){
bw.write(c,0,len);
}
br.close();
bw.close();
}
1)特有功能
BufferedWriter:
void newLine?():寫一行行分隔符屋休,行分隔符字符串由系統(tǒng)屬性定義
BufferedReader:
public String readLine?() :讀一行文字坞古。
結(jié)果包含行的內(nèi)容的字符串,不包括任何行終止字符劫樟,如果流的結(jié)尾已經(jīng)到達(dá)痪枫,則為null
一行行讀取數(shù)據(jù),進(jìn)行文件復(fù)制:
public static void line2()throws IOException {
BufferedReader br =new BufferedReader(new FileReader("e:\\file.txt"));
BufferedWriter bw=new BufferedWriter(new FileWriter("e:\\file3.txt"));
String line;
while ((line =br.readLine())!=null){
bw.write(line);
bw.newLine();
}
br.close();
bw.close();
}
案例1:點(diǎn)名器
案例2:集合到文件(需求:把ArrayList集合中的學(xué)生數(shù)據(jù)寫入到文本文件叠艳。要求:每一個學(xué)生對象的數(shù)據(jù)作為文件中的一行數(shù)據(jù)奶陈。? ? ?格式:學(xué)號,姓名,年齡,居住地? 舉例:1001,李局,30,北京)
案例3:文件到集合(需求:把文本文件中的數(shù)據(jù)讀取到集合中,并遍歷集合附较。要求:文件中每一行數(shù)據(jù)是一個學(xué)生對象的成員變量值吃粒。舉例:舉例:1001,李局,30,北京)
案例4:集合到文件(數(shù)據(jù)排序)(鍵盤錄入5個學(xué)生信息(姓名,語文成績,數(shù)學(xué)成績,英語成績)。要求按照成績總分從低到高寫入文本文件? 拒课。? 格式:姓名,語文成績,數(shù)學(xué)成績,英語成績? 舉例:zs,18,9,10)
案例5:復(fù)制單級文件夾
public class TestFile {
? ? public static void main(String[] args) throws IOException {
? ? ? ? copyfile();
? ? }
? ? private static void copyfile() throws IOException {
? ? ? ? //獲取要復(fù)制的文件夾,源文件
? ? ? ? File srcFile = new File("e:\\file");
? ? ? ? //獲取文件名
? ? ? ? String srcFolderName = srcFile.getName();
? ? ? ? File destFolder = new File("e:\\照片",srcFolderName);
? ? ? ? //如果目的地目錄不存在徐勃,就新建
? ? ? ? if(!destFolder.exists()){
? ? ? ? ? ? destFolder.mkdir();
? ? ? ? }
? ? ? ? //獲取數(shù)據(jù)源目錄下的所有文件
? ? ? ? File[] files = srcFile.listFiles();
? ? ? ? for(File srcF:files){
? ? ? ? ? String srcFileName = srcF.getName();
? ? ? ? ? File destFile = new File(destFolder,srcFileName);
? ? ? ? ? copy(srcF,destFile);
? ? ? ? }
? ? }
//f1目標(biāo)文件,f2要輸入到的文件
? ? private static void copy(File f1, File f2) throws IOException {
? ? ? ? FileInputStream bis = new FileInputStream(f1);
? ? ? ? FileOutputStream bos =new FileOutputStream(f2);
? ? ? ? byte[] b= new byte[1024];
? ? ? ? int len;
? ? ? ? while ((len=bis.read(b))!=-1){
? ? ? ? ? ? bos.write(b,0,len);
? ? ? ? }
? ? bis.close();
? ? ? ? bos.close();
? ? }
}
案例6:復(fù)制多級文件夾
public class TestFile4 {
? ? private static String srcFatherPath="C:\\Users\\Administrator\\Desktop\\圖片";
? ? private static String desFatherPath="e:\\zfile";
? ? public static void main(String[] args) throws IOException {
? ? ? ? //找到文件對象
? ? ? ? File srcFile = new File(srcFatherPath);
? ? ? ? File desFile = new File(desFatherPath);
? ? ? ? //調(diào)用復(fù)制文件夾方法
? ? ? ? copyFolder(srcFile,desFile);
? ? }
? ? public static void copyFolder(File srcFile,File desFile) throws IOException {
? ? ? ? //如果源文件是一個文件夾
? ? ? ? if(srcFile.isDirectory()){
? ? ? ? ? //獲取文件夾的名稱
? ? ? ? ? ? String srcFileName = srcFile.getName();
? ? ? ? ? ? //創(chuàng)建目標(biāo)文件夾
? ? ? ? ? ? File desFolder = new File(desFile,srcFileName);
? ? ? ? ? ? //判斷目標(biāo)文件夾是否存在
? ? ? ? ? ? if(!desFolder.exists()){
? ? ? ? ? ? ? ? //不存在早像,新建
? ? ? ? ? ? ? ? desFolder.mkdirs();
? ? ? ? ? ? }
? ? ? ? ? ? //獲取文件夾僻肖,里面的文件對象數(shù)組
? ? ? ? ? ? File[] fileArray = srcFile.listFiles();
? ? ? ? ? ? //遍歷數(shù)組
? ? ? ? ? ? for(File file: fileArray){
? ? ? ? ? ? ? ? //對每個遍歷出來的對象,再次判斷是文件夾還是文件
? ? ? ? ? ? ? ? copyFolder(file,desFolder);
? ? ? ? ? ? }
? ? ? ? }else{
? ? ? ? ? ? //如果不是一個文件夾卢鹦,說明是一個文件臀脏,就復(fù)制文件
? ? ? ? ? ? File newFile = new File(desFile,srcFile.getName());
? ? ? ? ? ? copy(srcFile,newFile);
? ? ? ? }
? ? }
? ? private static void copy(File srcFile, File desFile) throws IOException {
? ? ? ? //讀取源文件
? ? ? ? FileInputStream fis =new FileInputStream(srcFile);
? ? ? ? //寫入新文件
? ? ? ? FileOutputStream fos = new FileOutputStream(desFile);
? ? ? ? int len;
? ? ? ? byte[] b = new byte[1024];
? ? ? ? while ((len=fis.read(b))!=-1){
? ? ? ? ? ? fos.write(b,0,len);
? ? ? ? }
? ? ? ? fos.close();
? ? ? ? fis.close();
? ? }
}
6、特殊操作流
1)標(biāo)準(zhǔn)輸入輸出流
輸入
輸出
(System.out)輸出語句的本質(zhì):是一個標(biāo)準(zhǔn)的輸出流
PrintStream ps = System.out;
PrintStream類有的方法冀自,System.out都可以使用
2)打印流
字節(jié)打印流:PrintStream
字符打印流:PrintWriter
打印流的特點(diǎn):
只負(fù)責(zé)輸出數(shù)據(jù)揉稚,不負(fù)責(zé)讀取數(shù)據(jù)。永遠(yuǎn)不會拋出IOException熬粗。有自己的特有方法搀玖。
字節(jié)打印流
PrintStream?(String fileName):使用指定的文件名創(chuàng)建新的打印流
使用繼承父類的方法寫數(shù)據(jù),查看的時候會轉(zhuǎn)碼驻呐;使用自己的特有方法寫數(shù)據(jù)巷怜,查看的數(shù)據(jù)原樣輸出
可以改變輸出語句的目的地
public static
void setOut?(PrintStream out):重新分配“標(biāo)準(zhǔn)”輸出流
字符打印流
復(fù)制文件
2)對象序列化流
要實(shí)現(xiàn)序列化和反序列化就要使用對象序列化流和對象反序列化流:
對象序列化流:ObjectOutputStream
對象反序列化流:ObjectInputStream
序列化
對象序列化
反序列化流
序列化與反序列化問題
a葛超、用對象序列化流序列化了一個對象后暴氏,假如我們修改了對象所屬的類文件延塑,讀取數(shù)據(jù)會不會出問題呢?
會出問題答渔,會拋出InvalidClassException異常
b关带、如果出問題了,如何解決呢沼撕?
重新序列化;給對象所屬的類加一個serialVersionUID
private static? final long serialVersionUID = 42L;
c宋雏、如果一個對象中的某個成員變量的值不想被序列化,又該如何實(shí)現(xiàn)呢务豺?
給該成員變量加transient關(guān)鍵字修飾磨总,該關(guān)鍵字標(biāo)記的成員變量不參與序列化過程
3)properties
Properties類表示一組持久的屬性。Properties可以保存到流中或從流中加載笼沥。屬性列表中的每個鍵及其對應(yīng)的值都是一個字符串蚪燕。
案例:猜數(shù)字游戲,將游戲剩余次數(shù)放入文件中