2015-10-05 60 views
0

使用案例: 具有固定長度的約200萬條記錄的.dat舊式平面文件(File2)。需要讀取該文件,並在每個記錄中有一個唯一的ID,我需要抓取並檢查文件的差異集(File1)並刪除此記錄。RecordSeperatorPolicy Spring根據長度/字符數量批量

我做了什麼? 我配置了2個工作。第一份工作將使用FixedLengthTokenizer讀取File1,並將抓取唯一ID並寫入一個diff文件,在該文件上我使用Apache Lucene配置了一個tasklet以創建索引。

2nd Job是讀取File2,現在這個文件有點棘手。沒有分隔符或記錄分隔符。我所知道的是每個記錄將包含大約1400個字符。我研究了很多,我唯一的希望是這個RecordSeparatorPolicy,我不知道如何實現這個用例。 閱讀每條記錄後,在處理器中,我需要搜索Job1中創建的索引,然後以某種方式刪除File2中的記錄。

我在哪裏掙扎? 因此,我需要生成的輸出文件不應觸摸或轉換文件的原始格式。現在,不是使用ItemWriter創建新文件,而是有辦法在同一個文件中刪除該記錄?我的猜測是沒有。 因此,我使用PassThroughLineMapper將整個文件讀取爲單個字符串。這是一個200萬記錄文件,其中每個記錄有1400個字符。 Java字符串也不能容納這麼多。其他的想法是,編寫一個自定義的ItemReader,其中我將使用BufferedReader並以某種方式將單行的1400個字符分開,然後將其發送給處理器。但是這也沒有奏效。

如何讀取這種文件?另外,我不想使用任何類型的POJO,因爲我需要的文件完全是這樣,而且我沒有改變任何東西。 請建議一種方法。

+0

爲什麼沒有你的自定義閱讀器的工作?海事組織這是你應該怎麼做的方式。 –

+0

@HansjoergWingeier:不知道我做錯了什麼,我可以發佈這個讀者,但是你是否有一個impl? – PavanSandeep

+0

從我讀到的,我會寫我自己的讀者。我沒有特別的impl,但我知道,一次加載整個輸入是錯誤的方法。據我瞭解,你沒有一個行分隔符,並不是所有的recoards具有相同的長度,因此現在使用FlatFileItemReader是沒有選擇的(因爲它內部使用BufferedReader.readLine())。不過,應該可以從FlatFileItemReader擴展並覆蓋適當的方法。但是,請發佈您的閱讀器代碼,以便社區可以查看它。 –

回答

0

有一個FixedLengthTokenizer類可以用來讀取您的源文件。它允許您爲源文件的每一行指定字段數量及其各自的長度。

另請參閱:Springbatch documentation §6.6.2

下面是一個例子:

<bean id="tokenizer" class="org.springframework.batch.item.file.transform.FixedLengthTokenizer"> 
    <property name="names" value="column1, column2, column3, column4" /> 
    <property name="columns" value="1-100, 101-349, 350-1000, 1001-1400" />    
</bean> 

UPDATE

如果您的記錄不同,還有一類PatternMatchingCompositeLineTokenizer,它可以在一個文件中匹配多種類型。

欲瞭解更多信息(和示例)這樣的實現的,請參閱:SpringBatch Patterns §11.5 - Multi-Line Records

+0

我已經爲我的第一份工作使用了FixedLengthTokenizer。不過,我認爲它只適用於固定長度格式的文件,其中每一行以適當的\ n結尾。這意味着每條線都應該一致。在我的情況下,文件就像第一條記錄行可以結束它的第1200個字符。第二行可以以另一條記錄的第n個字符結尾。所有1400個字符都不在一行中。即使對於FixedLengthTokeinzer,我們也需要指定一個LineMapper。如果我使用DefaultLinemapper,它會在一行中預期整個記錄。如果我錯了,請糾正我。 – PavanSandeep

+0

@PavanSandeep你怎麼知道記錄在1400個字符的行結束? – Thrax

+0

@PavanSandeep我更新了我的帖子,提供了更多信息 – Thrax