2012-10-10 2 views
0

형식이 올바른 출력을 새로운 텍스트 파일에 쓰려면 올바르게 포맷하려면 큰 텍스트 파일 (약 600MB)을 처리해야합니다. 문제는 새로운 파일에 내용을 쓰는 것이 약 6.2 MB에서 멈추는 것입니다. 여기에 코드입니다 :Java - 텍스트 파일 작성을 완료 할 수 없습니다.

/* Analysis of the text in fileName to see if the lines are in the correct format 
    * (Theme\tDate\tTitle\tDescription). If there are lines that are in the incorrect format, 
    * the method corrects them. 
    */ 
    public static void cleanTextFile(String fileName, String destFile) throws IOException { 
     OutputStreamWriter writer = null; 
     BufferedReader reader = null; 

     try { 
      writer = new OutputStreamWriter(new FileOutputStream(destFile), "UTF8"); 
     } catch (IOException e) { 
      System.out.println("Could not open or create the file " + destFile); 
     } 

     try { 
      reader = new BufferedReader(new FileReader(fileName)); 
     } catch (FileNotFoundException e) { 
      System.out.println("The file " + fileName + " doesn't exist in the folder."); 
     } 

     String line; 
     String[] splitLine; 
     StringBuilder stringBuilder = new StringBuilder(""); 

     while ((line = reader.readLine()) != null) { 
      splitLine = line.split("\t"); 
      stringBuilder.append(line); 

      /* If the String array resulting of the split operation doesn't have size 4, 
      * then it means that there are elements of the news item missing in the line 
      */ 
      while (splitLine.length != 4) { 
       line = reader.readLine(); 
       stringBuilder.append(line); 

       splitLine = stringBuilder.toString().split("\t"); 
      } 
      stringBuilder.append("\n"); 
      writer.write(stringBuilder.toString()); 
      stringBuilder = new StringBuilder(""); 

      writer.flush(); 
     } 

     writer.close(); 
     reader.close(); 

    } 

이미 답을 검토 한 결과,하지만 문제는 일반적으로 작가가 폐쇄되지 않는 사실 또는 flush() 방법의 부재와 관련이 있습니다. 따라서 BufferedReader에 문제가 있다고 생각합니다. 내가 뭘 놓치고 있니? 이 루프에서

+1

..? – OmniOwl

+0

나는 처음에는 특정 횟수만큼 (정확히는 500 회) 플러시를 시도했다.주기의 모든 반복에서 플러시를 피하기를 희망했지만 작동하지 않았다. 플러시를 사용하는 올바른 방법은 무엇입니까? – Judas

+0

입력 파일 (600MB의 레코드)에서 최소한 일부 레코드를 제공 할 수 있습니까? – Jagger

답변

3

봐 :

while (splitLine.length != 4) { 
    line = reader.readLine(); 
    stringBuilder.append(line); 

    splitLine = stringBuilder.toString().split("\t"); 
} 

당신이 이제까지 splitLine 5 개 항목으로 끝낼 경우, 당신은 영원히 데이터를 읽는 계속 단지거야 ... 당신도 때를 통지하지 않습니다 파일 끝에 도달했습니다. nullStringBuilder에 계속 추가합니다. 나는 이것이 일어나고 있는지 (우리는 당신의 데이터가 어떻게 생겼는지는 모르지만) 확실하게 실현 가능하다는 것을 알지 못합니다.

도 (당신은 또한 자원을 닫기위한 try/finally 블록을 사용한다, 그러나 그것은 별도의 문제이다.)이 FileOutputStream에 밖으로

+0

그게 어리석은 실수 였어. 방금 연산자를'! ='에서'<'로 변경했습니다. 감사. – Judas

+1

@Judas : 그 것이 실제로는 올바른 수정이 아니라는 것이 확실합니다. 파일의 끝에 도달하면 여전히 * 반복됩니다. 문제를 진단했지만 해결책에 대해 더 신중하게 생각해야 할 수도 있습니다. –

+0

모든 내용을 파일에 기록 했으므로 파일의 끝에 문제가 없습니다. 그래도 또 다른 문제가 생겼지 만 지금은 괜찮을거야. 다시 한 번 감사드립니다! – Judas

0

분리 그 자체가 변수입니다으로하고 닫습니다 :

FileOutputStream fos = new FileOutputStream(destFile); 
writer = new OutputStreamWriter(fos); 

    ... 

writer.flush(); 
fos.flush(); 
0
  1. try/catch가 잘 코딩되지 않았으므로 오류가 발생할 경우 프로세스가 계속 진행됩니다. 당신이 line.substring (B, E)로 취득 부품을 추가 String.split()

  2. 대신 자신의 파서 line.indexOf('\t',from)를 사용

    stringBuilder.setLength(0); 
    
  3. 에 의해

    stringBuilder = new StringBuilder(""); 
    

    을 대체 할 수

  4. 목록 < 문자열>

  5. 올바른 문자로 된 PrintStream을 사용하십시오 acter 세트, 목록에서 데이터를 소비, 4 정보 4 쓰기 두 개의 매개 변수
  6. 와 생성자를 사용하는 경우는 list.size()> = 당신이 플러시 사용하여 제대로 시도해 봤어 4