1. 程式人生 > >java(十)IO流

java(十)IO流

java io流

例: 關於鍵盤錄入

package day22;

import java.io.IOException;

import java.io.InputStream;


public class ReadKey {

/**

* 關於鍵盤錄入。

*/

public static void main(String[] args) throws IOException {

//readKey();

readKey2();

}


public static void readKey() throws IOException {

/*

* 需求:讀取一個鍵盤錄入的數據,並打印出來。

* 鍵盤本身就是一個標準的輸入設備,java對於這種輸入設備都有對應的對象。

*/

InputStream in=System.in;

int ch=in.read(); //阻塞式方法。

System.out.println(ch); //這個流不需要關閉,關了就再也啟動不了了。

//默認輸入流和輸出流不需要關閉。

}

private static void readKey2() throws IOException {

/*

* 獲取用戶鍵盤錄入的數據並變成大寫輸出。

* 如果用戶輸入over,結束鍵盤錄入。

*

* 思路:

* 1.因為鍵盤錄入只讀取一個字節,要判斷是否是over,要先將讀到的字節拼成字符串。

* 2.那就需要一個容器。StringBuilder比較合適。

* 3.在用戶回車之前將錄入的數據變成字符串判斷即可。

*/

//1.創建容器

StringBuilder sb=new StringBuilder();

//2.獲取鍵盤讀取流

InputStream in=System.in;

//3.定義變量記錄讀取到的字節,並循環獲取。

int ch=0;

while((ch=in.read())!=-1){

//在存儲之前判斷是否是換行標記,因為換行標記不存儲。

if(ch==‘\r‘)

continue;

if(ch==‘\n‘){

String temp=sb.toString();

if("over".equals(temp))

break;

System.out.println(temp.toUpperCase());

sb.delete(0, sb.length()); //這句是清空,否則就會把上一次的數據和這一次的數據一塊輸出。

}

//將讀取到的字節存儲到StringBuilder中。

else

sb.append((char)ch);

}

}

}






上面代碼一個一個讀,然後自己還要考慮換行啥的太麻煩了,就想到了readline()方法,

可是那是字符流的方法,怎麽辦呢?

這就用到了字符流和字節流之間的轉換。


package day22;

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;


public class TransStreamDemo {


/** 對ReadKey中readKey2()方法的簡化。

* 轉換流:InputStreamReader,字節流轉向字符流的橋梁。

* 相反,OutputStreamWriter,是字符流轉向字節流的橋梁。

* @throws IOException

*/

public static void main(String[] args) throws IOException {

/*

InputStream in=System.in;

InputStreamReader isr=new InputStreamReader(in);

BufferedReader bufr=new BufferedReader(isr);

String line=null;

while((line=bufr.readLine())!=null){

if("over".equals(line))

break;

System.out.println(line.toUpperCase());

}

*/

//這句話一定牢記,以後一提到鍵盤錄入就寫這句話。其實就是上面註釋了的代碼的前三句。

BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));

BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));

String line=null;

while((line=bufr.readLine())!=null){

if("over".equals(line))

break;

bufw.write(line.toUpperCase());

bufw.newLine();

bufw.flush();

}

/* 思考

* 1.需求:將鍵盤錄入的數據寫入到一個文件中。

* 還是上面的代碼,只將System.out換成文件地址即可。

* 2.需求:將一個文本文件內容顯示在控制臺上。

* 同理,還是上面的代碼,只將System.in換成文件地址就行。

* 3.需求:講一個文件的內容復制到另一個文件中。

* 把上面的System.out和System.in都換成文件地址就行。

*/

}

}


轉換流:

InputStreamReader,字節流轉向字符流的橋梁。解碼

OutputStreamWriter,是字符流轉向字節流的橋梁。編碼

流的操作規律:

之所以要弄清楚這個規律,是因為流對象太多,開發時不知道到底要用那個對象合適。

想要知道開發時用到那些對象,只要通過四個明確即可。

1.明確源和目的(匯)

源:InputStream Reader

目的:OutputStream Writer

2.明確數據是否是純文本數據。

源:是:Reader 否:InputStream

目的:是:Writer 否:OutputStream

3.明確具體的設備。

硬盤:File

鍵盤:System.in 控制臺:System.out

內存:數組

網絡:Socket流

