---恢復內容開始---
Java對數據的操作都是通過流的方式,數據的輸入和輸出是相對內存來說的,將外設的數據讀到內存:輸入流;將內存的數據寫到外設:輸出流。
流按操作數據分為兩種:字節流,字符流。
輸入輸出的數據全都是以字節為單位的二進制,字符流后期才出現,字符流出現的目的是讓機器識別日常生活文字,編碼表(美國ascii,中國GBK)記錄了文字和數字的對應關系,從而字節流+編碼表=字節流,從硬盤讀取字節流之后,先查表,轉換成對應的文字,從而形成字符流。(注:國際統一的為unicode(java內置),無論什么字符都用2個字節表示)
字節流的抽象基類(頂層父類):inputStream,outputStream.(數據載體)
字符流的抽象基類:Reader,Writer.
這些子類的后綴都是父類名,前綴是子類實現的功能。
java.lang.Objectjava.lang.Object
|--java.io.writer(寫入字符流的抽象類)|--java.io.writer
|--java.io.OutputStreamWriter(字符流通向字節流的橋梁,轉換流)|--BufferedWriter
|--java.io.FileWriter
1.FileWriter:將字符寫入到文本文件(和文本編輯器,Word等工具一個原理)
public static void main(String[] args) throws IOException{
FileWriter fw= new FileWriter("demo.txt",true); // 如果demo存在,則會覆蓋,如果不存在,創建。如果加入 true,那么不會覆蓋,會續寫。
fw.write("abc"); //abc寫入到了臨時存儲緩沖區中。
fw.flush(); //將數據直接寫入到demo。
fw.close(); //關閉流,釋放資源。close中調用了flush,flush可省略。
}
IO異常的處理:
public static void main(String[] args){
FileWriter fw = null; //流對象的創建方式,因為一般都會發生異常。
try{
fw= new FileWriter("demo.txt",true);
fw.write("abc");
}
catch (IOException e){
System.out.PRintln(e.toString());
}
finally{
if(fw != null) //如果要創建的路徑不存在,比如F盤沒有,那么fw這個流就不能創建,如果這里不判斷,就會拋出異常。
try{
fw.close();
}catch(IOException e){throw new RuntimeException("關閉失敗");}
}
}
2.FileReader:讀取文本文件中的字符
FileReader fr = new FileReader("demo.txt");
int a = 0;
while((a=fr.read())!=-1)
{
sop(char(a)); //每次讀取一個字符,但是以二進制的數字格式輸出(0-65535 0x00-0xffff)。如果讀取完了,會返回-1
}
/*
也可以以數組的形式來讀
char[] buf = new char[3];
int num = fr.read(buf); //num是讀取的字符個數
sop(num+":"+new String(buf,0,num)); //這里string里用num可以保證讀幾個打印幾個。
如果存的是abcde五個字符,那么第一次逐個讀取abc到內存里的長度為3的數組,然后輸出num=3和abc,下次讀取時de放到了內存數組的前兩位,覆蓋了ab所在位置,第三位讀不到但是內存中還是c,所以第二次讀取num=2和dec,第三次返回num=0和dec。
while((num=fr.read(buf))!=-1){
sop(new String(buf,0,num)); //buf越大,效率越高
}
*/
例子:復制文本文件 先讀再寫
public static void main(String[] args) {FileReader fr = null; FileWriter fw = null; try{ fr = new FileReader("demo.txt"); fw = new FileWriter("demo123.txt"); char[] buf = new char[1024]; // 讀流讀出來以后,放到內存中緩沖區,然后進寫流,寫流flush或close,寫入demo123
int ch = 0; while((ch=fr.read())!=-1) { fw.write(buf); } }catch(IOException e){ e.toString(); } finally{ if(fw!=null ) try{ fw.close(); } catch( Exception e){ throw new RuntimeException("讀寫異常"); } if(fr!=null) try{ fr.close(); } catch( Exception e){ throw new RuntimeException("讀寫異常"); } }}
3.字符流的緩沖區BufferedReader,BufferedWriter(其實就是在類里面封裝的上面的char數組)
BufferedReader和BufferedWriter,結合流才可以使用,提高流的使用效率。 數據庫的連接池
BufferedWriter:將文本寫入字符輸出流,緩沖各個字符,從而提供單個字符,數組和字符串的高效寫入。可以設置大小,但是默認大小一般夠用。
方法:行分隔符newline();由line.seperate定義。
public static void main(String[] args) throws IOException { FileWriter fw = new FileWriter("demo1.txt");
FileReader fr = new FileReader("demo.txt");
BufferedReader bufr = new BufferedReader(fr); BufferedWriter bufw = new BufferedWriter(fw);
String line = null;
while((line = bufr.readLine())!=null){ //readLine()是BufferedReader特有方法,其中使用了BufferedReader的read方法,將讀取到的字符串緩沖并判斷換行標記,然后將標記前的字符串返回。
bufw.write(line);
bufw.newLine(); //換行 newLine()是BufferedWriter特有方法
bufw.flush();
}
bufr.close();
bufw.close(); //關掉的是流,不是緩沖區
}
java.lang.Object
|--java.io.OutputStream
|--java.io.FileOutputStream
4.FileOutputStream,FileInputStream,BufferedInputStream,BufferedOutputStream.流只能操作文本文件,而字節流可以操作多種。
private static void copy() {FileOutputStream fos = null;FileInputStream fis = null; try{ fis = new FileInputStream("D://cover.jpg"); BufferedInputStream buis = new BufferedInputStream(fis);fos = new FileOutputStream("E://cover.jpg"); BufferedOutputStream buos = new BufferedOutputStream(fos);int ch = 0; ry {while((ch=buis.read(buf))!=-1){ try{ buos.write(buf); } catch(IOException e){ System.out.println("失敗"); } } catch (IOException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace();}finally{try {if(fis==null)fis.close();if(fos==null)fos.close();System.out.println("復制成功");} catch (IOException e) {e.printStackTrace();}}
5.字節流和字符流之間的轉換 InputStreamReader,OutputStreamWriter
InputStreamReader將字節流轉換成字符流(讀取的還是字節流,但是它拿著字節去查表去了,返回的是字符的ASCII值,一個漢字兩個字節,如果不轉的話,分別輸出兩個字節值,轉換成字符流,輸出一個值) 解碼的過程
從 InputStream in = System.in; 上 OutputStream out =System.out; 上 InputStreamReader isr = new InputStreamReader(in); 向 OutputStreamWriter osw = new OutputStreamWriter(out); 向 BufferedReader bufr = new BufferedReader(isr);下 BufferedWriter bufw = new BufferedWriter(osw); 下 String line = bufr.readLine();-------------------------> 從 bufw.write(line);
簡化寫法 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in或者是FileInputStream("demo.txt")));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out或者是FileOutputStream("demo.txt")));
注意點:FileWriter fw = new FileWriter("demo.txt");效果等同于
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("demo.txt"),"GBK");
FileWriter是子類,為操作文件而生,默認GBK,其中封裝了轉換流功能,雖然看起來是直接操作文本中的字符,但說到底文本還是要從硬盤讀取,硬盤中的數據是字節。
6.File類
File f1 = new File("c://a.txt"); File f2 = new File("c://","a.txt");
File f = new File("c://"); File f4 = new File(f,"a.txt");
File f = new File("c:"+File.separator+"睿思"+File.separator+"a.txt"); 分隔符File.separator
具體方法:文件對象的狀態獲取,創建刪除,判斷,重命名,獲取根目錄和容量,目錄內容,過濾指定類型文件的過濾器(FilenameFilter接口)等。
7.Properties類(與流相關)
Map |--HashTable |--Properties1.集合中的鍵和值都是字符串類型。2.該集合中的數據可以保存到流中,或者從流獲取。操作以鍵值對形式存在的配置文件。
功能:將配置文件以流的形式讀出,然后利用properties的方法對其中的鍵值形式信息進行操作。
1.Properties p = new Properties(); p.setProperty("zhangsan", "22"); FileOutputStream fos = new FileOutputStream("demo.txt"); p.store(fos, "name+age"); fos.close();
2.File file = new File("demo.txt"); if(!file.exists()){ file.createNewFile(); } FileReader fr = new FileReader(file); Properties p = new Properties(); p.load(fr); p.list(System.out);//列出文件內容,測試是否關聯成功 p.setProperty("wangwu", "33"); FileWriter fw = new FileWriter(file); fw.close(); fr.close();
3.記錄應用程序打開次數
File confile = new File("confile.txt"); if(!confile.exists()){ confile.createNewFile(); } FileReader fr = new FileReader(confile); Properties p = new Properties(); p.load(fr); String name = p.getProperty("time"); int value = 0; if(name!=null){ value = Integer.parseInt(name); } value++; p.setProperty("time", "value");
4.返回目錄下文件名以.java結尾的文件(附件
public class Test { public static void main(String[] args) throws IOException { File dir = new File("c://"); FilenameFilter filter = new FilenameFilter(){ public boolean accept(File dir,String name){ return name.endsWith(".java"); } }; List<File> list = new ArrayList<File>(); getFiles(dir,filter,list); File destFile = new File(dir,"javalist.txt"); write2File(list,destFile); } public static void getFiles(File dir,FilenameFilter filter,List<File> list){ File[] files = dir.listFiles(); for(File file : files){ if(file.isDirectory()){ getFiles(file,filter,list); } else{ if(filter.accept(dir, file.getName()));{ list.add(file); } } } } public static void write2File(List<File> list,File destFile){ BufferedWriter bufw = null; try { bufw = new BufferedWriter(new FileWriter(destFile)); for(File file:list){ bufw.write(file.getAbsolutePath()); bufw.newLine(); bufw.flush(); } } catch (IOException e) { throw new RuntimeException(); } finally{ if(bufw!=null){ try{ bufw.close(); }catch(IOException e){ throw new RuntimeException("關閉失敗"); } } } } }8.打印流 PrintStream PrintWriter
可以對多種數據類型值進行打印,并保持數據的表示形式。不拋IOException。想保證數據形式原樣時,用print方法。
PrintStream打印的所有字符都使用平臺的默認字符編碼轉換為字節。在需要寫入字符而不是寫入字節的情況下,應該使用 PrintWriter類。
構造函數接受三種類型值:字符串路徑,File對象,字節輸出流
PrintStream out = new PrintStream("print.txt");
out.print(97);
out.close();
9.序列流SequenceInputStream
public static void main(String[] args) throws IOException { ArrayList<FileInputStream> al = new ArrayList<FileInputStream>(); al.add(new FileInputStream("demo1.txt"));al.add(new FileInputStream("demo2.txt"));al.add(new FileInputStream("demo3.txt")); Enumeration<FileInputStream> en = Collection.enumeration(al); //迭代器 SequenceInputStream sis = new SequenceInputStream(en); FileOutputStream fos = new FileOutputStream("demo.txt"); byte[] buf = new byte[1024]; int len = 0; while((len = sis.read(buf))!=-1){ fos.write(buf,0,len); } fos.close(); sis.close(); }新聞熱點
疑難解答