國內(nèi)專業(yè)網(wǎng)站建設(shè)公司希愛力雙效片用后感受
目錄
文件類型
File概述
屬性
構(gòu)造方法
常用方法
Reader
Writer
InputStream
OutputStream
字節(jié)流轉(zhuǎn)字符流?
通過Scanner讀取InputStream
通過PrintWriter轉(zhuǎn)換outputstream
示例?
文件類型
從編程的角度看,文件類型主要就是兩大類
- 文本(文件中保存的數(shù)據(jù),都是字符串,保存的內(nèi)容都是合法的字符)
- 二進(jìn)制(文件中保存的數(shù)據(jù),僅僅是二進(jìn)制數(shù)據(jù),不要求保存的內(nèi)容是合法的字符)
File概述
屬性
修飾符及類型 | 屬性 | 說明 |
---|---|---|
static String | pathSeparator | 依賴于系統(tǒng)的路徑分隔符,String類型表示 |
static char | pathSeparator | 依賴于系統(tǒng)的路徑分隔符,char類型表示 |
?D:\
如上所示,“\”就是一個(gè)路徑分隔符?
構(gòu)造方法
簽名 | 說明 |
File(File parent,String child) | 根據(jù)父目錄+孩子文件路徑,創(chuàng)建一個(gè)新的File實(shí)例 |
File(String pathname) | 根據(jù)文件路徑創(chuàng)建你一個(gè)新的File實(shí)例,路徑可以是絕對路徑或者相對路徑 |
File(String parent,String chile) | 根據(jù)父目錄+孩子我呢見路徑,創(chuàng)建一個(gè)新的File實(shí)例,父目錄用路徑表示 |
常用方法
修飾符及返回類型 | 方法簽名 | 說明 |
---|---|---|
String | getParent() | 返回File對象的父目錄文件路徑 |
String | getName() | 返回File對象的純文本名稱 |
String???????? | getPath() | 返回File對象的文件路徑 |
String | getAbsolutePath() | 返回File對象的絕對路徑 |
String | getCanonicalPath() | 返回File對象修飾過的絕對路徑 |
boolean | exists() | 判斷File對象描述的文件是否真實(shí)存在 |
boolean | isDirectory() | 判斷File對象代表的文件是否是一個(gè)目錄 |
boolean | isFile() | 判斷File對象代表的文件是否是一個(gè)普通文件 |
boolean | createNewFile() | 根據(jù)File對象,自動(dòng)創(chuàng)建一個(gè)空文件,成功創(chuàng)建返回true |
boolean | delete() | 根據(jù)File對象,刪除該文件 |
void | deleteOnExit() | 根據(jù)File對象,標(biāo)注文件將被刪除,刪除動(dòng)作會(huì)到JVM運(yùn)行結(jié)束時(shí)才刪除 |
String[] | list() | 返回File對象代表的目錄下所有文件名 |
File[] | listFiles() | 返回File對象代表的目錄下的所有文件,以File對象表示 |
boolean | mkdir() | 創(chuàng)建File對象代表的目錄 |
boolean | mkdirs() | 創(chuàng)建File對象代表的目錄,如果必要,會(huì)創(chuàng)建中間目錄 |
boolean | renameTo(File dest) | 進(jìn)行文件改名,也可以視為平時(shí)的剪切、粘貼操作 |
boolean | canRead() | 判斷用戶是否對文件有可讀權(quán)限 |
boolean | canWrite() | 判斷用戶是否對文件有可寫權(quán)限 |
在標(biāo)準(zhǔn)庫中,提供的讀寫文件的流對象,有很多個(gè)類,可以歸結(jié)為兩個(gè)大的類別中:
1、字節(jié)流(對應(yīng)著二進(jìn)制文件),每次讀/寫的最小單位,都是“字節(jié)”
- InputStream
- OutputStream
2、字符流(對應(yīng)著文本文件) ,每次讀/寫的最小單位,是“字符”,一個(gè)字符可能對應(yīng)多個(gè)字節(jié),跟當(dāng)前字符集編碼方式有關(guān),本質(zhì)上,是針對字節(jié)流進(jìn)行了又一層封裝
- Reader
- Writer
上述四種是抽象類,不能直接new實(shí)例
- 無參數(shù)read:一次讀取一個(gè)字符
- 一個(gè)參數(shù)read:一次讀取若干個(gè)字符,會(huì)把參數(shù)指定的buf數(shù)組給填充滿
- 三個(gè)參數(shù)read:一次讀取若干個(gè)字符,會(huì)把參數(shù)執(zhí)行的cbuf數(shù)組中,從off這個(gè)位置開始,到len這么長的范圍盡量填滿
使用示例:
Reader
一次read一個(gè)字符
try(Reader reader = new FileReader("D:/data.txt");){
??? while (true) {
??????? int c = reader.read();
??????? if (c == -1) {
??????????? //讀取完畢
??????????? break;
??????? }
??????? char ch = (char) c;
??????? System.out.println(ch);
??? }?????
} catch (IOException e) {
??? throw new RuntimeException(e);
}
read方法一次讀取一個(gè)字符,返回?cái)?shù)字,當(dāng)返回值為-1時(shí),代表讀取到文件末尾
一次read多個(gè)字符
Reader reader=new FileReader("D:/data.txt");
try{
??? while(true){
??????? char[] ch=new char[1024];
??????? int n= reader.read(ch);
??????? if(n==-1)
??????? {
??????????? //讀取完畢
??????????? break;
??????? }
??????? System.out.println("讀取長度:"+n);
??????? System.out.println(Arrays.toString(ch));
??? }
} catch (IOException e) {
??? throw new RuntimeException(e);
} finally {
??? try {
??????? reader.close();
??? } catch (IOException e) {
??????? throw new RuntimeException(e);
??? }
}
這樣寫雖然能夠解決中途拋異常,導(dǎo)致reader不能正常釋放,但是不夠優(yōu)雅,我們可以采取try with resources方法?,Reader reader=new FileReader("D:/data.txt")在出了作用域后,會(huì)自動(dòng)調(diào)用close方法
try(Reader reader=new FileReader("D:/data.txt")){
??? while(true){
??????? char[] ch=new char[1024];
??????? int n= reader.read(ch);
??????? if(n==-1)
??????? {
??????????? //讀取完畢
??????????? break;
??????? }
??????? System.out.println("讀取長度:"+n);
??????? System.out.println(Arrays.toString(ch));
??? }
} catch (IOException e) {
??? throw new RuntimeException(e);
}?
Writer
try(Writer writer=new FileWriter("D:/data.txt"))
{
??? writer.write("你好你好");
} catch (IOException e) {
??? throw new RuntimeException(e);
}
Writer寫入文件,默認(rèn)情況下,會(huì)將原來的數(shù)據(jù)清空掉,如果不想清空,需要在構(gòu)造函數(shù)中再傳入一個(gè)參數(shù)?,這樣就能實(shí)現(xiàn)追加寫
Writer writer=new FileWriter("D:/data.txt",true)
utf8編碼,一個(gè)中文字符是3個(gè)字節(jié),在Java標(biāo)準(zhǔn)庫內(nèi)部:
- 如果是只使用char,此時(shí)使用的字符集,固定就是unicode;
- 如果是使用String,此時(shí)就會(huì)自動(dòng)的把每個(gè)字符的unicode轉(zhuǎn)換utf8
InputStream
字節(jié)流與字符流不同的是,傳入的數(shù)組是byte類型的,read返回值是int,其實(shí)是byte,0-255之間的值,-1表示到達(dá)文件末尾
try(InputStream inputStream=new FileInputStream("D:/data.txt"))
{
??? byte[] buffer=new byte[1024];
??? int n=inputStream.read(buffer);
??? System.out.println("n = "+n);
??? for(int i=0;i<n;i++)
??? {
??????? System.out.printf("%x\n",buffer[i]);
??? }
} catch (IOException e) {
??? throw new RuntimeException(e);
}
OutputStream
OutputStream和Writer類似,打開一個(gè)文件,默認(rèn)就會(huì)清空文件的原有內(nèi)容
try(OutputStream outputStream=new FileOutputStream("d:/data.txt"))
{
??? String str="你好";
??? outputStream.write(str.getBytes());
} catch (IOException e) {
??? throw new RuntimeException(e);
}
若要使用追加的方式寫入,可以在構(gòu)造方法的第二個(gè)參數(shù)中傳入true
OutputStream outputStream=new FileOutputStream("d:/data.txt",true)
字節(jié)流轉(zhuǎn)字符流?
當(dāng)提供的是字節(jié)流對象,但實(shí)際數(shù)據(jù)內(nèi)容是文本數(shù)據(jù),我們可以將字節(jié)流轉(zhuǎn)換成字符流
通過Scanner讀取InputStream
try(InputStream inputStream=new FileInputStream("d:/data.txt"))
{
??? Scanner scanner=new Scanner(inputStream);
??? String str=scanner.next();
??? System.out.println(str);
} catch (IOException e) {
??? throw new RuntimeException(e);
}
通過PrintWriter轉(zhuǎn)換outputstream
try(OutputStream outputStream=new FileOutputStream("d:/data.txt"))
{
??? PrintWriter writer=new PrintWriter(outputStream);
??? writer.println("hello");
} catch (IOException e) {
??? throw new RuntimeException(e);
}
PrintWriter這樣的類,在進(jìn)行寫入的時(shí)候,不一定是直接寫硬盤,而是先把數(shù)據(jù)寫入到一個(gè)內(nèi)存構(gòu)成的緩沖區(qū)中,當(dāng)我們寫入緩沖區(qū)之后,如果還沒來得及把緩沖區(qū)的數(shù)據(jù)寫入硬盤中,進(jìn)程就結(jié)束了,此時(shí)數(shù)據(jù)就丟失了,為了能夠確保數(shù)據(jù)確實(shí)被寫入硬盤,就應(yīng)該在合適的時(shí)機(jī),使用flush方法手動(dòng)刷新緩沖區(qū),因此上述的代碼需要修改一下:
try(OutputStream outputStream=new FileOutputStream("d:/data.txt"))
{
??? PrintWriter writer=new PrintWriter(outputStream);
??? writer.println("hello");
??? writer.flush();
} catch (IOException e) {
??? throw new RuntimeException(e);
}
示例?
掃描指定目錄,并找到名稱中包含指定字符的所有普通文件(不包括目錄),并且后續(xù)詢問用戶是否要?jiǎng)h除該文件
public static void main(String[] args) throws FileNotFoundException {Scanner scanner = new Scanner(System.in);System.out.println("請輸入搜索路徑:");String direcory = scanner.next();File sourceFile = new File(direcory);if (!sourceFile.isDirectory()) {System.out.println("搜索路徑有誤!");return;}System.out.println("請輸入要?jiǎng)h除文件的關(guān)鍵詞:");String word=scanner.next();scanDir(sourceFile,word);}public static void scanDir(File rootPath, String word){File[] files = rootPath.listFiles();if(files==null)return;for (File file : files) {System.out.println("當(dāng)前掃描的文件: " + file.getAbsolutePath());if (file.isFile()) {checkDelete(file,word);} else {scanDir(file,word);}}}public static void checkDelete(File rootPath, String word){if(!rootPath.getName().contains(word)){//不必刪除,直接方法結(jié)束return ;}//需要?jiǎng)h除Scanner scanner = new Scanner(System.in);System.out.println("是否需要?jiǎng)h除(Y/N):");String choice=scanner.next();if(choice.equals("Y")||choice.equals("N")){rootPath.delete();System.out.println("刪除完畢!");}}