4.明確是否需要其他額外功能。

高效(緩沖區) 轉換

需求1:復制一個文本文件。

步驟:1.明確源和目的。 都有

2.明確數據是否是純文本數據。是

3.明確具體的設備。硬盤

FileReader fr=new FileReader("demo.txt");

FileWriter fw=new FileWriter("demo.txt");

4.明確是否需要其他額外功能。NO

需求2:讀取鍵盤錄入信息,並寫入到一個文件中。

步驟:1.明確源和目的。 都有

2.明確數據是否是純文本數據。是

3.明確具體的設備。源:鍵盤 目的:硬盤

InputStream in=System.in;

FileWriter fw=new FileWriter("demo.txt");

這樣可以完成,但是麻煩。將讀取的字節數據轉換成字符串,再由字符流操作。

4.明確是否需要其他額外功能。

是,轉換,字節流轉成字符流。因為已經明確的源是reader,這樣操作文本數據更便捷。

InputStreamReader isr=new InputStreamReader(System.in);

FileWriter fw=new FileWriter("demo.txt");

還要功能嗎? 要 ,高效

BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));

FileWriter fw=new BufferedWriter(FileWriter("demo.txt"));

需求3:將文本文件數據顯示在控制臺上。

BufferedReader bufr=new BufferedReader(new FileReader("demo.txt"));

BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));

需求4:將鍵盤錄入的數據顯示在控制臺上

BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));

BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));

需求5:將一個中文字符串數據"你好"按照指定的編碼表"UTF-8"寫入到一個文本文件中。

這題的重點在指定的編碼表上。中文Windows的默認編碼表是gbk。

需求中已經明確了編碼表,所以就不能用FileWriter,因為它內部是使用默認的本地編碼表。

只能使用其父類OutputStreamWriter。OutputStreamWriter接受一個字節輸出流對象,既然是 操作文件,那麽該對象應該是FileOutputStream。



package day22;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.FileWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;


public class TransStreamDemo2 {


/**

* 轉換流的第二個功能:可以使用指定的編碼表編碼。FileWriter只能用默認編碼表。

* @throws IOException

*/

public static void main(String[] args) throws IOException {

writeText_3();

readText(); //讀也得用指定編碼表解碼,要不就是亂碼。

}


public static void readText() throws IOException {

InputStreamReader isr=new InputStreamReader(new FileInputStream("u8_1.txt"),"UTF-8");

char[] buf=new char[10];

int len=isr.read(buf);

String str=new String(buf,0,len);

System.out.println(str);

isr.close();

}


public static void writeText_3() throws IOException{

OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("u8_1.txt"),"UTF-8");

osw.write("你好");

osw.close();

//在屬性裏可以發現前面兩個文件都是4個字節,而這個是6個字節。因為UTF-8編碼表中一個漢字3個字節。

}


public static void writeText_2() throws IOException {

OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("gbk_2.txt"),"GBK");

//FileWriter fw=new FileWriter("gbk_1.txt");

/*

* 這兩句代碼的功能是相同的。

* FileWriter:其實就是轉換流指定了本機默認碼表的體現。而且這個轉換流的子類對象,可以方便操作文本文件。

* 簡單說,操作文件的字節流+本機的默認碼表。這是按照默認碼表操作文件的便捷類。

* 如果操作文件需要明確具體的編碼表,FileWriter就不行了,必須用轉換流。

*/

osw.write("你好");

osw.close();

}


public static void writeText() throws IOException {

FileWriter fw=new FileWriter("gbk_1.txt");

fw.write("你好");

fw.close();

}

}



什麽時候使用轉換流呢?、

1.源或者目的對應的設備是字節流,但是操作的卻是文本數據,可以使用轉換作為橋梁,提高對文本的操作便捷。

2.一旦操作文本涉及到具體的指定編碼表時,必須用轉換流。




File類

用來將文件或者文件夾封裝成對象。方便對文件與文件夾的屬性信息進行操作。

File對象可以作為參數傳遞給流的構造函數。


package day22;

import java.io.File;

import java.io.IOException;

import java.text.DateFormat;

import java.util.Date;


