Търся многоредов шаблон в огромен файл и ако го намеря, трябва да заменя съдържанието. Искам да постигна това по ефективен за паметта начин. Текущата ми реализация чете текст от файл на парчета в 4096 байта. След това прилага regex search replace и записва резултата в изходния поток на буфера. Това ми дава някои подобрения на паметта, като не зареждам целия файл в паметта, но правя много IO с map/flush повиквания. Имам нужда от предложения за по-нататъшно подобряване на моя код. Освен това алгометърът се проваля, ако моделът, който ще се търси, е разделен на съседни части. Някакви идеи за това как ефективно търсене-замяна на текста, който се разделя на съседни части. Предположения: Текстът за търсене винаги е по-малък от 4096 байта.
public void searchAndReplace (String inputFilePath, String outputFilePath) {
Pattern HEADER_PATTERN = Pattern.compile("<a [^>]*>[^(</a>)]*</a>", Pattern.DOTALL);
Charset UTF8 = Charset.forName("UTF-8");
File outputFile = new File(outputfilepath);
if (!outputFile.exists()) {
outputFile.createNewFile();
}
FileInputStream inputStream = new FileInputStream(new File(inputfilepath));
FileOutputStream outputStream = new FileOutputStream(outputFile);
FileChannel inputChannel = inputStream.getChannel();
final long length = inputChannel.size();
long pos = 0;
while (pos < length) {
int remaining = (int)(length - pos) > 4096 ? 4096 : (int)(length - pos);
MappedByteBuffer map = inputChannel.map(FileChannel.MapMode.READ_ONLY, pos, remaining);
CharBuffer cbuf = UTF8.newDecoder().decode(map);
Matcher matcher = HEADER_PATTERN.matcher(cbuf);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, "Some text");
}
matcher.appendTail(sb);
outputStream.write(sb.toString().getBytes());
outputStream.flush();
pos = pos + 4096;
}
inputStream.close();
outputStream.close();
}
(, <, /, a, > or )
. Мисля, че всъщност искаш"<a [^>]*>.*?</a>"
- person Bohemian♦   schedule 29.03.2015