簡體   English   中英

Java中文件處理的可重試模式

[英]Retryable pattern for file processing in java

我需要處理一個大文件(具有列和相同格式的行)。 由於我需要考慮程序在處理過程中崩潰的情況,因此我需要將此處理程序重試,這意味着在它崩潰並再次啟動程序后,它可以繼續處理文件,從失敗的行開始。

有什么我可以遵循的模式或可以使用的圖書館嗎? 謝謝!


更新:

關於崩潰的情況,不僅涉及OOM或一些內部問題。 也可能是由於其他零件超時或機器崩潰導致的。 因此,try / catch無法處理此問題。


另一個更新:

關於對文件進行分塊,在我看來,這是可行的,但聽起來並不那么簡單。 就像我說的那樣,文件是用幾列格式化的,我可以根據其中一列將其拆分成數百個文件,然后逐個處理文件。 但是,除了這樣做,我想了解有關處理大文件/數據支持重試的通用解決方案的更多信息。

我會怎么做(雖然不是專業人士)

  1. 在文件的每一行上創建一個LineProcessor調用

    類Processor實現LineProcessor> {

      private List<String> lines = Lists.newLinkedList(); private int startFrom = 0; private int lineNumber = 0; public Processor(int startFrom) { this.startFrom = startFrom; } @Override public List<String> getResult() { return lines; } @Override public boolean processLine(String arg0) throws IOException { lineNumber++; if (lineNumber < startFrom) { // do nothing } else { if (new Random().nextInt() % 50000 == 0) { throw new IOException("Randomly thrown Exception " + lineNumber); } //Do the hardwork here lines.add(arg0); startFrom++; } return true; } } 
  2. 創建一個使用我的LineProcessor可調用文件來讀取

     class Reader implements Callable<List<String>> { private int startFrom; public Reader(int startFrom) { this.startFrom = startFrom; } @Override public List<String> call() throws Exception { return Files.readLines(new File("/etc/dictionaries-common/words"), Charsets.UTF_8, new Processor(startFrom)); } } 
  3. Callable包裝在Retryer中,然后使用Executor調用它

     public static void main(String[] args) throws InterruptedException, ExecutionException { BasicConfigurator.configure(); ExecutorService executor = Executors.newSingleThreadExecutor(); Future<List<String>> lines = executor.submit(RetryerBuilder .<List<String>> newBuilder() .retryIfExceptionOfType(IOException.class) .withStopStrategy(StopStrategies.stopAfterAttempt(100)).build() .wrap(new Reader(100))); logger.debug(lines.get().size()); executor.shutdown(); logger.debug("Happily Ever After"); 

    }

您可以在代碼中維護檢查點/提交樣式邏輯。 因此,當程序再次運行時,它將從同一檢查點開始。

您可以使用RandomAccessFile讀取文件,並使用getFilePointer()作為保存者的檢查點。 當您再次執行程序時,可以通過調用seek(offset)從此檢查點開始。

嘗試從OOM錯誤中捕獲獲勝者。 您應該對文件進行分塊處理,並在每次成功處理后將位置存儲到文件系統/數據庫/即使程序崩潰也可以保持持久性的任何位置。 然后,您可以在重新啟動軟件時從存儲它的位置讀取上一點。 在處理整個文件時,您還必須清除此信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM