Java中實現順序IO

  • 2020 年 2 月 17 日
  • 筆記

順序IO和隨機IO

對於磁碟的讀寫分為兩種模式,順序IO和隨機IO。 隨機IO存在一個定址的過程,所以效率比較低。而順序IO,相當於有一個物理索引,在讀取的時候不需要尋找地址,效率很高。

網上盜了一個圖(侵權刪)


Java中的隨機讀寫

在Java中讀寫文件的方式有很多種,先總結以下3種方法:

  1. 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();                   }                }         } 

  1. 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();                   }                }         }    } 

  1. 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許可證