2010-06-18 4 views
0

필자는 문제의 파일이 DOS/MAC 또는 UNIX 줄 끝으로 포맷되었는지 여부를 판단하기 위해 다음 방법을 작성했습니다.파일 형식을 결정하는 방법은 무엇입니까? DOS/Unix/MAC

적어도 1 개의 분명한 문제가 있습니다. 1. 첫 번째 실행에서 EOL을 얻으려고합니다. 첫 번째 1000 바이트 내로 말하면됩니다. 이것은 일어날 수도 있고 아닐 수도 있습니다.

이 내용을 검토하고 코드를 강화하고보다 일반적인 것으로 만드는 개선 사항을 제안합니다.

감사합니다.

new FileFormat().discover(fileName, 0, 1000); 

다음

public void discover(String fileName, int offset, int depth) throws IOException { 

    BufferedInputStream in = new BufferedInputStream(new FileInputStream(fileName)); 
    FileReader a = new FileReader(new File(fileName)); 

    byte[] bytes = new byte[(int) depth]; 
    in.read(bytes, offset, depth); 

    a.close(); 
    in.close(); 
    int thisByte; 
    int nextByte; 

    boolean isDos = false; 
    boolean isUnix = false; 
    boolean isMac = false; 

    for (int i = 0; i < (bytes.length - 1); i++) { 
     thisByte = bytes[i]; 
     nextByte = bytes[i + 1]; 
    if (thisByte == 10 && nextByte != 13) { 
      isDos = true; 
      break; 
     } else if (thisByte == 13) { 
      isUnix = true; 
      break; 
     } else if (thisByte == 10) { 
      isMac = true; 
      break; 
     } 
    } 
    if (!(isDos || isMac || isUnix)) { 
      discover(fileName, offset + depth, depth + 1000); 
    } else { 
     // do something clever 
    } 
} 
+1

FileReader a로 무엇을하고 계십니까? 오프셋은 무엇입니까? –

+0

아무 것도. 그것을 삭제하는 것을 잊었습니다. – JAM

답변

3

귀하의 방법이 불필요하게 복잡해 보입니다. 왜 :

