2015-10-01 3 views
1

Я работаю над разбором файла журнала размером более 2 ГБ. Требование состоит в том, чтобы напечатать некоторые предопределенные слова вместе с меткой времени в файле text/csv. Я написал приведенный ниже код и при использовании небольшого фрагмента файла журнала работает нормально, но с 2 ГБ фактического файла входного журнала я получаю ошибку из памяти. помогите мне в разрешении этого.Сплит огромные текстовые файлы с помощью java для их чтения

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.FileWriter; 
import java.sql.Time; 
import java.sql.Timestamp; 
import java.text.SimpleDateFormat; 
import java.util.Date; 


    public class MyFileParser{ 
     private static final String COMMA_STR = ","; 
     private static final String NEW_LINE_STR = "\n"; 


     public static void main(String[] args) throws IOException{ 

      String searchString = "" ; 
      String line = null; 
      boolean searchFlag = false; 
      StringBuffer sbr = new StringBuffer(); 

      FileReader reader = new FileReader("C:\\Users\\Kiran\\Desktop\\mylogs\\File.txt"); 
      FileWriter writter = new FileWriter("output.csv"); 
      BufferedReader br = new BufferedReader(reader); 


      while((line = br.readLine()) != null){ 

       if(line.contains("prompf1")){ 
        searchString= "prompf1"; 
        searchFlag = true; 
       } 

       else if (line.contains("prompf9")){ 
        searchString = "prompf9"; 
        searchFlag = true; 
       } 
        if(searchFlag){ 
         String timeStamp = ""; 
         int count = 0; 
        char[] charArray = line.toCharArray(); 
        for(int i=0 ; i <= charArray.length ; i++){ 
      // to remove [] at the begining and ending of time stamp in the file    
         if(charArray[i] == '[' || charArray[i] == ']'){ 
          count ++ ; 
         } 
           else 
         timeStamp= timeStamp+ charArray[i]; 
         if(count == 2){ 
          break ; 
         } 

        } 
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
        Date date = formatter.parse(timeStamp); 
        searchString = date + COMMA_STR+ searchString; 
        sbr.append(searchString); 
        sbr.append(NEW_LINE_STR); 
        System.out.println(searchString); 

       } 

      } 

      writter.write(sbr.toString()); 
      writter.flush(); 
      writter.close(); 

     } 


    } 

ответ

1

Вы читаете все строки в StringBuffer, а затем записывать их в одной операции. Это не нужно и вызовет проблемы с памятью, если таких строк много.

Что нужно сделать, так это написать каждую строку, как только она появится, внутри цикла считывания. Тогда вам не нужно ничего накапливать, и потребление памяти должно резко упасть.

Также у вас есть dateTime = timeStamp+ charArray[i]; в вашем коде? Не должно быть timeStamp = timeStamp+ charArray[i];? В любом случае, было бы эффективнее найти [ и ] с String#indexOf() и получить строку даты с String#substring().

И не нужно создавать новую SimpleDateFormat для каждой строки - создать ее перед циклом чтения.

+0

да, вы правы .. эта строка должна быть timeStamp = timeStamp + charArray [i]; Я буду изменять код в соответствии с вашими комментариями. Но я все еще не уверен, что эти изменения будут обрабатывать ошибку памяти или нет ... Есть ли способ разбить их на временные файлы и прочитать? – kiran

+0

@kiran Разделение файла поможет, если вам нужно будет сразу его прочитать в памяти. Но вам не нужно это делать, если вы читаете строку за строкой и сразу же пишете строки, которые вы выбираете, не добавляя их в 'StringBuffer'. – Cinnam

+0

Хорошо, позвольте мне проверить код с измененными изменениями. Я опубликую обновление здесь, если у меня возникнут проблемы. Спасибо снова. – kiran