2015-08-07 6 views
1

Я понимаю, что означает ошибка, что моя программа потребляет слишком много памяти и в течение длительного периода времени она не восстанавливается.java.lang.OutOfMemoryError: превышение верхнего предела GC при загрузке файла xlsx

Моя программа просто читает файл 6,2Mb xlsx при возникновении проблемы с памятью.

Когда я пытаюсь контролировать программу, она очень быстро достигает 1,2 ГБ в потреблении памяти, а затем она падает. Как он может достичь 1,2 ГБ при чтении 6,2 Мб файла?

Есть ли способ открыть файл в кусках? Так что его не нужно загружать в память? Или любое другое решение?

Именно эта деталь вызывает это. Но поскольку это библиотека, не следует ли ее каким-то образом обращаться с этим? Это всего 200 000 рядов с 3 колонками. В будущем мне нужно, чтобы он работал с ок. 1 мил записей и более столбцов ...

КОД:

Workbook myWorkBook; 
     Sheet mySheet; 
     if (filePath.contains(".xlsx")) { 
      // Finds the workbook instance for XLSX file 
      myWorkBook = new XSSFWorkbook(fis); 
      // Return first sheet from the XLSX workbook 
      mySheet = myWorkBook.getSheetAt(0); 
      myWorkBook.close(); // Should I close myWorkBook before I get data from it? 
     } 
+0

Сколько памяти вы даете программе? Сколько строк находится в файле Excel? Это ужасный формат, и даже фактическое приложение Excel просто задыхается, когда у вас достаточно строк. Библиотека не может перехитрить глупость формата файла. – Kayaman

+0

Звучит как один огромный файл Excel. Не похоже, что вы загружаете 6,2 МБ текстовых данных. –

+0

Это около 200 тыс. Строк, но мне нужно, чтобы он работал примерно с 1 мил. строки ... –

ответ

2

Если вы хотите работать с большими файлами XLSX, вам нужно использовать класс потокового XSSFReader. Поскольку данные являются XML, вы можете использовать StAX для эффективной обработки содержимого.

Здесь (в одну сторону), как получить Inputstream от xlsx.

OPCPackage opc = OPCPackage.open(file); 
XSSFReader xssfReader = new XSSFReader(opc); 
SharedStringsTable sst = xssfReader.getSharedStringsTable(); 
XSSFReader.SheetIterator itr = (XSSFReader.SheetIterator)xssfReader.getSheetsData(); 
while(itr.hasNext()) { 
    InputStream sheetStream = itr.next(); 
    if(itr.getSheetName().equals(sheetName)) { // Or you can keep track of sheet numbers 
     in = sheetStream; 
     return; 
    } else { 
     sheetStream.close(); 
    } 
} 

элементы являются <row> и <c> (для ячейки). Вы можете создать небольшой файл xlsx, распаковать его и изучить XML внутри для получения дополнительной информации.

Редактировать: Есть некоторые examples при обработке данных с помощью SAX, но использование StAX намного приятнее и точно так же эффективно.

+0

спасибо. Поэтому, когда я получаю InputStream, мне нужно создать свои собственные xlsx куски из него? –

+0

Я имею ввиду, что мне делать с sheetStream после этого? Есть ли у меня данные, находящиеся в файле? Я никогда не читал xlsx-файл с InputStream, поэтому я понятия не имею, чего ожидать. –

+0

Хорошо, поэтому я получаю XML, я просто не понимаю эту часть с ее распаковкой ... но хорошо, это просто моя нехватка знаний.Спасибо за ваш ответ. –

Смежные вопросы