流的理解
一個流可以理解爲一個字節數據的序列。
輸入流(InputStream)表示從一個源讀取(read)數據。
輸出流(OutputStream)表示向一個目標寫(write)數據。
一個不恰當但是很形象的例子:
輸入流就是從磁盤或網絡讀取字節數據到程序內存;
輸出流就是把字節數據從程序內存寫到磁盤或網絡中去。
這樣來看,所謂的輸入或輸出,參考方向都是當前程序內存而言。所以一個流不可能既是輸入流也是輸出流的說法。
流分類
按功能分:
低級流:有明確的數據源。
高級流:沒有明確的數據源,用於處理其他低級流,高級流不能單獨存在,只能與低級流配合使用。
所以區分也很好區分,也就是看有沒有明確的數據源,是否依賴低級流。
按讀取數據單位分:
字節流:以字節爲單位進行讀寫,InputStream OutputStream
字符流:以字符爲單位進行讀寫,Writer Reader
==================================
字節(Byte):字節是通過網絡傳輸信息(或在硬盤或內存中存儲信息)的單位。字節是計算機信息技術用於計量存儲容量和傳輸容量的一種計量單位,1個字節等於8位二進制(1 byte = 8 bit),它是一個8位的二進制數,是一個很具體的存儲空間。
字符:字符是指計算機中使用的文字和符號人們使用的記號,抽象意義上的一個符號。
關於字節和字符的關係,就不得不說道編碼方式。不同的編碼方式裏,字符和字節的對應關係不同。字符之間的編碼不一致也是造成亂碼的原因。
=======================================
以下詳細說明幾種流
Java 爲 I/O 提供了強大的而靈活的支持,使其更廣泛地應用到文件傳輸和網絡編程中。
Java所有的流類位於java.io包中,都分別繼承字以下四種抽象流類型。
繼承自InputStream/OutputStream的流都是用於向程序中輸入/輸出數據,且數據的單位都是字節(byte=8bit)。
繼承自Reader/Writer的流都是用於向程序中輸入/輸出數據,且數據的單位都是字符(2byte=16bit)。
字節流:
1、用於讀寫文件的輸入輸出流
FileInputStream:文件字節輸入流
該流用於從文件讀取數據,它的對象可以用關鍵字 new 來創建。
有多種構造方法可用來創建對象。
可以使用字符串類型的文件名來創建一個輸入流對象來讀取文件:
InputStream f =new FileInputStream("C:/xxxx/xxxx");
也可以使用一個文件對象來創建一個輸入流對象來讀取文件。我們首先得使用 File() 方法來創建一個文件對象:
File file =new File("C:/xxxx/xxxxx");
InputStream out =new FileInputStream(file);
FileOutputStream:文件字節輸出流
該類用來創建一個文件並向文件中寫數據。
如果該流在打開文件進行輸出前,目標文件不存在,那麼該流會創建該文件。
有兩個構造方法可以用來創建 FileOutputStream 對象。
使用字符串類型的文件名來創建一個輸出流對象:
OutputStream f =new FileOutputStream("C:/xxxx/xxxx")
也可以使用一個文件對象來創建一個輸出流來寫文件。我們首先得使用File()方法來創建一個文件對象:
File f = new File("C:/xxxx/xxxx");
OutputStream f =new FileOutputStream(f);
下面是一個演示 InputStream 和 OutputStream 用法的例子:
public class FileStreamsDemo { public static void main(String[] args) { try{ byte bWrite [] = {11,21,3,40,5}; OutputStream os = new FileOutputStream("test.txt"); for(int x=0; x < bWrite.length ; x++){ os.write( bWrite[x] ); // writes the bytes } os.close(); InputStream is = new FileInputStream("test.txt"); int size = is.available(); for(int i=0; i< size; i++){ System.out.print((char)is.read() + " "); } is.close(); }catch(IOException e){ System.out.print("Exception"); } } }
上面的程序首先創建文件test.txt,並把給定的數字以二進制形式寫進該文件,同時輸出到控制檯上。
以上代碼由於是二進制寫入,可能存在亂碼,你可以使用以下代碼實例來解決亂碼問題:
public class FileStreamsDemo2 { public static void main(String[] args) throws IOException { File f = new File("a.txt"); FileOutputStream fop = new FileOutputStream(f); // 構建FileOutputStream對象,文件不存在會自動新建 OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8"); // 構建OutputStreamWriter對象,參數可以指定編碼,默認爲操作系統默認編碼,windows上是gbk writer.append("中文輸入"); // 寫入到緩衝區 writer.append("\r\n"); //換行 writer.append("English"); // 刷新緩存衝,寫入到文件,如果下面已經沒有寫入的內容了,直接close也會寫入 writer.close(); //關閉寫入流,同時會把緩衝區內容寫入文件,所以上面的註釋掉 fop.close(); // 關閉輸出流,釋放系統資源 FileInputStream fip = new FileInputStream(f); // 構建FileInputStream對象 InputStreamReader reader = new InputStreamReader(fip, "UTF-8"); // 構建InputStreamReader對象,編碼與寫入相同 StringBuffer sb = new StringBuffer(); while (reader.ready()) { sb.append((char) reader.read()); // 轉成char加到StringBuffer對象中 } System.out.println(sb.toString()); reader.close(); // 關閉讀取流 fip.close(); // 關閉輸入流,釋放系統資源 } }
字符流(都是高級流):
response.setContentType("application/json;charset=UTF-8");
Map<String, Object> resultMap = "";
String respString = JSONObject.toJSONString(resultMap);
PrintWriter out = response.getWriter();
out.print(respString);
out.close();
Java中的目錄
創建目錄:
mkdir( )方法創建一個文件夾,成功則返回true,失敗則返回false。失敗表明File對象指定的路徑已經存在,或者由於整個路徑還不存在,該文件夾不能被創建。
mkdirs()方法創建一個文件夾和它的所有父文件夾。
讀取目錄:
如果創建一個 File 對象並且它是一個目錄,那麼調用 isDirectory() 方法會返回 true。
可以通過調用該對象上的 list() 方法,來提取它包含的文件和文件夾的列表。
下面展示的例子說明如何使用 list() 方法來檢查一個文件夾中包含的內容:
public class ReadDirListDemo { public static void main(String[] args) { String dirname = "/tmp"; File f1 = new File(dirname); if (f1.isDirectory()) { System.out.println( "目錄 " + dirname); String s[] = f1.list(); for (int i=0; i < s.length; i++) { File f = new File(dirname + "/" + s[i]); if (f.isDirectory()) { System.out.println(s[i] + " 是一個目錄"); } else { System.out.println(s[i] + " 是一個文件"); } } } else { System.out.println(dirname + " 不是一個目錄"); } } }
刪除目錄或文件:
以下代碼會刪除目錄/tmp/java/,即便目錄不爲空。
測試目錄結構:
public class DeleteFileDemo { public static void main(String args[]) { // 這裏修改爲自己的測試目錄 File folder = new File("/tmp/java/"); deleteFolder(folder); } //刪除文件及目錄 public static void deleteFolder(File folder) { File[] files = folder.listFiles(); if(files!=null) { for(File f: files) { if(f.isDirectory()) { deleteFolder(f); } else { f.delete(); } } } folder.delete(); } }