Расширение файла с учетом регистра и проверка существования

Мне нужно проверить, существует ли файл. Что может быть выполнено методом File#exists(). Но эта проверка существования чувствительна к регистру. Я имею в виду, если у меня есть имя файла some_image_file.jpg в коде, но если физически это файл some_image_file.JPG, то этот метод говорит, что файл не существует. Как я могу проверить существование файла с учетом регистра к расширению и получить фактическое имя файла?

В моем сценарии у меня есть файл excel. Каждая строка содержит метаданные для файлов и имя файла. В некоторых случаях у меня есть только имя файла или в других случаях у меня может быть полный путь. Я обозначаю строку как документ.

Эти файлы размещаются на сервере. Моя работа состоит в том, чтобы

  • Прочитайте файл Excel построчно и перечислите все документы.
  • Выньте имя файла или путь к файлу.
  • Создайте полный путь к файлу.
  • Проверьте, существует файл или нет.
  • Проверить другие метаданные/информацию, представленные в документе.
  • Загрузите файл.

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

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

Я запускаю приложение на сервере unix.

Поскольку расширения файлов не совпадают, поэтому File#exists() дает false, и в конечном итоге мой код выдает исключение.

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

Я хочу

  • Чтобы взять полный путь к файлу.
  • Проверьте, существует файл или нет.
  • Если его нет то
  • Проверьте существование файла, изменив регистр расширения.
  • Если он не существует после преобразования регистра, сгенерируйте исключение.
  • Если он существует, верните фактическое имя файла или путь к файлу.

Если имя файла имеет расширение типа .Jpg, не знаю, что делать! Должен ли я проверить это, переставив его, изменив регистр?


person Tapas Bose    schedule 29.11.2012    source источник
comment
Просто чтобы проверить - вы работаете в Windows, верно? (В файловой системе, чувствительной к регистру, вопрос не имеет особого смысла.) Я только что попробовал использовать File.exists сам, намеренно указав неправильный регистр имени файла, и он работает нормально...   -  person Jon Skeet    schedule 29.11.2012
comment
@JonSkeet Я работаю в UNIX.   -  person Tapas Bose    schedule 29.11.2012
comment
Хорошо, это имеет больше смысла с точки зрения поведения File.exists, но меньше смысла с точки зрения того, почему вы хотите это сделать. Откуда вы берете имя файла? На какую информацию можете вы положиться?   -  person Jon Skeet    schedule 29.11.2012
comment
@JonSkeet Я получаю имя файла, анализируя файл excel. По моему требованию мне нужно прочитать файл excel, взять имя файла и другие метаданные, проверить существование файла и загрузить файл вместе с метаданными на сервер содержимого. В некоторых случаях файл физически присутствует в формате .JPG, но в Excel это .jpg, также верно и обратное. Поэтому, когда я читаю имя файла из файла excel как .jpg, а файл на самом деле имеет .JPG, и я проверяю, существует ли файл или нет, я получаю ложь.   -  person Tapas Bose    schedule 29.11.2012
comment
Так является ли имя файла, которое вы читаете, абсолютным? Как узнать, в каком каталоге искать? (Было бы очень полезно, если бы вы обновили вопрос со всей такой информацией - вам будет намного сложнее помочь, если нам придется запрашивать информацию одну за другой.)   -  person Jon Skeet    schedule 29.11.2012
comment
@JonSkeet Я обновил свой вопрос, объясняя весь сценарий.   -  person Tapas Bose    schedule 29.11.2012


Ответы (3)


Вы можете получить имена файлов в папке с помощью

File.list() 

и проверить имена с помощью

equalsIgnoreCase()

Или попробуйте http://commons.apache.org/io/ и используйте

FileNameUtils.directoryContains(final String canonicalParent, final String canonicalChild)
person Romczyk    schedule 29.11.2012
comment
Спасибо. Но у меня нет имени папки и файла может не быть. - person Tapas Bose; 29.11.2012
comment
Вы имеете в виду, что вы проверяете полное имя файла, вроде D:\test\base\some_image_file.JPEG? - person Romczyk; 29.11.2012
comment
Да что-то подобное. Но в этом случае можно извлечь имя папки с помощью небольших манипуляций со строками. Но в папке может быть 30000 и более файлов. Так что в этом случае для каждого файла мне нужно перечислить все эти файлы! - person Tapas Bose; 29.11.2012
comment
Вы также можете попробовать commons.apache.org/io и использовать FileNameUtils.directoryContains(final String canonicalParent, окончательная строка canonicalChild) - person Romczyk; 29.11.2012

Таким образом я решил проблему:

public String getActualFilePath() {
    File givenFile = new File(filePath);
    File directory = givenFile.getParentFile();

    if(directory == null || !directory.isDirectory()) {
        return filePath;
    }


    File[] files = directory.listFiles();
    Map<String, String> fileMap = new HashMap<String, String>();

    for(File file : files) {                        
        if(file.isDirectory()){
            continue;
        }

        String absolutePath = file.getAbsolutePath();
        fileMap.put(absolutePath, StringUtils.upperCase(absolutePath));
    }

    int noOfOcc = 0;
    String actualFilePath = "";

    for(Entry<String, String> entry : fileMap.entrySet()) {
        if(filePath.toUpperCase().equals(entry.getValue())) {
            actualFilePath = entry.getKey();
            noOfOcc++;
        }
    }

    if(noOfOcc == 1) {
        return actualFilePath;
    }

    return filePath;
}

Здесь filePath — это полный путь к файлу.

person Tapas Bose    schedule 04.03.2013

Каноническое имя возвращает имя с учетом регистра. Если он возвращает строку, отличную от имени файла, который вы ищете, файл существует с другим регистром.

Итак, проверьте, существует ли файл или отличается ли его каноническое имя.

public static boolean fileExistsCaseInsensitive(String path) {
    try {
        File file = new File(path);
        return file.exists() || !file.getCanonicalFile().getName().equals(file.getName());
    } catch (IOException e) {
        return false;
    }
}
person Julien Feniou    schedule 23.11.2017