Прежде всего, я бы попытался объяснить, что мне нужно делать.
Мне нужно прочитать файл (размер которого может быть от 1 байта до 2 ГБ), максимум 2 ГБ, потому что я пытаюсь использовать MappedByteBuffer для быстрого чтения. Возможно, позже я попытаюсь прочитать файл кусками, чтобы прочитать файлы произвольного размера.
Когда я читаю файл, я конвертирую его байты и преобразую их (используя кодировку ASCII ) в символы, которые позже я помещаю в StringBuilder , а затем помещаю этот String Builder в ArrayList
Однако мне также нужно сделать следующее:
Пользователь может ввести blockSize
, которое представляет собой число символов, которые я должен прочитать в StringBuilder (в основном это число байтов файла, преобразованных в символы)
После того, как я собрал определяемое пользователем количество символов, я создаю копию String Builder и помещаю ее в список массивов
Все шаги выполняются для каждого прочитанного символа. Проблема в String Builder, поскольку, если файл большой (<500 МБ), я получаю исключение <strong>OutOfMemoryError .
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.lang.AbstractStringBuilder.<init>(AbstractStringBuilder.java:45)
at java.lang.StringBuilder.<init>(StringBuilder.java:80)
at java.lang.StringBuilder.<init>(StringBuilder.java:106)
at borrows.wheeler.ReadFile.readFile(ReadFile.java:43)
Java Result: 1
Я публикую свой код, возможно, кто-то может предложить улучшения этого кода или предложить несколько альтернатив.
public class ReadFile {
//matrix block size
public int blockSize = 100;
public int charCounter = 0;
public ArrayList readFile(File file) throws FileNotFoundException, IOException {
FileChannel fc = new FileInputStream(file).getChannel();
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, (int) fc.size());
ArrayList characters = new ArrayList();
int counter = 0;
StringBuilder sb = new StringBuilder();//blockSize-1
while (mbb.hasRemaining()) {
char charAscii = (char)mbb.get();
counter++;
charCounter++;
if (counter == blockSize){
sb.append(charAscii);
characters.add(new StringBuilder(sb));//new StringBuilder(sb)
sb.delete(0, sb.length());
counter = 0;
}else{
sb.append(charAscii);
}
if(!mbb.hasRemaining()){
characters.add(sb);
}
}
fc.close();
return characters;
}
}
EDIT :
Я делаю преобразование Барроуза-Уилера. Там я должен прочитать каждый файл, а затем по размеру блока создать столько матриц, сколько нужно. ну, я верю, что вики объяснит лучше меня:
http://en.wikipedia.org/wiki/Burrows%E2%80%93Wheeler_transform