public class FileDemo {


/**

* @param args

* @throws IOException

*/

public static void main(String[] args) throws IOException {

ConstructorDemo();

}


public static void ConstructorDemo() throws IOException {

//可以將一個已存在的,或者不存在的文件或者目錄封裝成File對象。

File file=new File("E:\\demo.txt");

File file2=new File("E:\\","demo.txt");

File file3=new File("E:"+File.separator+"demo.txt");

System.out.println(file3);

fileMethodDemo();

}


public static void fileMethodDemo() throws IOException {

/*

* File對象的常見方法

* 1.獲取

* 1.1 獲取文件名稱

* 1.2 獲取文件路徑

* 1.3 獲取文件大小

* 1.4 獲取文件修改時間

*/

File f=new File("demo.txt");

String name=f.getName();

String abspath=f.getAbsolutePath(); //獲取絕對路徑

String path=f.getPath(); //獲取相對路徑

long length=f.length();

long time=f.lastModified();

Date date=new Date(time);

DateFormat dateFormat=DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);

String str_time=dateFormat.format(date);

System.out.println("name"+":"+name);

System.out.println("abspath"+":"+abspath);

System.out.println("path"+":"+path);

System.out.println("length"+":"+length);

System.out.println("str_time"+":"+str_time);

/*

* 2.創建與刪除

* boolean

*/

createAndDeleteFile();

}


public static void createAndDeleteFile() throws IOException {

File file=new File("file.txt");

/*

* 和輸出流不一樣,如果文件不存在,則創建,否則,不創建。

*/

boolean b=file.createNewFile();

System.out.println(b);

boolean b1=file.delete();

System.out.println(b1);

//文件夾的創建與刪除。

File dir=new File("abc");

boolean b2=dir.mkdir();

System.out.println(b2);

isDemo();

}

/*

* 3.判斷

*/

public static void isDemo(){

File f=new File("abc.txt");

boolean b=f.exists();

System.out.println(b);

//最好先判斷是否存在。

System.out.println(f.isFile());

System.out.println(f.isDirectory());

renameToDemo();

}

/*

* 4.重命名

*/

public static void renameToDemo(){

File f1=new File("demo.txt");

File f2=new File("Abc.txt");

f2.renameTo(f1);

}

}



過濾器的演示:

package day22;

import java.io.File;

import java.io.FilenameFilter;


public class FilterByJava implements FilenameFilter {

//java文件過濾器

public boolean accept(File dir, String name) {

return name.endsWith(".java");


}

}



package day22;

import java.io.File;

import java.io.FilenameFilter;


public class SuffixFilter implements FilenameFilter {


//文件後綴名過濾器

private String suffix;

public SuffixFilter(String suffix){

super();

this.suffix=suffix;

}

public boolean accept(File dir, String name) {


return name.endsWith(suffix);


}

}



package day22;

import java.io.File;

import java.io.FileFilter;


public class FilterByHidden implements FileFilter {


//隱藏文件過濾器

public boolean accept(File pathname) {


return !pathname.isHidden();


}


}



package day22;

import java.io.File;


public class FileListDemo {


/**

* @param args

*/

public static void main(String[] args) {

listDemo_4();

}


public static void listDemo_4() {

File dir=new File("e:\\");

File[] files=dir.listFiles(new FilterByHidden()); //過濾掉隱藏文件

for(File file:files){

System.out.println(file);

}

}


public static void listDemo_3() { //這個比demo_2方便,傳啥過濾啥

File dir=new File("e:\\");

String[] names=dir.list(new SuffixFilter(".java")); //如果想過濾.txt文件,直接在這傳.txt就行,不用去修改過濾器,方便一些。

for(String name:names){

System.out.println(name);

}

}

public static void listDemo_2() {

File dir=new File("e:\\");

String[] names=dir.list(new FilterByJava()); //過濾掉非Java類型的文件

for(String name:names){

System.out.println(name);

}

}


public static void listDem() {

File file=new File("e:\\");

/*

* 獲取當前目錄下的文件以及文件夾的名稱,包含隱藏文件。

* 調用List方法的File對象中封裝的必須是目錄,否則空指針異常。訪問系統級目錄也會空指針異常。

* 如果目錄存在但是沒有內容,會返回一個數組,但是長度為零。

*/

String[] names=file.list();

for(String name:names){

System.out.println(name);

}

}

}


本文出自 “12946849” 博客,請務必保留此出處http://12956849.blog.51cto.com/12946849/1934943

java(十)IO流