Перейти к основному содержимому

Поиск по CooLWJ

选择搜索范围,输入关键词后按回车。

Язык

Определение типа файла java file

При разработке на Java часто требуется определять тип файла: например, при загрузке файлов нужно проверить, соответствует ли файл пользователя допустимому типу. В этой статье подробно рассматриваются способы определения типа файла с помощью Java.

一、Определение типа файла по расширению

Самый распространённый способ определить тип файла — посмотреть на его расширение. В операционной системе большинство файлов имеют определённое расширение, например у текстовых файлов это обычно .txt,расширение файла изображения обычно — .jpg или.png и так далее。

Получить расширение файла в программе на Java очень просто, достаточно использовать String класса substring достаточно вызвать метод, код приведён ниже:

public static String getFileExtension(File file) {
    String fileName = file.getName();
    if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    } else {
        return "";
    }
}


Этот метод принимает File объект в качестве параметра, затем использовать lastIndexOf методом найти положение последней точки в имени файла, то есть начало расширения, а затем использовать substring Метод получает строку расширения файла и возвращает её. Если у файла нет расширения, возвращается пустая строка.

Для проверки этого метода можно использовать следующий код:

File file = new File("C:/path/to/file.txt");
String extension = getFileExtension(file);
System.out.println(extension);


Результат выполнения:

txt

У этого способа определения типа файла есть следующие преимущества:

  • Просто и удобно в использовании, лаконичная реализация в коде.

  • Это работает для подавляющего большинства файлов, поскольку у подавляющего большинства файлов есть расширение.

Однако у этого способа есть и некоторые недостатки:

  • Расширение файла может быть изменено, что приведёт к ошибочному результату проверки.

  • У некоторых файлов нет суффикса имени, например у исполняемых файлов без расширения.

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

Тематическое изображение к материалу об определении типа файла в Java

II. Определение типа файла по его сигнатуре

Магическое число файла — это определённые байты в самом начале файла, используемые для определения его типа. По магическому числу можно точно определить тип файла независимо от его расширения.

В Java магическое число файла можно получить, прочитав его двоичные данные.

2.1 Чтение двоичных данных файла

Мы можем использовать FileInputStream класс для чтения двоичных данных файла. Следующий метод возвращает массив байтов, содержащий двоичные данные файла:

public static byte[] readFileToByteArray(File file) throws IOException {
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(file);
        byte[] data = new byte[(int)file.length()];
        fis.read(data);
        return data;
    } finally {
        if (fis != null) {
            fis.close();
        }
    }
 }


В приведённом выше методе используется FileInputStream для открытия файла, чтения данных и сохранения их в массив байтов. Обратите внимание: после завершения чтения файла необходимо вызвать close метод закрывает файловый поток, освобождая системные ресурсы.

2.2 Определение типа файла по магическому числу

Получив двоичные данные файла, можно определить его тип. У каждого типа файлов есть определённая магическая сигнатура, по которой и определяется тип. Ниже приведены магические сигнатуры некоторых распространённых типов файлов и соответствующие способы их определения:

  • Магическое число текстового файла(.txt)— EF BB BF(в начале файла в кодировке UTF-8 есть эта последовательность байтов),для проверки можно использовать следующий способ:

    public static boolean isTextFile(byte[] data) {
      if (data.length >= 3 && data[0] == -17 && data[1] == -69 && data[2] == -65) {
          return true;
      }
      return false;
    }


  • Магическая сигнатура изображений JPEG(.jpg) — FF D8 FF,для определения можно использовать следующий способ:

    public static boolean isJPEGFile(byte[] data) {
      if (data.length >= 3 && data[0] == -1 && data[1] == -40 && data[2] == -1) {
          return true;
      }
      return false;
     }


  • Магическая сигнатура изображений PNG (.png):89 50 4E 47 0D 0A 1A 0A,для определения можно использовать следующий способ:

    public static boolean isPNGFile(byte[] data) {
      if (data.length >= 8 && data[0] == -119 && data[1] == 80 && data[2] == 78 && data[3] == 71 &&
          data[4] == 13 && data[5] == 10 && data[6] == 26 && data[7] == 10) {
          return true;
      }
      return false;
    }


При необходимости можно добавить другие типы файлов и соответствующие способы проверки магических чисел.

2.3 Полный пример

Ниже приведён полный пример определения типа файла по его магическому числу:

