--------------android培訓、java培訓、學習型技術博客、期待與您交流! --------------
IO流的四個基類
A:字節流
輸入流
InputStream
|--FileInputStream
輸出流
OutputStream
|--FileOutputStream
B:字符流
輸入流
Reader
|--FileReader
輸出流
Writer
|--FileWriter爲了提高讀寫效率,加入了緩衝技術字符流:(BufferedReader和BufferedWriter)字節流:(BufferedInputStream和BufferedOutputStream)
複製文本代碼
package Demo;
/*需求:複製文本文件
分析:源:用Reader或者InputStream
操作的是硬盤上的純文本數據用Reader
加入緩衝技術用BufferedReader
目的:用Writer或者OutputStream
操作的是硬盤上的純文本數據用Writer
加入緩衝技術用BufferedWriter
*/
import java.io.*;
public class CopyTxt {
public static void main(String[] args) {
BufferedReader bur = null;
BufferedWriter buw = null;
try {
bur = new BufferedReader(new FileReader("D:\\work.txt")); // 提高效率,定義讀取流緩衝區
buw = new BufferedWriter(new FileWriter("C:\\123.txt")); // 提高效率,定義寫入流緩衝區
String line = null;
while ((line = bur.readLine()) != null) { // 讀取一行數據
buw.write(line);
buw.newLine(); // 換行
buw.flush(); // 刷新,將緩衝區的數據保存到文件裏。使用緩衝區一定記着刷新
}
System.out.println("複製成功");
} catch (Exception e) {
throw new RuntimeException("複製失敗");
} finally {
try {
if (bur != null)
bur.close(); // 關閉讀取流
} catch (Exception e) {
throw new RuntimeException("讀取流關閉失敗");
}
try {
if (buw != null)
buw.close(); // 關閉寫入流
} catch (Exception e) {
throw new RuntimeException("寫入流關閉失敗");
}
}
}
}
需求:複製一張圖片
分析:
源:用Reader或者InputStream
操作的是硬盤上的非純文本數據用InputStream
加入緩衝技術用BufferedInputStream
目的:用Writer或者OutputStream
操作的是硬盤上的純文本數據用OutputStream
加入緩衝技術用BufferedOutputStream
package Demo;
import java.io.*;
public class CopyPic {
public static void main(String[] args) {
BufferedInputStream br = null;
BufferedOutputStream bw = null;
try {
bw = new BufferedOutputStream(new FileOutputStream("D:\\123.jpg"));
br = new BufferedInputStream(new FileInputStream("C:\\abc.jpg"));
int len = 0;
while ((len = br.read()) != -1) { // 從輸入流中讀取下一個字節
bw.write(len);
bw.flush();
}
} catch (Exception e) {
throw new RuntimeException("複製失敗");
} finally {
try {
if (br != null) {
br.close();
}
} catch (Exception e) {
throw new RuntimeException("讀取流關閉失敗");
}
try {
if (bw != null) {
bw.close();
}
} catch (Exception e) {
throw new RuntimeException("寫入流關閉失敗");
}
}
System.out.println("複製成功");
}
}
裝飾模式
裝飾模式比繼承要靈活,而且降低了類於類之間的關係。避免了繼承體系臃腫。裝飾類因爲增強已有對象,具備的功能和已有的是相同的,只不過提供了更強功能,所以裝飾類和被裝飾類通常是都屬於一個體系中的。
給已有的對象提供增強額外的功能。還不用對原有對象進行修改。
裝飾模式在IO中的應用,寫入文件用的FileWriter,發現這個類的功能不夠強大裝飾類出現了BufferedWriter,增強原有FileWriter的功能,在原有FileWriter的基礎上,增加了一個新的方法newLine(),但是BufferedWriter寫一行的方法,底層用的還是FileWriter的方法BufferedWriter構造方法 BufferedWriter(Writer out)
Writer
|--TestWriter
|--MediaWriter
現有一個體系用於各種數據的寫入。
但是,防線寫入效率有點低。想要對其進行效率的提高。
可以使用緩衝技術來完成的。
以後對象的寫入方法,不夠高效,可以通過派生子類的形式對齊進行復寫,定義高效的寫入動作。
Writer
|--TestWriter
|--BufferTextWriter
|--MediaWriter
|--BufferMediaWriter
通過繼承的方式提高了效率。
但是對於擴展性是一個問題。而且所需的功能越多,子類就越多。
一旦加入新類,就需要爲它提供高效。麻煩!
如何解決這個問題呢?優化!
既然都需要緩衝,對數據寫入的效率進行提高。
可以轉變一下思想,這樣來做,將緩衝技術單獨進行封裝。
哪個對象需要緩衝,就把哪個對象傳遞給緩衝對象即可。
class Buffer {
Buffer(TestWriter w) {
}
Buffer(MediaWriter w) {
}
}
爲了便於擴展,可以對一組對象進行緩衝。
class BufferWriter extends Writer{
Buffer(Writer w){
}
Public void write(){
}
}
體系就變成了這樣:
Writer
|--TextWriter
|--MediaWriter
|--BufferWriter
BufferWriter的出現,增強了Writer體系中的功能。
這種設計方式比原來更爲靈活,避免了繼承的臃腫。
將這樣解決方式就定義了一個名稱方便於後人使用:裝飾設計模式。
裝飾設計代碼
/*
模擬一下BufferedReader
*/
import java.io.*;
class MyBufferedReader extends Reader {
private Reader r;
MyBufferedReader(Reader r) {
this.r = r;
}
// 可以一次讀一行數據的方法。
public String myReadLine() throws IOException {
// 定義一個臨時容器。原BufferReader封裝的是字符數組。
// 爲了演示方便。定義一個StringBuilder容器。因爲最終還是要將數據變成字符串。
StringBuilder sb = new StringBuilder();
int ch = 0;
while ((ch = r.read()) != -1) {
if (ch == '\r')
continue;
if (ch == '\n')
return sb.toString();
else
sb.append((char) ch);
}
if (sb.length() != 0)
return sb.toString();
return null;
}
/*
* 覆蓋Reader類中的抽象方法。
*/
public int read(char[] cbuf, int off, int len) throws IOException {
return r.read(cbuf, off, len);
}
public void close() throws IOException {
r.close();
}
public void myClose() throws IOException {
r.close();
}
}
class MyBufferedReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("buf.txt");
MyBufferedReader myBuf = new MyBufferedReader(fr);
String line = null;
while ((line = myBuf.myReadLine()) != null) {
System.out.println(line);
}
myBuf.myClose();
}
}
需求:讀取鍵盤錄入,將鍵盤錄入轉換成大寫存放在文件中
分析:
源:用InputStream或Reader
操作的數據是純文本用Reader 加入緩衝技術BufferedReader
設備:鍵盤,對應的對象是System.in 所以要用轉換流 InputStreamReader
目的:用Writer或OutputStream
操作的數據是文本數據用Writer
加入緩衝技術BufferedWriter
設備:硬盤 硬盤上的一個文本文件
package Demo;
import java.io.*;
public class ReadSystemIn {
public static void main(String[] args) throws Exception {
BufferedReader bur = null;
BufferedWriter buw = null;
try {
bur = new BufferedReader(new InputStreamReader(System.in));
buw = new BufferedWriter(new FileWriter("D:\\abc.java"));
String line = null;
while ((line = bur.readLine()) != null) { // 一次讀一行的數據
if (line.equals("over"))
break;
buw.write(line.toUpperCase()); // 把讀取的字符串轉換成大寫並寫入
buw.newLine(); // 換行
buw.flush();
}
} catch (Exception e) {
throw new RuntimeException("失敗");
} finally {
try {
if (bur != null)
bur.close(); // 關閉讀取流
} catch (Exception e) {
throw new RuntimeException("讀取流關閉失敗");
}
try {
if (buw != null)
buw.close(); // 關閉寫入流
} catch (Exception e) {
throw new RuntimeException("寫入流關閉失敗");
}
}
}
}
File類
1)創建功能:
A:創建文件
public boolean createNewFile():如果文件不存在,就會創建一個文件。
B:創建文件夾(目錄)
public boolean mkdir():創建單級文件夾,要求父文件夾先存在
2)刪除功能:public boolean mkdirs():直接創建多級文件夾
public boolean delete() 不管的是刪除文件還是文件夾,都是採用同一種功能。
注意事項:如果是刪除文件夾,請保證文件夾內沒有內容。 如果有內容,必須把內容刪除完畢才能刪除文件夾。
3)判斷功能:
boolean exists() :文件是否存在.
boolean isFile(): 判斷是否是文件
boolean isDirectory();是否是文件夾
boolean isHidden(); 是否隱藏
boolean isAbsolute(); 是否是絕對路徑,文件不存在的情況也能判斷。4)獲取信息:
String getAbsolutePath(): 獲取抽象路徑
需求: 將一個指定目錄下的class文件的絕對路徑,存儲到一個文本文件中。
分析:列出指定目錄下文件的絕對路徑,就是包含子目錄中的內容,也就是列出指定目錄下所有class文件的絕對路徑。 在列出過程中因爲是目錄中還有目錄,所以還可以調用本功能,也就是遞歸。
在使用遞歸的時候要注意:(1)遞歸一定要有出口,否則就是死遞歸。(2)遞歸的次數不能過多,否則內存溢出。
import java.io.*; import java.util.ArrayList; import java.util.List; public class ListDir { public static void main(String[] args) { File dir = new File("C:\\work2"); List<File> list = new ArrayList<File>(); getPath(dir, list); // System.out.println(list); writeToFile(list, "D:\\abc.txt"); } // 定義一個獲取文件絕對路徑,把絕對路徑對象存入到集合中的方法 public static void getPath(File dir, List<File> list) { File[] file = dir.listFiles(); for (File f : file) { if (f.isDirectory()) { // 遍歷到的f,如果是目錄就進行遞歸 getPath(f, list); } else { if (f.getName().endsWith(".class")) list.add(f); } } } // 定義一個得到集合裏面的絕對路徑,把絕對路徑存儲到指定的文本文件的方法 public static void writeToFile(List<File> list, String javaListFile) { BufferedWriter buw = null; try { buw = new BufferedWriter(new FileWriter(javaListFile)); for (File file : list) { buw.write(file.getAbsolutePath()); // 得到絕對路徑,並且寫入到流中 buw.newLine(); buw.flush(); } } catch (IOException e) { throw new RuntimeException(); } finally { try { if (buw != null) buw.close(); } catch (IOException e) { throw new RuntimeException("寫入流關閉失敗"); } } } }