Как определить формат файла?DOS / Unix / MAC - PullRequest
0 голосов
/ 18 июня 2010

Я написал следующий метод, чтобы определить, форматируется ли рассматриваемый файл в DOS / MAC или в конце строки UNIX.

Я вижу по крайней мере 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
    }
}

Ответы [ 3 ]

3 голосов
/ 18 июня 2010

Ваш метод кажется излишне сложным.Почему бы и нет:

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;
    }
}

, который помещает это в статический метод, который затем можно вызвать и использовать как:

switch(FileFormat.discover(fileName) {
case WINDOWS: ...
case MAC: ...
case UNKNOWN: ...
}
1 голос
/ 22 июня 2010

Вот грубая реализация, которая угадывает тип окончания строки на основе простого большинства и возвращается к неизвестному в худшем случае:

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;
        }
    }
}
0 голосов
/ 18 июня 2010

В этом много чего плохого.Вам нужно лучше понять класс FileInputStream.Обратите внимание, что read не гарантирует чтение всех запрошенных вами байтов.offset - это смещение в массиве, а не в файле.И так далее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...