import java.io.File;import java.io.FileInputStream;import java.io.IOException;public class FileTypeChecker {
    public static void main(String[] args) {
        File file = new File("C:/path/to/file.jpg");
        try {
            byte[] data = readFileToByteArray(file);
            if (isJPEGFile(data)) {
                System.out.println("This is a JPEG file.");
            } else if (isPNGFile(data)) {
                System.out.println("This is a PNG file.");
            } else if (isTextFile(data)) {
                System.out.println("This is a text file.");
            } else {
                System.out.println("Unknown file type.");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static byte[] readFileToByteArray(File file) throws IOException {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            byte[] data = new byte[(int)file.length()];
            fis.read(data);
            return data;
        } finally {
            if (fis != null) {
                fis.close();
            }
        }
    }

    public static boolean isTextFile(byte[] data) {
        if (data.length >= 3 && data[0] == -17 && data[1] == -69 && data[2] == -65) {
            return true;
        }
        return false;
    }

    public static boolean isJPEGFile(byte[] data) {
        if (data.length >= 3 && data[0] == -1 && data[1] == -40 && data[2] == -1) {
            return true;
        }
        return false;
    }

    public static boolean isPNGFile(byte[] data) {
        if (data.length >= 8 && data[0] == -119 && data[1] == 80 && data[2] == 78 && data[3] == 71 &&
            data[4] == 13 && data[5] == 10 && data[6] == 26 && data[7] == 10) {
            return true;
        }
        return false;
    }
 }


Приведённый выше пример кода определяет тип файла по его сигнатуре и выводит соответствующий результат.

III、Определение типа файла с помощью сторонней библиотеки

Помимо описанных выше способов, для определения типа файла можно использовать сторонние библиотеки. В Java есть сторонние библиотеки с открытым исходным кодом, которые позволяют удобнее получать сведения о типе файла.

3.1 Tika

Tika — проект Apache Software Foundation, предоставляющий открытую библиотеку Java для разбора различных форматов файлов, включая текст, изображения, аудио, видео и другие. С помощью Tika можно извлекать метаданные файлов, в том числе тип файла.

Сначала нужно добавить зависимость библиотеки Tika. Если проект собирается с помощью Maven, можно в pom.xml добавьте в файл следующие зависимости:

<dependency>
    <groupId>org.apache.tika</groupId>
    <artifactId>tika-core</artifactId>
    <version>1.27</version>
</dependency>


Затем для определения типа файла можно использовать следующий код:

import org.apache.tika.Tika;
public class FileTypeChecker {
    public static void main(String[] args) {
        Tika tika = new Tika();
        try {
            File file = new File("C:/path/to/file.jpg");
            String fileType = tika.detect(file);
            System.out.println("File type: " + fileType);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


При выполнении приведённого выше кода будет выведен тип файла.

Tika использует различные способы определения типов файлов, включая расширения имён файлов, магические числа и другие признаки. Он также поддерживает пользовательские детекторы, позволяя при необходимости добавлять собственные правила определения типов файлов.

3.2 FileTypeDetector

Java предоставляет стандартный API для определения типа файла, а именно FileTypeDetector интерфейс и ProbeContentType класс. Реализовав этот интерфейс, можно создать собственный определитель типов файлов。

Ниже приведён пример собственного определителя типа файла:

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.spi.FileTypeDetector;

public class CustomFileTypeDetector extends FileTypeDetector {
    @Override
    public String probeContentType(Path path) throws IOException {
        String extension = getFileExtension(path.toFile());
        if ("txt".equals(extension)) {
            return "text/plain";
        } else if ("jpg".equals(extension) || "jpeg".equals(extension)) {
            return "image/jpeg";
        } else if ("png".equals(extension)) {
            return "image/png";
        } else {
            return null;
        }
    }

    private String getFileExtension(File file) {
        String fileName = file.getName();
        if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
            return fileName.substring(fileName.lastIndexOf(".") + 1);
        } else {
            return "";
        }
    }
  }

В этом примере мы определяем тип файла по его расширению и возвращаем соответствующий MIME-тип.

Чтобы использовать собственный определитель типов файлов, добавьте следующий код в точку входа программы:

File file = new File("C:/path/to/file.jpg");
Path path = file.toPath();
String fileType = Files.probeContentType(path);
System.out.println("File type: " + fileType);

При выполнении приведённого выше кода будет выведен тип файла.

Обратите внимание: для некоторых особых типов файлов, например исполняемых файлов без расширения, метод определения по расширению может быть недостаточно точным. Поэтому предпочтительнее использовать описанный выше метод на основе магического числа файла.

Четвёртое, итоги

В этой статье представлены несколько способов определения типа файла в Java. Тип файла можно определить по его расширению или по магическому числу. Сторонние библиотеки, такие как Tika, позволяют делать это удобнее. Для особых типов файлов можно реализовать собственный детектор, обеспечивающий точное определение.

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


Комментарии

Отправка

Выберите оформление

Выбранное оформление применяется ко всему сайту.