1. 什麼是流
Java中的流是對字節序列的抽象,咱們能夠想象有一個水管,只不過如今流動在水管中的再也不是水,而是字節序列。和水流同樣,Java中的流也具備一個「流動的方向」,一般能夠從中讀入一個字節序列的對象被稱爲輸入流;可以向其寫入一個字節序列的對象被稱爲輸出流java
2. 字節流
Java中的字節流處理的最基本單位爲單個字節,它一般用來處理二進制數據。Java中最基本的兩個字節流類是InputStream和OutputStream,它們分別表明了一組基本的輸入字節流和輸出字節流。InputStream類與OutputStream類均爲抽象類,咱們在實際使用中一般使用Java類庫中提供的它們的一系列子類。app
3. 字符流
Java中的字符流處理的最基本的單元是Unicode碼元(大小2字節),它一般用來處理文本數據。所謂Unicode碼元,也就是一個Unicode代碼單元,範圍是0×0000~0xFFFF。在以上範圍內的每一個數字都與一個字符相對應,Java中的String類型默認就把字符以Unicode規則編碼然後存儲在內存中。然而與存儲在內存中不一樣,存儲在磁盤上的數據一般有着各類各樣的編碼方式。使用不一樣的編碼方式,相同的字符會有不一樣的二進制表示。ui
4. 字符流與字節流的區別
通過以上的描述,咱們能夠知道字節流與字符流之間主要的區別體如今如下幾個方面:
字節流操做的基本單元爲字節;字符流操做的基本單元爲Unicode碼元。
字節流默認不使用緩衝區;字符流使用緩衝區。
字節流一般用於處理二進制數據,實際上它能夠處理任意類型的數據,但它不支持直接寫入或讀取Unicode碼元;字符流一般處理文本數據,它支持寫入及讀取Unicode碼元。
示例一:文件讀取和寫入(支持編碼選擇、文件內容追加)編碼
/** * 讀取文件文本內容。 * * @param filePath 文件路徑 * @param charset 字符編碼格式 * @throws Exception */ public static String readAllText(String filePath, String charset) throws Exception { StringBuilder sb = new StringBuilder(); try ( InputStreamReader reader = new InputStreamReader(new FileInputStream(filePath), charset); BufferedReader br = new BufferedReader(reader) ) { String line; while ((line = br.readLine()) != null) { sb.append(line); sb.append(SystemCharUtils.getNewLine()); } } catch (Exception e) { throw e; } return sb.toString(); } /** * 將字符串追加到文件。 * * @param str 待寫入字符串 * @param filePath 文件路徑(文件不存在則自動建立) * @param charset 字符編碼 * @throws Exception */ public static void appendFile(String str, String filePath, String charset) throws Exception { // 建立新文件對象。 File file = new File(filePath); //自動建立目錄。 if (!file.getParentFile().exists()) { if (!file.getParentFile().mkdirs()) { throw new RuntimeException("文件目錄建立失敗:" + file.getParentFile().getAbsolutePath()); } } //若是文件不存在則自動建立。 if (!file.exists()) { file.createNewFile(); } try ( OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file, true), charset); BufferedWriter bw = new BufferedWriter(writer); ) { bw.write(str); } catch (Exception e) { throw e; } }
示例二:對象序列化到文件流 及 從文件流反序列化爲對象
注意:實體對象要實現Serializable接口。spa
/** * 序列化文件路徑。 */ String localFilePath = SystemCharUtils.getUserDir() + SystemCharUtils.getFileSeparator() + "data" + SystemCharUtils.getFileSeparator() + "test" +SystemCharUtils.getFileSeparator() + "testData.data"; /** * 從文件流反序列化爲對象。 * * @param filePath 文件路徑 * @throws Exception */ public static <T> T getObject(String filePath) throws Exception { try ( ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(filePath)); ) { return (T) inputStream.readObject(); } catch (Exception e) { throw e; } } /** * 將對象序列化到文件流。 * * @param obj 須要序列化的對象 * @param filePath 文件路徑 * @throws Exception */ public static void saveObject(Object obj, String filePath) throws Exception { // 建立新文件對象。 File file = new File(filePath); //自動建立目錄。 if (!file.getParentFile().exists()) { if (!file.getParentFile().mkdirs()) { throw new RuntimeException("文件目錄建立失敗:" + file.getParentFile().getAbsolutePath()); } } //若是文件不存在則自動建立。 if (!file.exists()) { file.createNewFile(); } try ( ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file)); ) { outputStream.writeObject(obj); } catch (Exception e) { throw e; } }