проверить, относится ли файл к определенному типу

Я хочу проверить, все ли файлы в каталоге имеют определенный тип. Что я сделал до сих пор.

private static final String[] IMAGE_EXTS = { "jpg", "jpeg" };

private void validateFolderPath(String folderPath, final String[] ext) {

        File dir = new File(folderPath);

        int totalFiles = dir.listFiles().length;

        // Filter the files with JPEG or JPG extensions.
        File[] matchingFiles = dir.listFiles(new FileFilter() {
            public boolean accept(File pathname) {
                return pathname.getName().endsWith(ext[0])
                        || pathname.getName().endsWith(ext[1]);
            }
        });

        // Check if all the files have JPEG or JPG extensions
        // Terminate if validation fails.
        if (matchingFiles.length != totalFiles) {
            System.out.println("All the tiles should be of type " + ext[0]
                    + " or " + ext[1]);
            System.exit(0);
        } else {
            return;
        }

    }

Это прекрасно работает, если имя файла имеет расширение, такое как {file.jpeg, file.jpg}. Это не работает, если файлы не имеют расширений {file1 file2}. Когда я делаю следующее в своем терминале, я получаю:

$ file folder/file1 
folder/file1: JPEG image data, JFIF standard 1.01

Обновление 1:

Я попытался получить магические числа файла, чтобы проверить, является ли он JPEG:

for (int i = 0; i < totalFiles; i++) {
            DataInputStream input = new DataInputStream(
                    new BufferedInputStream(new FileInputStream(
                            dir.listFiles()[i])));

            if (input.readInt() == 0xffd8ffe0) {
                isJPEGFlag = true;
            } else {
                isJPEGFlag = false;
                try {
                    input.close();
                } catch (IOException ignore) {
                }
                System.out.println("File not JPEG");
                System.exit(0);
            }
        }

Я столкнулся с другой проблемой. В моей папке есть несколько файлов .DS_Store. Любая идея, как игнорировать их?


person yesh    schedule 11.10.2012    source источник
comment
Вы имеете в виду, как проверить, является ли файл без расширения файлом JPEG или нет?   -  person Kalpak Gadre    schedule 11.10.2012
comment
Тот факт, что имя файла заканчивается определенным расширением, не означает, что содержимое этого файла соответствует его имени. Вам нужно прочитать содержимое файла (по крайней мере, первые N байтов) - это то, что делает команда "файл"...   -  person Art Swri    schedule 11.10.2012
comment
Кто-нибудь заметил, когда у Windows была склонность создавать изображения JPEG с расширением .jpe? AFAIR сохранял изображения прямо из IE, но моя память немного туманна.   -  person Andrew Thompson    schedule 11.10.2012
comment
Изменения выглядят нормально, за исключением того, что я бы обернул ваши потоки блоками, чтобы соединения закрывались после чтения каждого файла.   -  person emalamisura    schedule 12.10.2012


Ответы (3)


Во-первых, расширения файлов не являются обязательными, файл без расширения вполне может быть действительным файлом JPEG.

Проверьте RFC для формата JPEG, форматы файлов обычно начинаются с некоторой фиксированной последовательности байтов для определения формата файла. Это определенно не так просто, но я не уверен, что есть лучший способ.

Короче говоря, вы должны открыть каждый файл, прочитать первые n байтов в зависимости от формата файла, проверить, соответствуют ли они ожидаемому формату файла. Если они это сделают, это действительный файл JPEG, даже если он имеет расширение exe или даже если он не имеет никакого расширения.

person Kalpak Gadre    schedule 11.10.2012
comment
Я сделал некоторое обновление. Скажите, правильно ли я иду? - person yesh; 12.10.2012

Для файлов JPEG вы можете выполнить проверку магического числа в заголовке файла:

static bool HasJpegHeader(string filename)
{
    using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open)))
    {
        UInt16 soi = br.ReadUInt16();
        UInt16 jfif = br.ReadUInt16();      
        return soi == 0xd8ff && jfif == 0xe0ff;
    }
}

Более полный метод здесь, который также охватывает EXIFF: C# Как проверить, является ли файл jpeg?

person emalamisura    schedule 11.10.2012
comment
Есть ли у JPEG формальный заголовок? ваш подход интересен, но не уверен, что он будет работать для JPEGS. - person yesh; 11.10.2012
comment
Я сделал некоторое обновление. Скажите, правильно ли я иду? - person yesh; 12.10.2012

Одна хорошая (хотя и дорогая) проверка правильности изображения, понятного J2SE, состоит в том, чтобы попытаться ImageIO.read(File) его. Этот метод генерирует несколько весьма полезных исключений, если не находит изображения в предоставленном файле.

person Andrew Thompson    schedule 11.10.2012
comment
Я сделал некоторое обновление. Скажите, правильно ли я иду? - person yesh; 12.10.2012