[TOC]
IO流
IO流概述及其分類
IO概念
IO流用來處理設(shè)備之間的數(shù)據(jù)傳輸,Java對數(shù)據(jù)的操作是通過流的方式
Java用于操作流的類都在IO包中诵盼,
流按流向分為兩種:
輸入流(讀取數(shù)據(jù))
輸出流(寫數(shù)據(jù))
流按操作類型分為兩種:
字節(jié)流 : 字節(jié)流可以操作任何數(shù)據(jù),因為在計算機中任何數(shù)據(jù)都是以字節(jié)的形式存儲的
字符流 : 字符流只能操作純字符數(shù)據(jù)惠豺,比較方便。
常用的IO流類
字節(jié)流的抽象父類
InputStream
OutputStream
字符流的抽象父類:
Reader
Writer
InputStream & FileInputStream 文件輸入流
InputStream是抽象類风宁,表示字節(jié)輸入流洁墙。
直接已知子類:
●AudioInputStream
●ByteArrayInputStream
●FileInputStream(學(xué)習(xí)文件輸入流)
●FilterInputStream
●ObjectInputStream
●PipedInputStream
●SequenceInputStream
●StringBufferInputStream
FileInputStream 文件輸入流
概述
FileInputStream 從文件系統(tǒng)中的某個文件中獲得輸入字節(jié)。FileInputStream 用于讀取諸如圖像數(shù)據(jù)之類的原始字節(jié)流戒财。要讀取字符流热监,請考慮使用 FileReader
構(gòu)造方法
FileInputStream(File file)
FileInputStream(String name)
成員方法
int read() 從此輸入流中讀取一個數(shù)據(jù)字節(jié)。
案例:讀取一個txt文件數(shù)據(jù)(方法一)
知識點
- 1.FileInputStream用于讀取文件數(shù)據(jù)饮寞,在構(gòu)造方法中傳入文件對象
- 2.構(gòu)造方法孝扛,有可能拋出文件找不到的異常
- 3.read方法是每次讀取一個字節(jié)的數(shù)據(jù),把字節(jié)轉(zhuǎn)成int返回
- 讀取數(shù)據(jù)也會拋出異常,比如突然文件某部份數(shù)據(jù)損壞了
- 讀取的數(shù)據(jù)是文件編碼的表值(ascii,GBK,unicode)
- ascii是包含在GBK或者unicode中的
- 如果讀取數(shù)據(jù)到最后幽崩,會返回一個-1(代表讀完數(shù)據(jù)了)
- 4.文件不用后苦始,要關(guān)閉輸入流,避免占用資源
package lesson10;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* 讀取txt文件內(nèi)容
* 1.通過FileInputStream來讀取txt文件內(nèi)容
* 2.讀取內(nèi)容通過read方法慌申,
* 》read方法每次讀文件1個字節(jié)(byte),把byte轉(zhuǎn)成int返回
》當(dāng)讀到后的時候陌选,返回-1,-1表示讀取文件結(jié)束
3.當(dāng)讀完文件后,這個輸入流要關(guān)閉咨油,釋放資源
*
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
//FileNotFoundException fnfe;
//案例:讀取txt文件內(nèi)容
//1.創(chuàng)建一個文件對象
File file = new File("a.txt");
//2.創(chuàng)建一個文件輸入流【讀取文件數(shù)據(jù)】對象
FileInputStream fis1 = new FileInputStream(file);
//再創(chuàng)建一個文件輸入 流對象
FileInputStream fis2 = new FileInputStream("b.txt");
//3.讀取a.txt的數(shù)據(jù)
/**
* 1.read方法每次讀文件1個字節(jié)(byte),把byte轉(zhuǎn)成int返回
* 2.當(dāng)讀到后的時候您炉,返回-1,-1讀取文件結(jié)束
*/
System.out.println(fis1.read());
System.out.println(fis1.read());
System.out.println(fis1.read());
System.out.println(fis1.read());
//4.關(guān)閉流
fis1.close();
fis2.close();
}
}
案例:讀取一個txt文件數(shù)據(jù)(方法二)
//1.創(chuàng)建一個文件對象
File file = new File("abc.txt");
System.out.println(file.getAbsolutePath());
//2.創(chuàng)建一個文件輸入流
FileInputStream inputStream = new FileInputStream(file);
int b;
//while循環(huán)里臼勉,每次讀取字節(jié)賦值給b
while((b = inputStream.read()) != -1){
System.out.println(b);
}
面試題:read()方法讀取的是一個字節(jié),為什么返回是int,而不是byte 邻吭?
因為字節(jié)輸入流可以操作任意類型的文件,比如圖片音頻等,這些文件底層都是以二進(jìn)制形式的存儲的,如果每次讀取都返回byte,有可能在讀到中間的時候遇到111111111 那么這11111111是byte類型的-1,我們的程序是遇到-1就會停止不讀了,后面的數(shù)據(jù)就讀不到了,所以在讀取的時候用int類型接收,如果11111111會在其前面補上 24個0湊足4個字節(jié),那么byte類型的-1就變成int類型的255了這樣可以保證整個數(shù)據(jù)讀完,而結(jié)束標(biāo)記的-1就是int類型
package lesson12;
public class Demo01 {
public static void main(String[] args) {
//面試題:read()方法讀取的是一個字節(jié),為什么返回是int,而不是byte ?
//如果使用FileInputStream讀取圖片數(shù)據(jù)
/**
* 00010111 00010111 00010111 00010111
* 00010111 11111111 00010111 00010111
*
* byte:11111111 表示的-1
* int:00000000 00000000 00000000 11111111 byte轉(zhuǎn)成int 補0 了不是-1 因此往后讀數(shù)據(jù)
*
* 為什么11111111是表示-1宴霸?
* 因為計算機是以補碼的方式計算
* 補碼: 11111111 (-1)
* 反碼: 11111110
* 原碼: 10000001
*
* 假如使用FileInputStream讀取圖片的時候囱晴,
* 圖片中間有一段數(shù)據(jù)剛好是 11111111,這八個一表示的-1瓢谢,用byte接收
* java程序如果讀取的是-1畸写,后面的數(shù)據(jù)就不讀取
* 如果把8個1轉(zhuǎn)成int,那就是00000000 00000000 00000000 11111111,這個表示255,
* 就不是-1氓扛,歸避后面數(shù)據(jù)沒有讀取問題
*
*/
}
}
OutputStream & FileOutputStream 文件輸出流
文件輸出流是用于將數(shù)據(jù)寫入 File 的輸出流枯芬。
FileOutputStream 用于寫入諸如圖像數(shù)據(jù)之類的原始字節(jié)的流。
查看文檔的構(gòu)造方法和成員方法
-
案例:往一個abc.txt文件寫數(shù)據(jù)(知識點)
new FileOutputStream(file)這種構(gòu)造方法采郎,會把以前的內(nèi)容都刪除
new FileOutputStream(file,true);這種構(gòu)造方法能追加內(nèi)容
FileNotFoundException是IOException的子類
write(int b)千所,寫數(shù)據(jù)
package lesson13;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Demo01 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
/* FileOutputStream:表示文件輸出流,用于往文件寫內(nèi)容
*
* 構(gòu)造方法
* FileOutputStream(String name)
* FileOutputStream(File file)
*
* 方法
* write(int b);//每次寫一個字節(jié)
* write(byte[] b) ;//一次寫多個字節(jié)
* */
//案例:往b.txt 寫個內(nèi)容
//1.創(chuàng)建文件輸出流對象
//FileOutputStream fos = new FileOutputStream("b.txt");
OutputStream fos = new FileOutputStream("b.txt");//多態(tài)寫法
//2.寫數(shù)據(jù)
// fos.write(97);//a
// fos.write(98);//b
// fos.write(99);//c
//一次性寫多個字節(jié)
byte[] bytes = {97,98,99,100,101};
fos.write(bytes);
//3.關(guān)閉流
fos.close();
}
}
案例:拷貝圖片和音頻
- 原理蒜埋,使用輸入流讀取數(shù)據(jù)淫痰,使用輸出流寫數(shù)據(jù)
- 畫圖講原理和性能
每次都讀一次字節(jié),太慢整份,效率太低
package lesson14;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
//案例:拷貝圖片
/**
* 目的:結(jié)合輸入流和輸出流使用
*
* 圖片路徑:C:\Users\10301\Desktop\a\cm.jpg
*/
//1.先創(chuàng)建輸入流對象和輸出流對象
FileInputStream fis = new FileInputStream("C:/Users/10301/Desktop/a/cm.jpg");
FileOutputStream fos = new FileOutputStream("C:/Users/10301/Desktop/a/cm2.jpg");
//2.通過輸入流讀取圖片的數(shù)據(jù)
int b = 0;
while( (b = fis.read()) != -1){
//3.通過輸出流寫入圖片數(shù)據(jù)
fos.write(b);
}
//4.關(guān)閉流
fos.close();
fis.close();
System.out.println("圖片拷貝成功");
}
}
字節(jié)數(shù)組拷貝之a(chǎn)vailable()方法
package lesson01;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
//案例:拷貝圖片【優(yōu)化一待错、這種方式在大文件下不建議使用】
/**
* 前面拷貝圖片問題:每次只讀一個字節(jié),寫入的時候也是一個字節(jié)一個字節(jié)寫
* 如果有10W個字節(jié)烈评,就要讀10W次火俄,寫10W次
*
* 字節(jié)數(shù)組拷貝之a(chǎn)vailable()方法
*/
//1.文件輸入流
FileInputStream fis = new FileInputStream("C:/Users/10301/Desktop/a/cm.jpg");
int size = fis.available();//是返回文件的長度【字節(jié)為單位】
System.out.println("文件的大小:" + size);
//2.現(xiàn)在一次讀文件大小的字節(jié)
//2.1定義一個字節(jié)數(shù)組
byte[] bytes = new byte[size];//相當(dāng)于現(xiàn)在是一個空杯子
//2.2 把數(shù)據(jù)讀到字節(jié)數(shù)組中
int r = fis.read(bytes);//這個方法的返回值讀取到的實際長度
System.out.println("r:" + r);
//3.把字節(jié)數(shù)組一次性寫入到文件
//3.1 輸出流
FileOutputStream fos = new FileOutputStream("C:/Users/10301/Desktop/a/cm-副本.jpg");
//3.2 寫數(shù)據(jù)
fos.write(bytes);
//4.關(guān)閉流
fis.close();
fos.close();
}
}
案例:正確的拷貝文件的方法(杯子思想、緩沖思想)
1.輸入流讀取數(shù)據(jù)的方法:
read(byte[] b) 讀取指定字節(jié)數(shù)的數(shù)據(jù)
2.輸出流寫數(shù)據(jù)的方法:
write(byte[] b)
write(byte[] b, int off, int len)寫出有效的字節(jié)個數(shù)
package lesson02;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 杯子思想,緩沖思想
* @author gyf
*
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
//案例:拷貝圖片【優(yōu)化二讲冠、這種方式開發(fā)中建議經(jīng)常使用】
/**
* 1.每次只讀一個字節(jié)瓜客,又覺得太慢
* 2.一次性讀一個文件的所有數(shù)據(jù),又怕內(nèi)存裝不下
* 內(nèi)存只有2G,視頻3G,這樣就會內(nèi)存溢出
*
* 3.最終解決方法:折中竿开,定義每次讀8KB
*
*/
//1.輸入流
FileInputStream fis = new FileInputStream("C:/Users/10301/Desktop/a/cm.jpg");
//2.輸出流
FileOutputStream fos = new FileOutputStream("C:/Users/10301/Desktop/a/cm-副本2.jpg");
//3.定義個8kb字節(jié)數(shù)組谱仪,也叫緩沖區(qū)流
byte[] bytes = new byte[1024 * 8];
int len = 0;
int i = 0;
while( (len = fis.read(bytes)) != -1){
i++;
//4.寫入文件
fos.write(bytes,0,len);
}
System.out.println("讀取的次數(shù):" + i);
//5.關(guān)閉流
fis.close();
fos.close();
}
}
BufferedInputStream和BufferOutputStream
- 這兩個流是內(nèi)置了緩沖區(qū)流,也就是說內(nèi)部有一個 字節(jié)數(shù)組
- 緩沖思想
字節(jié)流一次讀寫一個數(shù)組的速度明顯比一次讀寫一個字節(jié)的速度快很多,
java本身在設(shè)計的時候,加入了數(shù)組這樣的緩沖區(qū)效果德迹,
也考慮到了這樣的設(shè)計思想(裝飾設(shè)計模式后面講解)芽卿,所以提供了字節(jié)緩沖區(qū)流 - BufferedInputStream
BufferedInputStream內(nèi)置了一個緩沖區(qū)(數(shù)組)
從BufferedInputStream中讀取一個字節(jié)時
BufferedInputStream會一次性從文件中讀取8192個(8Kb), 存在緩沖區(qū)中, 返回給程序
程序再次讀取時, 就不用找文件了, 直接從緩沖區(qū)中獲取
直到緩沖區(qū)中所有的都被使用過, 才重新從文件中讀取8192個 - BufferedOutputStream
BufferedOutputStream也內(nèi)置了一個緩沖區(qū)(數(shù)組)
程序向流中寫出字節(jié)時, 不會直接寫到文件, 先寫到緩沖區(qū)中
直到緩沖區(qū)寫滿, BufferedOutputStream才會把緩沖區(qū)中的數(shù)據(jù)一次性寫到文件里
案例:使用緩沖輸入輸出流拷貝文件
package lesson03;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//1.創(chuàng)建文件輸入流
FileInputStream fis = new FileInputStream("C:/Users/10301/Desktop/a/ghsy.mp3");
//2.創(chuàng)建文件輸出流
FileOutputStream fos = new FileOutputStream("C:/Users/10301/Desktop/a/ghsy-副本.mp3");
//3.輸入流讀數(shù)據(jù)揭芍、輸出流寫數(shù)據(jù)
int b = 0;
while( (b = fis.read()) != -1){
fos.write(b);
}
//4.關(guān)流
fis.close();
fos.close();
System.out.println("音頻拷貝完成...");
}
private static void test1() throws FileNotFoundException, IOException {
/* BufferedInputStream和BufferedOutputStream
>這兩個流是內(nèi)置了緩沖區(qū)流,也就是說內(nèi)部有一個字節(jié)數(shù)組
>這個兩個類沒有前面我們寫的好用胳搞,因為它內(nèi)部每次讀8kb字節(jié),如果想讀80kb,沒辦法
*/
//案例:拷貝音頻文件
//1.創(chuàng)建緩沖輸入流
FileInputStream fis = new FileInputStream("C:/Users/10301/Desktop/a/ghsy.mp3");
BufferedInputStream bis = new BufferedInputStream(fis);
//2.創(chuàng)建緩沖輸出流
FileOutputStream fos = new FileOutputStream("C:/Users/10301/Desktop/a/ghsy-副本.mp3");
BufferedOutputStream bos =new BufferedOutputStream(fos);
//3.輸入流讀數(shù)據(jù)、輸出流寫數(shù)據(jù)
int b = 0;
// bis.read()方法肌毅,內(nèi)部會讀8kb數(shù)據(jù)
while( (b = bis.read()) != -1){
bos.write(b);//內(nèi)部會寫8kb數(shù)據(jù)
}
//4.關(guān)流,只需要關(guān)緩沖流筷转,文件流不用關(guān)
bis.close();//【內(nèi)部會關(guān)文件流輸入流】
bos.close();//【內(nèi)部會關(guān)文件流輸出流】
System.out.println("音頻拷貝完成...");
}
}
帶Buffered的流和自己寫的數(shù)組緩沖對比
自己寫 的數(shù)組的讀寫和帶Buffered的讀取哪個更快?
自己寫數(shù)組會略勝一籌,因為讀和寫操作的是同一個數(shù)組
而Buffered操作的是兩個數(shù)組
BufferOutputStream的flush和close方法的區(qū)別
- flush()方法
用來刷新緩沖區(qū)的,刷新后可以再次寫出 - close()方法
用來關(guān)閉流釋放資源的的,如果是帶緩沖區(qū)的流對象的close()方法,不但會關(guān)閉流,還會再關(guān)閉流之前刷新緩沖區(qū),關(guān)閉后不能再寫出
package lesson05;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
//BufferedOutputStream的flush和close方法的區(qū)別
/* flush()方法
1.用來刷新緩沖區(qū)的,刷新后可以再次寫出
close()方法
2.用來關(guān)閉流釋放資源的
3.如果是帶緩沖區(qū)的流對象的close()方法,不但會關(guān)閉流,還會再關(guān)閉流之前刷新緩沖區(qū),關(guān)閉后不能再寫出
*/
//案例:把a文件的內(nèi)容拷貝到b文件
//1.輸入流
FileInputStream fis = new FileInputStream("a.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
//2.輸出流
FileOutputStream fos = new FileOutputStream("b.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
//3.讀寫操作
int b = 0;
while( (b = bis.read()) != -1){
bos.write(b);
}
bos.flush();
bos.write(97);
//bos.flush();
//4.關(guān)閉流
bis.close();
bos.close();
}
}
字節(jié)流讀寫中文亂碼問題
字節(jié)流讀取中文:
字節(jié)流讀取中文的問題
字節(jié)流在讀中文的時候有可能會讀到半個中文,造成亂碼
package lesson06;
import java.io.FileInputStream;
import java.io.IOException;
public class Demo06 {
public static void main(String[] args) throws IOException {
//字節(jié)流讀寫中文亂碼問題
//1.讀數(shù)據(jù)
//創(chuàng)建文件輸入流
FileInputStream fis = new FileInputStream("a.txt");
//讀
//定義字節(jié)數(shù)組[杯子思想,緩沖區(qū)思想]
/**
* 在UTF-8編碼表中悬而,一個中文占3個字節(jié),一個英文占1個字節(jié)
* 在GBK編譯中呜舒,一個中文占2個字節(jié)
*/
byte buf[] = new byte[3];
int len = 0;
while( (len = fis.read(buf)) != -1){
System.out.println("len:" + len );
//把字節(jié)轉(zhuǎn)成字符串
String s = new String(buf, 0, len);
System.out.println("s:" + s);
}
}
}
字節(jié)流寫入中文的問題
字節(jié)流直接操作的字節(jié),所以寫出中文必須將字符串轉(zhuǎn)換成字節(jié)數(shù)組
寫出回車換行 write("\r\n".getBytes());
package lesson07;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
//案例:往a.txt文件寫中文
//1.輸出流
FileOutputStream fos = new FileOutputStream("a.txt");
//2.寫中文
String s = "你好,Gosling最近好嗎笨奠?";
//把字符轉(zhuǎn)成字節(jié)數(shù)組
//byte[] bytes = s.getBytes();
/**
* charsetName 字符編碼 UTF-8(Unicode),GBK,ASCII
*/
byte[] bytes = s.getBytes("UTF-8");
fos.write(bytes);
//3.關(guān)流
fos.close();
}
}
流的標(biāo)準(zhǔn)處理異常代碼1.6版本及其以前
package lesson08;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException{
//流的標(biāo)準(zhǔn)處理異常代碼-jdk1.6版本及其以前
//案例:a.txt的內(nèi)容拷貝到b.txt
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("b.txt");
try {
//讀寫數(shù)據(jù)會拋出
int b = 0;
while((b = fis.read()) != -1){
fos.write(b);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//關(guān)流
try {
fis.close();
}finally {
fos.close();
}
}
}
public static void test1() throws FileNotFoundException {
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("b.txt");
try {
//讀寫數(shù)據(jù)會拋出
int b = 0;
while((b = fis.read()) != -1){
fos.write(b);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//關(guān)流
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
流的標(biāo)準(zhǔn)處理異常代碼1.7以上版本
原理:在try()中創(chuàng)建的流對象必須實現(xiàn)了AutoCloseable這個接口,如果實現(xiàn)了,在try后面的{}(讀寫代碼)執(zhí)行后就會自動調(diào)用,流對象的close方法將流關(guān)掉
package lesson09;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Demo01 {
public static void main(String[] args)throws Exception {
//流的標(biāo)準(zhǔn)處理異常代碼1.7版本
/**
* 1.把流對象的聲明放在try() 括號里面
* 2.操作流【讀寫數(shù)據(jù)】的代碼放在花括號里面
* 3.這樣寫不用關(guān)閉流袭蝗,java自動關(guān)閉流
* 4.在try的括號里的對象,必須是實現(xiàn)AutoCloseable的接口
*/
try(
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("b.txt");
//Person p = new Person();
//聲明一個自己輸入流
MyInputStream myis = new MyInputStream();
){
int b = 0;
while((b = fis.read()) != -1){
fos.write(b);
}
}
}
}
class Person{
}
class MyInputStream implements AutoCloseable{
@Override
public void close() throws Exception {
System.out.println("我的輸入流關(guān)閉了...");
}
}
練習(xí):圖片加密
package lesson10;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args)throws IOException {
// TODO Auto-generated method stub
//練習(xí):圖片加密
//1.輸入輸出流
FileInputStream fis = new FileInputStream("C:/Users/10301/Desktop/a/cm2.jpg");
FileOutputStream fos = new FileOutputStream("C:/Users/10301/Desktop/a/cm.jpg");
//2.讀寫數(shù)據(jù)
/**
* 加密操作
* 解密操作
*
* 一個數(shù)異或2次般婆,數(shù)據(jù)不變
*/
int b = 0;
while((b = fis.read()) != -1){
fos.write(b ^ 5);
}
//3.關(guān)流
fis.close();
fos.close();
System.out.println("圖片加密完成");
}
}
練習(xí):根據(jù)用戶輸入的文件拷貝文件到當(dāng)前項目目錄
package lesson11;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class Demo01 {
public static void main(String[] args) throws IOException {
//練習(xí):根據(jù)用戶輸入的文件[圖片]拷貝文件到當(dāng)前項目目錄
//C:/Users/10301/Desktop/a/cm2.jpg
//1.獲取用戶輸入的文件路徑
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入一個文件的路徑[請不要輸入文件夾路徑]:");
String path = scanner.nextLine();
//2.判斷這個路徑是否為文件
File file = new File(path);
if(file.isDirectory()){
System.out.println("您輸入的路徑不是一個文件");
return;
}
//3.如果是文件就拷貝
//3.1 輸入流
FileInputStream fis = new FileInputStream(path);
//3.2輸出流
FileOutputStream fos = new FileOutputStream(file.getName());
//3.3讀寫【性能】
byte[] buf = new byte[8 * 1024];
int len = 0;
while((len = fis.read(buf)) != -1){
fos.write(buf, 0, len);
}
//3.4關(guān)流
fis.close();
fos.close();
System.out.println("文件拷貝完成...");
}
}
練習(xí):錄入數(shù)據(jù)拷貝到文件
/**
* 根據(jù)用戶在鍵盤中輸入的內(nèi)容到腥,然后寫到一個文件中去
*
*/
package lesson12;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class Demo01 {
public static void main(String[] args) throws IOException {
//練習(xí):錄入數(shù)據(jù)拷貝到文件
//1.創(chuàng)建一個文件輸出流
FileOutputStream fos = new FileOutputStream("new.txt");
//2.創(chuàng)建一個Scanner對象
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入需要錄入內(nèi)容...輸入quit代表退出");
//3.通過死循環(huán)來獲取用戶輸入【當(dāng)輸入quit,代表不錄入】
while(true){
//獲取用戶的輸入
String line = scanner.nextLine();
//退出循環(huán)
if(line.equals("quit")){
break;
}
//寫入文件
fos.write(line.getBytes());
//換行
fos.write("\r\n".getBytes());
}
//4.關(guān)流
fos.close();
}
}
字符流概念
字符流是什么
1蔚袍、字符流是可以直接讀寫字符的IO流
2乡范、字符流讀取字符, 就要先讀取到字節(jié)數(shù)據(jù), 然后轉(zhuǎn)為字符.
3、寫入字符, 需要把字符轉(zhuǎn)為字節(jié)再寫出.
字符流有Reader和Writer兩大派,開發(fā)中使用它們的子類(查看API)
FileReader 讀取字符流類
FileWrite 寫入字符流類
FileReader 讀取字符流
查看API的方法
案例:使用FileReader 讀取一個文本數(shù)據(jù)(知識點):
1啤咽、read方法是讀取字符char
2晋辆、一個字符可能占用1個字節(jié),2個字節(jié)宇整,或者3個字節(jié)
3瓶佳、占用字節(jié)個的數(shù)根據(jù)碼表決定(ASCII:1字節(jié),GBK:2字節(jié) unicode:3個字節(jié))
4没陡、用int表示字節(jié)涩哟,假如讀取到2個字節(jié),int有4個字節(jié)盼玄,前個兩個字節(jié)可以補0
5贴彼、GBK,unicode中,中文的字符的第一個字節(jié)都是負(fù)數(shù)埃儿,所以知道怎么去讀取
6器仗、讀取的方式與FileInputStream字節(jié)流差不多,會用FileInputStream童番,就會用 FileReader
package lesson13;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/**
* 以后讀純文本文件精钮,使用FileReader這個類,為什么剃斧?因為我們不用考慮亂碼問題
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
//讀字節(jié)
FileInputStream fis = new FileInputStream("a.txt");
//int 00000000 00000000 00000000 11111111
System.out.println((byte)fis.read());
System.out.println((byte)fis.read());
System.out.println((byte)fis.read());
System.out.println((byte)fis.read());
System.out.println((byte)fis.read());
System.out.println((byte)fis.read());
System.out.println((byte)fis.read());
}
public static void test1() throws FileNotFoundException, IOException {
//FileReader
/**
* FileReader 用于讀取字符
*/
//1.創(chuàng)建對象
FileReader reader = new FileReader("a.txt");
//2.讀取數(shù)據(jù)
/**
* reader.read() : 先讀取到字節(jié)數(shù)據(jù), 然后轉(zhuǎn)為字符
*/
System.out.println((char)reader.read());
System.out.println((char)reader.read());
System.out.println((char)reader.read());
System.out.println((char)reader.read());
System.out.println((char)reader.read());
System.out.println(reader.read());
int c;
while((c = reader.read()) != -1){
System.out.println((char)c);
}
//3.關(guān)閉流
reader.close();
}
}
FileWiter 寫入字符流
查看API中FileWriter的方法
案例:使用FileWrite寫入數(shù)據(jù)(知識點)
1.其實內(nèi)部是通過一個字符數(shù)組緩沖區(qū)寫入文件
2.內(nèi)部方法轨香,創(chuàng)建一個字符串長度的字符數(shù)組緩存區(qū)
package lesson14;
import java.io.FileWriter;
import java.io.IOException;
/**
* FileWiter:
* 掌握:
* 1.write方法使用
* 2.write方法內(nèi)部實現(xiàn),內(nèi)部是通過一個字符數(shù)組緩沖區(qū)寫入文件
*
*/
public class Demo01 {
public static void main(String[] args) throws Exception {
//FileWiter 文件寫入流幼东、文件寫入字符流
//案例:使用FileWiter往一個文件a.txt寫內(nèi)容
//1.創(chuàng)建writer對象
FileWriter writer = new FileWriter("a.txt");
//2.寫內(nèi)容
writer.write("你好!");
writer.write("\r\n");
writer.write("你好!");
writer.write("\r\n");
writer.write("你好!");
writer.write("\r\n");
writer.write("你好!");
//3.關(guān)閉
writer.close();
}
}
案例:字符流的拷貝
//案例:字符流的拷貝
//思路:用FileReader讀字符,用FileWriter寫字符
package lesson15;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
//案例:字符流的拷貝
//思路:用FileReader讀字符,用FileWriter寫字符
//1.創(chuàng)建 “讀取流” 對象
FileReader reader = new FileReader("a.txt");
//2.創(chuàng)建 "寫入流" 對象
FileWriter writer = new FileWriter("b.txt");
//3.讀取和寫入【緩沖思想】
char[] buf = new char[8 * 1024];
int len = 0;
while( (len = reader.read(buf)) != -1){
writer.write(buf, 0, len);
}
//4.關(guān)閉流
reader.close();
writer.close();
}
public static void test1() throws FileNotFoundException, IOException {
//1.創(chuàng)建 “讀取流” 對象
FileReader reader = new FileReader("a.txt");
//2.創(chuàng)建 "寫入流" 對象
FileWriter writer = new FileWriter("b.txt");
//3.讀取和寫入
int c = 0;
while((c = reader.read()) != -1){
writer.write(c);
}
//4.關(guān)閉流
reader.close();
writer.close();
}
}
使用字符流的場景
package lesson01;
import java.io.FileWriter;
public class Demo01 {
public static void main(String[] args) {
//使用字符流的場景
/**
* 1.使用FileReader讀取字符
* 原理:先讀字節(jié)臂容,把字節(jié)轉(zhuǎn)成字符(byte -> char)
* 2.使用FileWriter寫入字符
* 原理:writer(String str),str 轉(zhuǎn)成 字符數(shù)組 再轉(zhuǎn)成 字節(jié)寫入文件
* (string -> char[] -> char -> byte)
* 如果是讀取文本文件科雳,使用FileReader比較好,不考慮亂碼問題
* 如果是寫入文本文件,不建議使用FileWriter,直接使用FileOutputStream好一點
*/
}
}
帶緩沖的字符流 BufferedReader/BufferedWriter
-
BufferedReader
- read()方法讀取字符時會一次讀取若干字符到緩沖區(qū),然后逐個返回給程序, 降低讀取文件的次數(shù), 提高效率
-
BufferedWriter
- write()方法寫出字符時會先寫到緩沖區(qū)緩沖區(qū)寫滿時才會寫到文件, 降低寫文件的次數(shù), 提高效率
- 查看源碼:字符緩沖區(qū)的大小是8192
package lesson02;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
/**
* 帶緩沖的字符流 BufferedReader/BufferedWriter
* 1.這兩個類脓杉,內(nèi)部都一個緩沖區(qū)糟秘,字符數(shù)組
* 2.br.read()方法,內(nèi)部會讀8192(8*1024)個字符
* 3.bw.write(),內(nèi)部會寫8192(8*1024)個字符
*
* 回顧:帶緩沖的字節(jié)流,BufferedInputStream/BufferedOutputStream
* 1.這兩個類球散,內(nèi)部都一個緩沖區(qū)尿赚,字節(jié)數(shù)組
*/
//需求:拷貝文件,a.txt -> b.txt
//1.創(chuàng)建Reader
FileReader fr = new FileReader("a.txt");
BufferedReader br = new BufferedReader(fr);
//2.創(chuàng)建Writer
FileWriter fw =new FileWriter("b.txt");
BufferedWriter bw = new BufferedWriter(fw);
//3.讀寫
int c = 0;
while( (c = br.read()) != -1){
bw.write(c);
}
//4.關(guān)流
br.close();//內(nèi)部關(guān)閉FileReader
bw.close();//內(nèi)部關(guān)閉FileWriter
}
}
BufferedReader的readLine()&BufferedWriter的newLine()方法
package lesson03;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
//BufferedReader的readLine()&BufferedWriter的newLine()方法
/**
* 1.readLine(),每次讀取一行數(shù)據(jù)
*/
//1.創(chuàng)建Reader
FileReader fr = new FileReader("a.txt");
BufferedReader br = new BufferedReader(fr);
//2.讀一行數(shù)據(jù)
/* System.out.println(br.readLine());
System.out.println(br.readLine());
System.out.println(br.readLine());
System.out.println(br.readLine());
System.out.println(br.readLine());
System.out.println(br.readLine());*/
String line = null;
while((line = br.readLine()) != null){
System.out.println(line);
}
//3.關(guān)流
br.close();
}
}
BufferedWriter的newLine()方法
package lesson04;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
//BufferedWriter的newLine()方法
// newLine()換行
//往b.txt寫a.txt文件的內(nèi)容【一行一行拷貝,讀一行寫一行】
//1.創(chuàng)建Reader
FileReader fr = new FileReader("a.txt");
BufferedReader br = new BufferedReader(fr);
//2.創(chuàng)建writer
FileWriter fw = new FileWriter("b.txt");
BufferedWriter bw = new BufferedWriter(fw);
//3.讀一行寫一行
String line = null;
while((line = br.readLine()) != null){
bw.write(line);
/**
* 當(dāng)使用readline讀取一行數(shù)據(jù)時蕉堰,不會讀回車換行"\r\n"字符
*/
//bw.write("\r\n");
bw.newLine();//換行
}
//4.關(guān)流
br.close();
bw.close();
}
}
案例:使用帶緩沖的字符流拷貝文件
**BufferedReader的readLine()&BufferedWriter的newLine()方法 **
BufferedReader的readLine()方法可以讀取一行字符(不包含換行符號)
BufferedWriter的newLine()可以輸出一個跨平臺的換行符號"\r\n"
案例:將文本反轉(zhuǎn)
一個文本文檔上的文本反轉(zhuǎn),第一行和倒數(shù)第一行交換,第二行和倒數(shù)第二行交換
package lesson05;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 掌握思想:
* 1.for循環(huán)的倒序遍歷
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
//案例:將文本反轉(zhuǎn)寫入另一個文件
//1.把文本每一行內(nèi)容讀取出來存在List<String> 集合
//1.1 集合對象
List<String> list = new ArrayList<String>();
//1.2一行行讀取文件
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
String line = null;
while((line = br.readLine()) != null){
list.add(line);
}
System.out.println(list);
//2.當(dāng)我們要寫入文件時凌净,倒序保存List集合中的內(nèi)容到文件中
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
for(int i = list.size() - 1 ; i>=0; i--){
bw.write(list.get(i));
bw.newLine();//換行
}
//3.關(guān)閉流
br.close();
bw.close();
System.out.println("finish....");
}
}
裝飾(Decorator)設(shè)計模式
裝飾模式的概念:
動態(tài)的給一個對象添加一些額外的功能,就增加功能來說屋讶,裝飾模式比生成子類更為靈活泻蚊。
在不必改變原類文件和使用繼承的情況下,動態(tài)的擴(kuò)展一個對象的功能丑婿。
它是創(chuàng)建一個包裝對象性雄,也就是使用裝飾來包裹真實的對象。
適用性
- 需要擴(kuò)展一個類的功能羹奉,或給一個類添加附加職責(zé)秒旋。
- 當(dāng)不能采用生成子類來實現(xiàn),比如final類
裝飾模式的實現(xiàn)方式
- 裝飾對象和真實對象有相同的接口诀拭。
- 裝飾對象包含一個真實對象的引用(reference)
- 裝飾對象的所有方法迁筛,內(nèi)部實現(xiàn)都是通過真實對象的引用來調(diào)用,然后實現(xiàn)自己的功能
案例1:
package lesson06;
public class Demo01 {
public static void main(String[] args) {
//
/**
* 一耕挨、設(shè)計模式【一種固定代碼風(fēng)格】
* 面試題:Java中有哪些設(shè)計模式
* 常用設(shè)計模式:裝飾模式细卧、單例模式、模版模式筒占、適配器模式贪庙、代理模式、工廠模式...
*
* 二翰苫、裝飾(Decorator)設(shè)計模式
* 1.裝飾模式的概念:
裝飾模式是動態(tài)的給一個對象添加一些額外的功能止邮,就增加功能來說,裝飾模式比生成子類更為靈活奏窑。
裝飾模式是在不必改變原類文件和使用繼承的情況下导披,動態(tài)的擴(kuò)展一個對象的功能。
裝飾模式是創(chuàng)建一個包裝對象埃唯,也就是使用裝飾來包裹真實的對象撩匕。
2.裝飾模式的實現(xiàn)方式
1. 裝飾對象和真實對象有相同的接口/抽象類。
2. 裝飾對象包含一個真實對象的引用(reference)
3. 裝飾對象的所有方法墨叛,內(nèi)部實現(xiàn)都是通過真實對象的引用來調(diào)用止毕,然后實現(xiàn)自己的功能
3.適用性
1. 需要擴(kuò)展一個類的功能并村,或給一個類添加附加職責(zé)。
2. 當(dāng)不能采用生成子類來實現(xiàn)滓技,比如final類
*/
/* BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream bos;
BufferedReader br;
BufferedWriter bw;*/
/*GYFStudent stu = new GYFStudent();
stu.code();*/
GYFStudent stu = new GYFStudent(new UniversityStudent());
stu.code();
}
}
//1.接口
interface Person{
public void code();
}
//2.接口實現(xiàn)類
final class UniversityStudent implements Person{
@Override
public void code() {
// TODO Auto-generated method stub
System.out.println("在大學(xué)期間學(xué)了一點點C語言...");
}
}
/*class GYFStudent extends UniversityStudent{
@Override
public void code() {
// TODO Auto-generated method stub
super.code();
System.out.println("在GYF IT EDU 學(xué)習(xí)Java語言...");
}
}*/
class GYFStudent implements Person{
private UniversityStudent us;
public GYFStudent(UniversityStudent us){
this.us = us;
}
//裝飾對象的所有方法,內(nèi)部實現(xiàn)都是通過真實對象的引用來調(diào)用棚潦,然后實現(xiàn)自己的功能
@Override
public void code() {
us.code();
System.out.println("在GYF IT EDU 學(xué)習(xí)Java語言...");
}
}
案例2:
package com.gyf.lesson09;
public class Demo {
public static void main(String[] args) {
GYFStudent stu = new GYFStudent();
stu.coding();
}
}
interface Person {
//人可以具備編碼的功能
public void coding();
}
//大學(xué)生
class UniversityStudent implements Person{
@Override
public void coding() {
System.out.println("我會一點c基礎(chǔ)編程...");
}
public void piano(){
System.out.println("我會鋼琴...");
}
}
//第一種繼承類的寫法
class GYFStudent extends UniversityStudent{
@Override
public void coding() {
// TODO Auto-generated method stub
super.coding();
System.out.println("我會java基礎(chǔ)編程了...");
}
}
//class GYFStudent implements Person{
//
// private UniversityStudent uStu;
//
// public GYFStudent(UniversityStudent uStu) {
// super();
// this.uStu = uStu;
// }
//
//
// @Override
// public void coding() {
// // TODO Auto-generated method stub
// uStu.coding();
// System.out.println("我會java基礎(chǔ)編程了...");
// }
//}
InputStreamReader&OutputStreamWriter
這兩個類用于使用指定的碼表讀寫字符
FileReader是使用默認(rèn)碼表讀取文件, 如果需要使用指定碼表讀取請使用InputStreamReader(字符流,編碼表)
FileWriter是使用默認(rèn)碼表寫出文件, 如果需要使用指定碼表寫入請使用OutputStreamWriter(字符流,編碼表)
package lesson07;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class Demo01 {
public static void main(String[] args) throws IOException {
/* InputStreamReader&OutputStreamWriter
1>這兩個類用于使用指定的碼表讀寫字符*/
//案例1:使用指定 “碼表UTF-8&GBK” 讀取字符
/**
* charsetName:字符編碼的名稱
*/
FileInputStream fis = new FileInputStream("a.txt");
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
//讀一個字符
/* System.out.println((char)isr.read());
System.out.println((char)isr.read());*/
//讀一行
BufferedReader br = new BufferedReader(isr);
System.out.println(br.readLine());
br.close();
}
}
案例2:
package lesson07;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* 掌握:
* 1.當(dāng)讀取文件內(nèi)容令漂,還有寫入文件,可以指定編碼格式
* 2.使用InputStreamReader&OutputStreamWriter這個類
* @author gyf
*
*/
public class Demo02 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
/* OutputStreamWriter
1>使用指定的編碼 寫入文件
*/
//1.創(chuàng)建Writer
FileOutputStream fos = new FileOutputStream("c.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
BufferedWriter bw = new BufferedWriter(osw);
//2.寫
bw.write("你好丸边,IO流...搞的我有點暈...");
bw.newLine();
bw.write("你好叠必,IO流...搞的我有點暈...");
bw.newLine();
//3.關(guān)流
bw.close();
}
}
編碼轉(zhuǎn)換流圖解
練習(xí):獲取文本上字符出現(xiàn)的次數(shù)
package lesson08;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
/**
* 掌握:當(dāng)鍵盤敲 enter鍵,兩個字符\r\n : 回車換行
*
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
//練習(xí):獲取文本上字符出現(xiàn)的次數(shù),把數(shù)據(jù)寫入文件
/* 思路:
1.遍歷文本每一個字符
2.字符出現(xiàn)的次數(shù)存在Map中
*//**
* Map<Character,Integer> map = new HashMap<Character,Integer>();
* map.put('a',18);
* map.put('你',2);
*//*
3.把map中的數(shù)據(jù)寫入文件*/
//==================================
//1.創(chuàng)建Map集合
Map<Character,Integer> map = new HashMap<Character,Integer>();
//System.out.println(map.get('a'));
//2.遍歷每一個字符,每一個字符出現(xiàn)的次數(shù)放到map中
FileReader reader = new FileReader("a.txt");
int c = 0;
while((c = reader.read()) != -1){
//int 還原 char
char ch = (char)c;
// 判斷char是否在map中第一次出現(xiàn)
if(map.get(ch) == null){
map.put(ch, 1);
}else{
map.put(ch, map.get(ch) + 1);
}
}
//3.把map中數(shù)據(jù)存在文件count.txt
//3.1 創(chuàng)建Writer
BufferedWriter bw = new BufferedWriter(new FileWriter("count.txt"));
//3.2 遍歷map,再寫入數(shù)據(jù)
for(Entry<Character, Integer> entry :map.entrySet()){
switch (entry.getKey()) {
case ' ':
bw.write("空格=" + entry.getValue());
break;
case '\t'://\t表示tab 鍵字符
bw.write("tab鍵=" + entry.getValue());
break;
case '\r'://
bw.write("回車=" + entry.getValue());
break;
case '\n'://
bw.write("換行=" + entry.getValue());
break;
default:
bw.write(entry.getKey() + "=" + entry.getValue());
break;
}
bw.newLine();
}
//4.關(guān)流
reader.close();
bw.close();
}
}
遞歸(5妹窖!-5個乘階)
概述
- 遞歸做為一種算法,在程序設(shè)計語言中廣泛應(yīng)用纬朝。
遞歸:就方法內(nèi)部調(diào)用自己
- 遞歸的弊端:不能調(diào)用次數(shù)過多,容易導(dǎo)致棧內(nèi)存溢出
遞歸的好處:不用知道循環(huán)次數(shù)
構(gòu)造方法是否可以遞歸調(diào)用?
構(gòu)造方法不能使用遞歸調(diào)用遞歸調(diào)用是否必須有返回值?
不一定(可以有,也可以沒有)
package lesson09;
public class Demo01 {
public static void main(String[] args) {
//遞歸
/**
* 遞歸做為一種算法,在程序設(shè)計語言中廣泛應(yīng)用。
遞歸:就方法內(nèi)部調(diào)用自己
遞歸的弊端:不能調(diào)用次數(shù)過多,容易導(dǎo)致棧內(nèi)存溢出
遞歸的好處:不用知道循環(huán)次數(shù)
*/
//使用遞歸來寫乘階
int r = jiecheng(116);
System.out.println("r=" + r);
}
/**
* jiecheng(6) i = 6
* 6 * jecheng(5)
* 6 * 5 * jecheng(4)
* 6 * 5 * 4 * jecheng(3)
* 6 * 5 * 4 * 3 * jecheng(2)
* 6 * 5 * 4 * 3 * 2 * jecheng(1)
* 6 * 5 * 4 * 3 * 2 * 1
*/
public static int jiecheng(int i){
if(i==1){
return 1;
}else{
return i * jiecheng(i - 1);
}
}
/**
* 使用for循環(huán)寫階乘
*/
public static void test1() {
//5骄呼!-5的階乘共苛,5個乘階
//5*4*3*2*1
int r = 1;//結(jié)果
for(int i=1;i<=5;i++){
r = r * i;
/**
* i = 1 ; r = 1*1
* i = 2 ; r = 1* 1 * 2
* i = 3 ; r = 1* 1 * 2 * 3
* .....
*/
}
System.out.println("r=" + r);
}
}
遞歸:文件目錄
package lesson10;
import java.io.File;
/**
* 任務(wù):計算一個文件夾大小:累加文件的大小
* @author gyf
*
*/
public class Demo01 {
public static void main(String[] args) {
//遞歸:文件目錄
/**打印出a目錄所有文件名稱蜓萄,包括子文件夾的文件*/
//1.創(chuàng)建目錄對象
File dir = new File("C:/Users/10301/Desktop/a");
//2.打印目錄的子文件
printSubFile(dir);
}
public static void printSubFile(File dir){
//打印目錄的子文件
File[] subfiles = dir.listFiles();
for(File f : subfiles){
if(f.isDirectory()){//文件夾
printSubFile(f);
}else{//文件
System.out.println(f.getAbsolutePath());
}
}
}
}
練習(xí):從鍵盤輸入接收一個文件夾路徑,打印出該文件夾下所有的.jpg文件名
package lesson11;
import java.io.File;
import java.util.Scanner;
public class Demo02 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//練習(xí):從鍵盤輸入接收一個文件夾路徑,打印出該文件夾下所有的.jpg文件名
//1.獲取文件路徑
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入一個文件夾路徑...");
String path = scanner.nextLine();
//2.把路徑封裝成File對象
File file = new File(path);
if(!file.exists()){
System.out.println("此路徑對應(yīng)的文件不存在");
return;
}
if(!file.isDirectory()){
System.out.println("請輸入文件夾路徑隅茎,而不文件路徑");
return;
}
//3.遍歷文件夾下的子文件
printSubFile(file);
}
public static void printSubFile(File dir){
//打印目錄的子文件
File[] subfiles = dir.listFiles();
for(File f : subfiles){
if(f.isDirectory()){//文件夾
printSubFile(f);
}else{//文件
if(f.getName().endsWith(".jpg")){
System.out.println(f.getAbsolutePath());
}
}
}
}
}
SequenceInputStream 序列流
什么是序列流
序列流可以把多個字節(jié)輸入流整合成一個, 從序列流中讀取數(shù)據(jù)時, 將從被整合的第一個流開始讀, 讀完一個之后繼續(xù)讀第二個, 以此類推.
案例:使用字節(jié)流把兩個件數(shù)據(jù)寫到另一個文件
案例:使用序列流把兩個件數(shù)據(jù)寫到另一個文件
package lesson12;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
public class Demo01 {
public static void main(String[] args) throws IOException {
//SequenceInputStream 序列流
/**
* InputStream:輸入流
* Sequence:序列 連續(xù)
*
* 序列流可以把多個字節(jié)輸入流整合成一個, 從序列流中讀取數(shù)據(jù)時,
* 將從被整合的第一個流開始讀, 讀完一個之后繼續(xù)讀第二個, 以此類推.
*/
test2();
}
public static void test2() throws FileNotFoundException, IOException {
//需求:a.txt,b.txt 依次寫c.txt
//創(chuàng)建序列流
FileInputStream fis1 = new FileInputStream("a.txt");
FileInputStream fis2 = new FileInputStream("b.txt");
SequenceInputStream sis = new SequenceInputStream(fis1, fis2);
//創(chuàng)建輸出流
FileOutputStream fos = new FileOutputStream("c.txt");
//讀寫
int b = 0;
while((b = sis.read()) != -1){
fos.write(b);
}
fis2.close();
sis.close();
fos.close();
}
public static void test1() throws FileNotFoundException, IOException {
//需求:a.txt,b.txt 依次寫c.txt
//1.創(chuàng)建兩個輸入流
FileInputStream fis1 = new FileInputStream("a.txt");
FileInputStream fis2 = new FileInputStream("b.txt");
//2.創(chuàng)建一個輸出流
FileOutputStream fos = new FileOutputStream("c.txt");
//3.先把a文件的內(nèi)容寫到c.txt
int b = 0;
while((b=fis1.read()) != -1){
fos.write(b);
}
fos.write("\r\n".getBytes());//換行
//4.再把b文件內(nèi)容寫到c.txt
while((b=fis2.read()) != -1){
fos.write(b);
}
//5.關(guān)流
fis1.close();
fis2.close();
fos.close();
}
}
序列流整合多個字節(jié)流(了解)
package lesson13;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;
public class Demo01 {
public static void main(String[] args) throws Exception {
//SequenceInputStream序列流使用二
//需求,把a.txt b.txt c.txt 的內(nèi)容拷貝到d.txt
//1.Vector是集合
Vector<InputStream> vector = new Vector<InputStream>();
vector.add(new FileInputStream("a.txt"));
vector.add(new FileInputStream("b.txt"));
vector.add(new FileInputStream("c.txt"));
//2.Enumeration枚舉
Enumeration<InputStream> e = vector.elements();
//3.序列流
SequenceInputStream sis = new SequenceInputStream(e);
//4.創(chuàng)建輸出流
FileOutputStream fos = new FileOutputStream("d.txt");
//讀寫
int b = 0;
while((b = sis.read()) != -1){
fos.write(b);
}
sis.close();
fos.close();
}
}
ByteArrayOutputStream字節(jié)數(shù)組輸出流
此類實現(xiàn)了一個輸出流嫉沽,其中的數(shù)據(jù)被寫入一個 byte 數(shù)組辟犀。緩沖區(qū)會隨著數(shù)據(jù)的不斷寫入而自動增長〕袼叮可使用 toByteArray() 和 toString() 獲取數(shù)據(jù)堂竟。
package lesson01;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
//ByteArrayOutputStream 字節(jié)數(shù)組輸出流
/**
* 1.前面學(xué)習(xí)的流-必需關(guān)于一個文件
* FileOutputStream fos = new FileOutputStream("a.txt")
*
* 2.ByteArrayOutputStream 不需要關(guān)聯(lián)文件
*
* 3.此類實現(xiàn)了一個輸出流,其中的數(shù)據(jù)被寫入一個 byte 數(shù)組玻佩。
* 緩沖區(qū)會隨著數(shù)據(jù)的不斷寫入而自動增長出嘹。
* 可使用 toByteArray() 和 toString() 獲取數(shù)據(jù)。
*/
//1.創(chuàng)建字節(jié)數(shù)組輸出流對象
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//2.輸入流
FileInputStream fis = new FileInputStream("a.txt");
//3.寫入輸出流
int b = 0;
while((b = fis.read()) != -1){
baos.write(b);
}
//自動把字節(jié)數(shù)組 轉(zhuǎn)成 字符串
System.out.println(baos.toString());
System.out.println(baos.toString("UTF-8"));//指定編碼格式的字符串
//獲取文件數(shù)據(jù)
byte[] bytes = baos.toByteArray();
System.out.println(new String(bytes));
System.out.println(new String(bytes, "UTF-8"));//指定編碼格式的字符串
//4.關(guān)流
fis.close();
}
}
面試題:找bug
定義一個文件輸入流,調(diào)用read(byte[] b)方法,將a.txt文件中的內(nèi)容打印出來(byte數(shù)組大小限制為5)
package lesson02;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
/* 面試題:找bug
定義一個文件輸入流,調(diào)用read(byte[] b)方法,
將a.txt文件中的內(nèi)容打印出來(byte數(shù)組大小限制為5)*/
//1.文件輸入流
FileInputStream fis = new FileInputStream("a.txt");
//2.字節(jié)數(shù)組輸出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//3.字節(jié)數(shù)組【緩沖區(qū)思想咬崔,杯子思想】
byte[] arr = new byte[5];
int len;
while((len = fis.read(arr)) != -1) {
//通過字節(jié)緩沖數(shù)組寫入
baos.write(arr, 0, len);
//把字節(jié)轉(zhuǎn)成字符串
/**
* 中文亂碼問題
*/
System.out.println(new String(arr,0,len));
}
//內(nèi)部會調(diào)用toString方法,把字節(jié)數(shù)組轉(zhuǎn)成字符串
System.out.println(baos);
fis.close();
}
}
對象操作流ObjecOutputStream& ObjecInputStream (了解)
什么是對象操作流
該流可以將一個對象寫出, 或者讀取一個對象到程序中. 也就是執(zhí)行了序列化和反序列化的操作.
歸檔(序列化) :將對象存在一個文件
解歸檔=反序列化:把一個文件解析出對象
ObjecOutputStream對象輸出流疚漆,把一個對象存儲起來,存儲的對象必須實現(xiàn)Serializable接口
ObjecInputStream對象輸入流刁赦,把存的數(shù)據(jù)還原成一個對象
package lesson03;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Demo01 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// TODO Auto-generated method stub
//對象操作流ObjectOutputStream& ObjectInputStream
/**
* 一娶聘、ObjectOutputStream:將一個對象寫入文件
* 1.如果使用這個類寫入對象,這個對象需要序列化
* 2.序列化就是讓這個對象實現(xiàn)一個Serializable接口
* 3.如果沒實現(xiàn)Serializable接口甚脉,會拋異常NotSerializableException
* 二丸升、ObjectInputStream:從文件中讀一個對象
*/
//案例:從文件中取出女朋友對象
//1.創(chuàng)建一個對象輸入流
FileInputStream fis = new FileInputStream("gf.data");
ObjectInputStream ois = new ObjectInputStream(fis);
//2.讀數(shù)據(jù)
GirlFriend gf1 = (GirlFriend) ois.readObject();
System.out.println(gf1);
GirlFriend gf2 = (GirlFriend) ois.readObject();
System.out.println(gf2);
/**
* 如果沒有數(shù)據(jù)可讀了,強制讀的時候報錯了EOFException牺氨,
*/
System.out.println(ois.readObject());
}
public static void test1() throws FileNotFoundException, IOException {
//案例:將對象直接存入文件
//1.創(chuàng)建女朋友對象
GirlFriend gf1 = new GirlFriend("林志玲", 1.78);
GirlFriend gf2 = new GirlFriend("林心如", 1.68);
//2.創(chuàng)建對象輸出流
FileOutputStream fos = new FileOutputStream("gf.data");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//3.往文件存入對象
oos.writeObject(gf1);
oos.writeObject(gf2);
//4.關(guān)流
oos.close();
}
}
class GirlFriend implements Serializable{
String name;
double height;
public GirlFriend(String name, double height) {
super();
this.name = name;
this.height = height;
}
@Override
public String toString() {
return "GirlFriend [name=" + name + ", height=" + height + "]";
}
}
對象操作流優(yōu)化
為了方便讀取多個對象
建立把將對象存儲在集合中狡耻,然后將集合對象存入取出
package lesson05;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class Demo01 {
public static void main(String[] args) throws IOException, IOException {
//對象操作流優(yōu)化-思路墩剖,存多個對象時,把對象存在list里面
//把女朋友對象存在List中夷狰,再把List寫入文件【序列化/歸檔】
//1.創(chuàng)建集合
List<GirlFriend> list = new ArrayList<GirlFriend>();
//2.添加女朋友
list.add(new GirlFriend("林志玲", 1.78));
list.add(new GirlFriend("林心如", 1.68));
list.add(new GirlFriend("林嘉欣", 1.58));
//3.把list存入文件
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list.data"));
oos.writeObject(list);
//4.關(guān)流
oos.close();
}
}
class GirlFriend implements Serializable{
String name;
double height;
public GirlFriend(String name, double height) {
super();
this.name = name;
this.height = height;
}
@Override
public String toString() {
return "GirlFriend [name=" + name + ", height=" + height + "]";
}
}
package lesson05;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.util.List;
public class Demo02 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// TODO Auto-generated method stub
//案例:從list.data 讀取所有的女朋友對象【反序列化岭皂、解歸檔】
//1.創(chuàng)建對象輸入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("list.data"));
//2.讀取List對象
Object obj = ois.readObject();
//把obj轉(zhuǎn)list
@SuppressWarnings("unchecked")
List<GirlFriend> list = (List<GirlFriend>)obj;
System.out.println(obj.getClass());
//遍歷
for(GirlFriend gf : list){
System.out.println(gf);
}
ois.close();
}
}
Serializable接口的ID
要歸檔或者序列化的對象必須實現(xiàn)Serializable接口才能被序列化
Serializable 中有個id,但I(xiàn)D不是一定有加的
SerialVersionUid沼头,簡言之爷绘,其目的是序列化對象版本控制,有關(guān)各版本反序列化時是否兼容进倍。
如果在新版本中這個值修改了土至,新版本就不兼容舊版本,反序列化時會拋出InvalidClassException異常猾昆。
如果修改較小陶因,比如僅僅是增加了一個屬性,我們希望向下兼容垂蜗,老版本的數(shù)據(jù)都能保留楷扬,那就不用修改;
如果我們刪除了一個屬性贴见,或者更改了類的繼承關(guān)系毅否,必然不兼容舊數(shù)據(jù),這時就應(yīng)該手動更新版本號蝇刀,即SerialVersionUid螟加。
package lesson06;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Demo01 {
public static void main(String[] args) throws IOException, ClassNotFoundException{
// TODO Auto-generated method stub
/* Serializable接口的ID
1.要歸檔或者序列化的對象必須實現(xiàn)Serializable接口才能被序列化
2.Serializable 中有個id,但I(xiàn)D不是一定要加的
3.SerialVersionUid吞琐,簡言之捆探,其目的是以序列化對象進(jìn)行版本控制,有關(guān)各版本
反序列化時是否兼容站粟。
4.如果在新版本中這個值修改了黍图,新版本就不兼容舊版本,反序列化時會拋出InvalidClassException異常奴烙。
5.如果修改較小助被,比如僅僅是增加了一個屬性,我們希望向下兼容切诀,老版本
的數(shù)據(jù)都能保留揩环,那就不用修改;
6.如果我們刪除了一個屬性幅虑,或者更改了類的繼承關(guān)系丰滑,必然不兼容舊數(shù)據(jù),
這時就應(yīng)該手動更新版本號倒庵,即SerialVersionUid褒墨。
7.一般不會添加ID,就算添加了ID,版本號最好不要修改
*/
//save();
//取學(xué)生
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("stu.data"));
Student stu = (Student) ois.readObject();
System.out.println(stu);
}
public static void save() throws IOException, FileNotFoundException {
//1.創(chuàng)建學(xué)生對象
Student stu = new Student("霍建華");
//2.把學(xué)生存入文件
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("stu.data"));
/**
* 存的學(xué)生的版本號是1
*/
oos.writeObject(stu);
//3.關(guān)流
oos.close();
}
}
class Student implements Serializable{
/**
* 序列化版本ID
*/
private static final long serialVersionUID = 1L;
private String name;
private String hometown;
public Student(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "Student [name=" + name + "]";
}
}
打印流的概述和特點 (掌握)
**什么是打印流 **
該流可以很方便的將對象的toString()結(jié)果輸出, 并且自動加上換行, 而且可以使用自動刷出的模式
System.out就是一個PrintStream, 其默認(rèn)向控制臺輸出信息
PrintStream和PrintWriter分別是打印的字節(jié)流和字符流
package lesson07;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
public class Demo01 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//打印流的概述和特點 (掌握)
/* 什么是打印流
1.該流可以很方便的將對象的toString()結(jié)果輸出, 并且自動加上換行, 而且可以使用自動刷出的模式
2.System.out就是一個PrintStream, 其默認(rèn)向控制臺輸出信息
3.PrintStream和PrintWriter分別是打印的字節(jié)流和字符流*/
//1.打印的字節(jié)流【打印到控制臺】
PrintStream ps = System.out;
ps.println("你好炫刷,元宵節(jié)快樂");//打印字符串
ps.println(19.6);
//2.打印的字符流
/**
* 1.PrintWriter調(diào)用打印方法,控制臺是沒有內(nèi)容郁妈,它是把內(nèi)容寫到文件中
* 2.如果打印了內(nèi)容浑玛,沒有調(diào)用flush或者close,內(nèi)容在文件中也不存在
*/
PrintWriter pw = new PrintWriter("test.txt");
pw.println("吃湯圓了...");
pw.print("超市一包湯圓10幾塊錢");
pw.print(13.01);
//pw.flush();
pw.close();
}
}
標(biāo)準(zhǔn)輸入輸出流概述和輸出語句(了解)
System.in是InputStream, 標(biāo)準(zhǔn)輸入流, 默認(rèn)可以從鍵盤輸入讀取字節(jié)數(shù)據(jù)
System.out是PrintStream, 標(biāo)準(zhǔn)輸出流, 默認(rèn)可以向Console中輸出字符和字節(jié)數(shù)據(jù)
package lesson08;
import java.io.InputStream;
import java.io.PrintStream;
public class Demo01 {
public static void main(String[] args) {
//標(biāo)準(zhǔn)輸入輸出流概述和輸出語句(了解)
/* System.in是InputStream, 標(biāo)準(zhǔn)輸入流, 默認(rèn)可以從鍵盤輸入讀取字節(jié)數(shù)據(jù)
System.out是PrintStream, 標(biāo)準(zhǔn)輸出流, 默認(rèn)可以向Console中輸出字符和字節(jié)數(shù)據(jù)*/
InputStream is = System.in;//標(biāo)準(zhǔn)輸入流
PrintStream ps = System.out;//標(biāo)準(zhǔn)輸出流
}
}
隨機訪問流概述和讀寫數(shù)據(jù)
**隨機訪問流概述 **
RandomAccessFile概述
RandomAccessFile類不屬于流噩咪,是Object類的子類顾彰。但它融合了InputStream和OutputStream的功能。
支持對隨機訪問文件的讀取和寫入剧腻。
package lesson09;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* RandomAccessFile這個類用于文件斷點下載
* @author gyf
*
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
//隨機訪問流概述和讀寫數(shù)據(jù)
/* 隨機訪問流概述
RandomAccessFile概述
RandomAccessFile類不屬于流,是Object類的子類涂屁。但它融合了InputStream和OutputStream的功能书在。
支持對隨機訪問文件的讀取和寫入。*/
/**
* 構(gòu)造方法兩個參數(shù):
* name:文件名稱拆又、路徑
* mode:模式 儒旬,r=read 只讀、 w=write
*/
//1.創(chuàng)建一個隨機訪問流對象帖族,以讀寫的方式打開文件
RandomAccessFile raf = new RandomAccessFile("a.txt", "rw");
//2.讀字符
/**
* 使用RandomAccessFile的readChar/readLine方法讀文件有亂碼問題
*/
/* System.out.println(raf.readChar());
System.out.println(raf.readChar());
System.out.println(raf.readChar());
System.out.println(raf.readLine());*/
//使用字節(jié)數(shù)組來讀比較好
/* byte[] buf = new byte[1024];
int len;
while((len = raf.read(buf)) != -1){
System.out.println(new String(buf,0,len));
}*/
//3.寫數(shù)據(jù)
//raf.writeChars("abc");
//raf.writeBytes("abc");
raf.seek(4);//指定位置
raf.write(97);
raf.write(98);
raf.write(99);
}
}
DataOutputStream&DataInputStream
什么是數(shù)據(jù)輸入輸出流
DataInputStream, DataOutputStream可以按照基本數(shù)據(jù)類型大小讀寫數(shù)據(jù)
例如:
按Long大小寫出一個數(shù)字, 寫出時該數(shù)據(jù)占8字節(jié). 讀取的時候也可以按照Long類型讀取, 一次讀取8個字節(jié).
package lesson10;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//DataOutputStream&DataInputStream 數(shù)據(jù)輸入輸出流
/* DataInputStream, DataOutputStream可以按照基本數(shù)據(jù)類型大小讀寫數(shù)據(jù)
例如按Long大小寫出一個數(shù)字, 寫出時該數(shù)據(jù)占8字節(jié).
讀取的時候也可以按照Long類型讀取, 一次讀取8個字節(jié).*/
//讀3個long數(shù)據(jù)
DataInputStream dis = new DataInputStream(new FileInputStream("a.txt"));
System.out.println(dis.readLong());//讀8個字節(jié)
System.out.println(dis.readLong());//讀8個字節(jié)
System.out.println(dis.readLong());//讀8個字節(jié)
}
public static void test1() throws FileNotFoundException, IOException {
long a = 997;
long b = 998;
long c = 999;
//使用FileOutputStream沒法寫入long類型數(shù)據(jù)
FileOutputStream fos = new FileOutputStream("a.txt");
//byte -128~127 0~255
/* fos.write(997);只會寫一個字節(jié)栈源,不會寫4個字節(jié)
fos.write(998);
fos.write(999);*/
//fos.wr
DataOutputStream dos = new DataOutputStream(fos);
dos.writeLong(a);//寫4個字節(jié)
dos.writeLong(b);
dos.writeLong(c);
dos.close();
}
}
Properties的概述和作為Map集合的使用
Properties的概述
Properties 類表示了一個持久的屬性集。
Properties 可保存在流中或從流中加載竖般。
屬性列表中每個鍵及其對應(yīng)值都是一個字符串甚垦。
方法
Properties的load()和store()
public Object setProperty(String key,String value)
public String getProperty(String key)
public Enumeration<String> stringPropertyNames()
package lesson11;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.Period;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
public class Demo01 {
public static void main(String[] args) throws IOException, IOException {
//Properties的概述和作為Map集合的使用【掌握-經(jīng)常用】
/**
* Properties:屬性
1.Properties 類表示了一個持久的屬性集。
2.Properties 可保存在流中或從流中加載涣雕。
3.屬性列表中每個鍵及其對應(yīng)值都是一個字符串艰亮。
*/
//遍歷properties所有屬性key和值value
//1.創(chuàng)建屬性對象
Properties p = new Properties();
//2.關(guān)聯(lián)文件
p.load(new FileInputStream("info.properties"));
//3.遍歷一
Set<Object> keys = p.keySet();
for(Object key : keys){
System.out.println(key + "=" + p.get(key));
}
//System.out.println(keys);
//4.遍歷二
System.out.println("=====================");
//p.entrySet();
for(Entry<Object, Object> entry :p.entrySet()){
System.out.println(entry.getKey() + "=" + entry.getValue());
}
}
public static void test2() throws IOException, FileNotFoundException {
//使用Properties讀取數(shù)據(jù)
//1.創(chuàng)建屬性對象
Properties p = new Properties();
//2.關(guān)聯(lián)文件
p.load(new FileInputStream("info.properties"));
//3.通過key讀數(shù)據(jù)
String name = p.getProperty("name");
String city = p.getProperty("city");
String hometown = p.getProperty("hometown");
System.out.println(name);
System.out.println(city);
System.out.println(hometown);
}
/**
* 使用Properties來存儲數(shù)據(jù)
*/
public static void test1() throws IOException, FileNotFoundException {
//1.創(chuàng)建屬性對象
Properties p = new Properties();
//2.存數(shù)據(jù)
p.setProperty("name", "gyf");
p.setProperty("city", "廣州");
p.setProperty("hometown", "梅州");
//3.關(guān)聯(lián)文件
/**
* 當(dāng)Properties把key和value存入文件,把中文轉(zhuǎn)成unicode編碼
*/
p.store(new FileOutputStream("info.properties"), null);
}
}
捋一捋IO流
package lesson12;
public class Demo01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//捋一捋IO流
/**
* 一挣郭、IO流-輸入輸出流
* I:input
* O:out
* IO流 操作文件迄埃,讀取文件內(nèi)容,往文件寫內(nèi)容
*
* 二兑障、字節(jié)流
*
* >InputStream
* -FileInputStream 文件輸入流侄非,讀的單位是字節(jié)
* -BufferedInputStream 緩沖輸入流,內(nèi)部有個byte[]字節(jié)數(shù)組
* -SequenceInputStream 序列流流译,把多個字節(jié)流整合成一個流
* -ObjectInputStream 對象輸入流逞怨,直接從文件中讀取一個對象,這個對象要實現(xiàn)serilazable接口
* -Sytem.in 標(biāo)準(zhǔn)輸入流-指鍵盤
* -DataInputStream 數(shù)據(jù)輸入流,按基本數(shù)據(jù)類型的大小(long) 讀取文件
*
* >OutputStream
* -FileOutputStream 文件輸出流福澡,寫的單位是字節(jié)
* -BufferedOutputStream 緩沖輸出流骇钦,內(nèi)部有個byte[]字節(jié)數(shù)組
* -ByteArrayOutputStream 字節(jié)數(shù)組輸出流,把數(shù)據(jù)讀取到內(nèi)存中竞漾,這個類不需要關(guān)聯(lián)文件
* -ObjectOutputStream 對象輸出流眯搭,直接把一個對象存入文件窥翩,
* -PrintStream 打印流,把內(nèi)容打印到控制臺
* -System.out 標(biāo)準(zhǔn)輸出流-指控制臺
* -DataOutputStream 數(shù)據(jù)輸出流鳞仙,按基本數(shù)據(jù)類型的大小(long) 寫入文件
*
* 三寇蚊、字符流
* >Reader
* -FileReader 文件讀取流,讀取的單位是字符
* -BufferedReader 緩沖讀取流棍好,內(nèi)部有個char[] 字符數(shù)組
* -InputStreamReader 指定字符編碼讀取文件
*
* >Writer
* -FileWriter 文件寫入流,寫入的單位是字符
* -BufferedWriter,緩沖寫入流仗岸,內(nèi)部有個char[] 字符數(shù)組
* -OutputStreamWriter 指定字符編碼寫入文件
* -PrintWriter 打印流,把內(nèi)容打印一個文件
*
*
* RandomAccessFile 隨機訪問流借笙,特點:讀和寫都在一個類中
*
* Properties 相當(dāng)于Map一樣使用扒怖,這個類把數(shù)據(jù)存在一個后綴名為.properties文件
*/
}
}