switch(FileFormat.discover(fileName) { 
case WINDOWS: ... 
case MAC: ... 
case UNKNOWN: ... 
} 
+0

딘 감사합니다! – JAM

+0

우수한, 정확하게 내가 필요로하는 것, 감사합니다 순전히! – dimo414

+0

@DeanPovey 위의 내용을 사용하여 다른 파일에 인쇄 된 줄 구분 기호를 확인하려고합니다. 그러나 그것은 작동하지 않습니다. –

0

이 잘못 훨씬이있다. FileInputStream 클래스를 더 잘 이해해야합니다. read은 요청한 모든 바이트를 읽을 수 있다고 보장하지 않습니다. offset은 파일이 아니라 배열에 대한 오프셋입니다. 등등.

1

다음은 간단한 대다수 폭포에 따라 유형을 끝 라인을 추측 거친 구현 : 당신은 다음 전화로 사용할 수있는 정적 메서드에서이 문제를두고

public class FileFormat { 
    public enum FileType { WINDOWS, UNIX, MAC, UNKNOWN } 

    private static final char CR = '\r'; 
    private static final char LF = '\n'; 

    public static FileType discover(String fileName) throws IOException {  

     Reader reader = new BufferedReader(new FileReader(fileName)); 
     FileType result = discover(reader); 
     reader.close(); 
     return result; 
    } 

    private static FileType discover(Reader reader) throws IOException { 
     int c; 
     while ((c = reader.read()) != -1) { 
      switch(c) {   
      case LF: return FileType.UNIX; 
      case CR: { 
       if (reader.read() == LF) return FileType.WINDOWS; 
       return FileType.MAC; 
      } 
      default: continue; 
      } 
     } 
     return FileType.UNKNOWN; 
    } 
} 

최악의 시나리오에서 알 수없는 경우 다시 입력 :

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.util.EnumMap; 
import java.util.Map; 
import java.util.Scanner; 

class LineEndings 
{ 
    private enum ExitState 
    { 
     SUCCESS, FAILURE; 
    } 

    public enum LineEndingType 
    { 
     DOS("Windows"), MAC("Mac OS Classic"), UNIX("Unix/Linux/Mac OS X"), UNKNOWN("Unknown"); 

     private final String name; 
     private LineEndingType(String name) 
     { 
      this.name = name; 
     } 

     public String toString() 
     { 
      if (null == this.name) { 
       return super.toString(); 
      } 
      else { 
       return this.name; 
      } 
     } 
    } 

    public static void main(String[] arguments) 
    { 
     ExitState exitState = ExitState.SUCCESS; 

     File inputFile = getInputFile(); 

     if (null == inputFile) { 
      exitState = ExitState.FAILURE; 

      System.out.println("Error: No input file specified."); 
     } 
     else { 
      System.out.println("Determining line endings for: " + inputFile.getName()); 

      try { 
       LineEndingType lineEndingType = getLineEndingType(inputFile); 

       System.out.println("Determined line endings: " + lineEndingType); 
      } 
      catch (java.io.IOException exception) { 
       exitState = ExitState.FAILURE; 

       System.out.println("Error: " + exception.getMessage()); 
      } 
     } 

     switch (exitState) { 
     case SUCCESS: 
      System.exit(0); 
      break; 
     case FAILURE: 
      System.exit(1); 
      break; 
     } 
    } 

    private static File getInputFile() 
    { 
     File inputFile = null; 
     Scanner stdinScanner = new Scanner(System.in); 

     while (true) { 
      System.out.println("Enter the input file name:"); 
      System.out.print(">> "); 

      if (stdinScanner.hasNext()) { 
       String inputFileName = stdinScanner.next(); 

       inputFile = new File(inputFileName); 

       if (!inputFile.exists()) { 
        System.out.println("File not found.\n"); 
       } 
       else if (!inputFile.canRead()) { 
        System.out.println("Could not read file.\n"); 
       } 
       else { 
        break; 
       } 
      } 
      else { 
       inputFile = null; 
       break; 
      } 
     } 

     System.out.println(); 

     return inputFile; 
    } 

    private static LineEndingType getLineEndingType(File inputFile) 
     throws java.io.IOException, java.io.FileNotFoundException 
    { 
     EnumMap<LineEndingType, Integer> lineEndingTypeCount = 
      new EnumMap<LineEndingType, Integer>(LineEndingType.class); 

     BufferedReader inputReader = new BufferedReader(new FileReader(inputFile)); 

     LineEndingType currentLineEndingType = null; 

     while (inputReader.ready()) { 
      int token = inputReader.read(); 

      if ('\n' == token) { 
       currentLineEndingType = LineEndingType.UNIX; 
      } 
      else if ('\r' == token) { 
       if (inputReader.ready()) { 
        int nextToken = inputReader.read(); 

        if ('\n' == nextToken) { 
         currentLineEndingType = LineEndingType.DOS; 
        } 
        else { 
         currentLineEndingType = LineEndingType.MAC; 
        } 
       } 
      } 

      if (null != currentLineEndingType) { 
       incrementLineEndingType(lineEndingTypeCount, currentLineEndingType); 

       currentLineEndingType = null; 
      } 
     } 

     return getMostFrequentLineEndingType(lineEndingTypeCount); 
    } 

    private static void incrementLineEndingType(Map<LineEndingType, Integer> lineEndingTypeCount, LineEndingType targetLineEndingType) 
    { 
     Integer targetLineEndingCount = lineEndingTypeCount.get(targetLineEndingType); 

     if (null == targetLineEndingCount) { 
      targetLineEndingCount = 0; 
     } 
     else { 
      targetLineEndingCount++; 
     } 

     lineEndingTypeCount.put(targetLineEndingType, targetLineEndingCount); 
    } 

    private static LineEndingType getMostFrequentLineEndingType(Map<LineEndingType, Integer> lineEndingTypeCount) 
    { 
     Integer maximumEntryCount = Integer.MIN_VALUE; 

     Map.Entry<LineEndingType, Integer> mostFrequentEntry = null; 

     for (Map.Entry<LineEndingType, Integer> entry : lineEndingTypeCount.entrySet()) { 
      int entryCount = entry.getValue(); 

      if (entryCount > maximumEntryCount) { 
       mostFrequentEntry = entry; 
       maximumEntryCount = entryCount; 
      } 
     } 

     if (null != mostFrequentEntry) { 
      return mostFrequentEntry.getKey(); 
     } 
     else { 
      return LineEndingType.UNKNOWN; 
     } 
    } 
} 
관련 문제