Java中實現順序IO
- 2020 年 2 月 17 日
- 筆記
順序IO和隨機IO
對於磁碟的讀寫分為兩種模式,順序IO和隨機IO。 隨機IO存在一個定址的過程,所以效率比較低。而順序IO,相當於有一個物理索引,在讀取的時候不需要尋找地址,效率很高。
網上盜了一個圖(侵權刪)

Java中的隨機讀寫
在Java中讀寫文件的方式有很多種,先總結以下3種方法:
- FileWriter和FileReader
public static void fileWrite(String filePath, String content) { File file = new File(filePath); //創建FileWriter對象 FileWriter writer = null; try { //如果文件不存在,創建文件 if (!file.exists()) file.createNewFile(); writer = new FileWriter(file); writer.write(content);//寫入內容 writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } public static void fileRead(String filePath) { File file = new File(filePath); if (file.exists()) { try { //創建FileReader對象,讀取文件中的內容 FileReader reader = new FileReader(file); char[] ch = new char[1]; while (reader.read(ch) != -1) { System.out.print(ch); } reader.close(); } catch (IOException ex) { ex.printStackTrace(); } } }
- BufferedReader和BufferedWriter BufferedReader和BufferedWriter與
FileWriter和FileReader
程式碼的寫法一致,Buffer也多了一個讀取一行字元的操作。
public class BuffredRWHelper { public static void fileWrite(String filePath, String content) { File file = new File(filePath); //創建FileWriter對象 BufferedWriter writer = null; try { //如果文件不存在,創建文件 if (!file.exists()) file.createNewFile(); writer = new BufferedWriter(new FileWriter(file)); writer.write(content);//寫入內容 writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } public static void fileRead(String filePath) { File file = new File(filePath); if (file.exists()) { try { //創建FileReader對象,讀取文件中的內容 BufferedReader reader = new BufferedReader(new FileReader(file)); String line; while ((line = reader.readLine()) != null) { System.out.print(line); } reader.close(); } catch (IOException ex) { ex.printStackTrace(); } } } }
- FileInputStream和FileOutputStream 使用Stream的形式是最原始的方式,以位元組數組為中間的中轉緩解
public static void fileWrite(String filePath, String content) { FileOutputStream outputStream = null; try { File file = new File(filePath); boolean isCreate = file.createNewFile();//創建文件 if (isCreate) { outputStream = new FileOutputStream(file);//形參裡面可追加true參數,表示在原有文件末尾追加資訊 outputStream.write(content.getBytes()); }else { outputStream = new FileOutputStream(file,true);//表示在原有文件末尾追加資訊 outputStream.write(content.getBytes()); } } catch (Exception e) { e.printStackTrace(); } finally { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void fileRead(String filePath) { File file = new File(filePath); if (file.exists()) { try { //創建FileInputStream對象,讀取文件內容 FileInputStream fis = new FileInputStream(file); byte[] bys = new byte[1024]; while (fis.read(bys, 0, bys.length) != -1) { //將位元組數組轉換為字元串 System.out.print(new String(bys, StandardCharsets.UTF_8)); } } catch (IOException ex) { ex.printStackTrace(); } } }
Java中的順序讀寫
上面的對文件的讀寫都是隨機讀寫,如果用來寫比較小的日誌文件還能滿足要求,如果用來操作一個文件的讀寫,那可能帶來很大的性能消耗。
順序IO的讀寫在中間件使用的很頻繁,尤其是在隊列中。幾乎所有的隊列(kafka,qmq等使用文件存儲消息)都採用了順序IO讀寫。
與隨機讀寫不同的是,順序讀寫是優先分配一塊文件空間,然後後續內容追加到對應空間內。
在使用順序IO進行文件讀寫時候,需要知道上次寫入的地方,所以需要維護一個索引或者輪詢獲得一個沒有寫入位置。
public static long fileWrite(String filePath, String content, int index) { File file = new File(filePath); RandomAccessFile randomAccessTargetFile; MappedByteBuffer map; try { randomAccessTargetFile = new RandomAccessFile(file, "rw"); FileChannel targetFileChannel = randomAccessTargetFile.getChannel(); map = targetFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, (long) 1024 * 1024 * 1024); map.position(index); map.put(content.getBytes()); return map.position(); } catch (IOException e) { e.printStackTrace(); } finally { } return 0L; } public static String fileRead(String filePath, long index) { File file = new File(filePath); RandomAccessFile randomAccessTargetFile; MappedByteBuffer map; try { randomAccessTargetFile = new RandomAccessFile(file, "rw"); FileChannel targetFileChannel = randomAccessTargetFile.getChannel(); map = targetFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, index); byte[] byteArr = new byte[10 * 1024]; map.get(byteArr, 0, (int) index); return new String(byteArr); } catch (IOException e) { e.printStackTrace(); } finally { } return ""; }
(本文完)
作者:付威 部落格地址:http://blog.laofu.online 如有任何知識產權、版權問題或理論錯誤,還請指正。 本文是付威的網路部落格原創,自由轉載-非商用-非衍生-保持署名,請遵循:創意共享3.0許可證