Получить расширение файла c

Обновлено: 03.07.2024

Классы определены в пространстве имен System.IO и по сути являют собой расширение встроенных функций работы с файлами, определенными в mscorlib.dll. Для корректной работы приложений, использующих эти классы нужно включать пространство имен System.IO с помощью ключевого слова using следующим образом:

Назначение классов

Классы File и FileInfo рекомендуется применять, для операций с файлами общего типа, таких как:

  • Создание и удаление;
  • Копирование или перемещение;
  • Открытие и переименование;
  • Соединение двух файлов в одном;
  • Изменение атрибутов файла для файловой системы.

Если необходима работа со строками и отельными символами, члены классов возвращают специальный объект для этого (например, StreamWriter).

Различие между классами

Кроется в механизме взаимодействия с ними. Так, все члены класса File – статические, поэтому он позволяет производить файловые операции без необходимости создавать объект типа. Все его методы требуют указания файлового пути, то есть адресной ссылки внутри файловой системы.

Статичность методов класса File делает его использование предпочтительным в большинстве случаев, когда файловая операция – одиночная.

Основные методы:

  • Create – создает файл;
  • Delete – удаляет файл;
  • Copy – копирует файл;
  • Move – перемещает файл;
  • Exist(file_path) – проверяет существует ли файл.

Все эти методы вызываются через имя типа, как при использовании любого статического класса.

Когда существует необходимость множественных действий с конкретным файлом, то безопасней и удобней создать объектную ссылку. Такой подход заключен в классе FileInfo. Функционал этого класса заметно шире благодаря более низкому положению в иерархии наследования типов внутри System.IO.

Так, FileInfo кроме аналогичных методов класса File имеет ряд полезных свойств:

  • Length – возвращает размер файла;
  • Directory – возвращает ссылку на родительский каталог файла (объект типа DirectoryInfo);
  • DirectoryName – возвращает строку-путь к родительской дериктории;
  • Exist – проверяет существует ли файл и возвращает значение типа bool;
  • Свойство Extension – возвращает расширение файла;
  • Name и FullName: возвращают имя или полное имя файла.

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

Использование классов

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

Строка, которую используют члены классов File или FileInfo может включать себя путь к фалу или каталогу.

Примеры правильной строки:

Строка использующая путь к сетевому общему ресурсу выглядит следующим образом:

Строка с путем к файлу в неправильно введенном формате вызовет исключение.

Примеры использования

Допустим у нас есть тривиальная задача – создание файла и запись в него, разделим его на 3 этапа:

  1. Проверим существует ли уже такой файл.
  2. Если нет, то создадим его и запишем в него строку.
  3. Откроем созданный файл и прочитаем строку, записанную нами ранее.

Поскольку задача одиночная используем функционал класса File.

В качестве пути к файлу мы использовали строковую переменную со значением: c:\Examples\FileTestApp.txt. Прежде чем использовать этот код, необходимо, чтобы директория c:\Examples была создана. Проверить есть ли она невозможно средствами класса File, для этого используется класс Directory. Если каталога с таким именем не обнаружится, будет вызвано исключение.

В следующем примере описано использование функционала класса FileInfo.

Как видно из примера выше, использование ссылки на объект работы с фалом гораздо удобнее в случае если после записи или чтения из фала с ним нужно еще работать. Пример этой работы находится в блоке try/catch (копирование информации из файла в файл).

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

Учитывая строку "filename.conf" , как проверить часть расширения?

Мне нужно кроссплатформенное решение.

Этот вопрос был задан в 2008 году, но если вы пришли сюда сегодня, см. std :: filesystem :: path, который является стандартным (начиная с C ++ 17) и кроссплатформенным. Как указано ниже Рой Дантон и yves.

Вы должны позаботиться о том, чтобы имена файлов состояли из более чем одной точки. пример: c:\.directoryname\file.name.with.too.many.dots.ext не будет правильно обрабатываться strchr или find.

Мне больше всего нравится библиотека файловой системы boost, у которой есть функция расширения (пути)

Имя вашего каталога легко обрабатывается обратным поиском :). По моему личному мнению, буст-решения не следует указывать как ответы на проблемы C ++. Требовать внешней библиотеки для чего-то такого простого кажется немного глупым. @marsh: тем не менее, проблема so simple имеет свои особые случаи, особенно когда речь идет о файловых системах - концепции, для которой почти каждая основная (и не такая серьезная) операционная система имеет свою собственную интерпретацию. Рассмотрим, например, скрытые файлы linux (`/home/oren/.conf ') или случай, упомянутый @Torlack . @ 17 из 26, попытка упомянуть только свое имя пользователя должна высветить проблемы, которые могут возникнуть из-за чрезмерного упрощения того, как люди используют именование в свободной форме;) Тем не менее, решение boost никогда не следует принимать как ответ на вопрос, который не спрашивает, как это сделать с помощью boost. Это заблуждение. . ну, переносимое решение для othervise включает в себя некоторый длинный фрагмент кода, который учитывает кодировку учетных записей имен файлов или / и использует другие библиотеки (я подозреваю, что boost не реализует его с нуля, вместо этого использует другие пакеты или API, где это возможно) . Обратите внимание, что даже получение канонического пути из частичного в качестве задачи - огромная проблема с полдюжиной крайних случаев .

Это слишком простое решение?

Происходит, когда имя файла не имеет расширения, а у предыдущей папки есть. в его имени? Отвечаю на вопрос; который указывает "filename.conf", а не ваш гипотетический. По этой логике вы могли бы просто сказать return "Yes. "; вообще без проверки - это подразумевает, что решение должно работать для других входных данных. В качестве другого примера счетчика файл с именем просто «conf» без расширения также вернет «Да . » с учетом вышеизложенного. std :: filesystem :: path :: extension теперь является частью стандарт, проверьте, например, Рой Дантон ответ ниже.

Лучший способ - не писать код, который это делает, а вызывать существующие методы. В Windows PathFindExtension метод, наверное, самый простой.

Так почему бы вам не написать свой собственный?

Хорошо, возьмем пример strrchr, что произойдет, если вы используете этот метод со следующей строкой «c: \ program files \ AppleGate.Net \ readme»? Является ли ".Net \ readme" расширением? Легко написать что-то, что работает для нескольких примеров, но может быть намного сложнее написать что-то, что работает для всех случаев.

Эта функция (в Windows 7) некорректно обрабатывает "file.i i". Да, это действительно так, обратите внимание на пробел. Он спросил об извлечении расширения из файла, а не полного пути. Кроме того, функция Windows API не будет хорошим ответом. Это абсолютно не ответ, а комментарий. -1 за предоставление решения для конкретной платформы, когда OP запросил переносимое решение. +1 От меня. Этот вопрос является первым, который возникает, когда вы гуглите "mfc get file extension", и ваш самый простой ответ, который работает.

Предполагая, что у вас есть доступ к STL:

Изменить: это кроссплатформенное решение, поскольку вы не упомянули платформу. Если вы специально используете Windows, вы захотите использовать специальные функции Windows, упомянутые другими в потоке.

+1, это простейшее решение, если у вас есть файл в виде строки, а не пути!

Кто-то еще упомянул усиление, но я просто хотел добавить код для этого:

+1, спасибо за размещение фактического фрагмента кода с использованием boost. Не забудьте установить связь с -lboost_filesystem , и вы получите рабочее решение.

В C ++ 17 и его std::filesystem::path::extension (библиотека является преемником boost :: filesystem), вы бы сделали свое утверждение более выразительным, чем использование, например, std::string .

На самом деле STL может сделать это без большого количества кода, я советую вам немного узнать о STL, потому что он позволяет вам делать некоторые необычные вещи, в любом случае это то, что я использую.

Это решение всегда будет возвращать расширение даже для таких строк, как «this.a.b.c.d.e.s.mp3», если оно не может найти расширение, которое вернет «».

Собственно, самый простой способ -

Следует помнить одну вещь: если '.' не существует в имени файла, ext будет NULL .

Это не было бы идеальным решением для скрытых файлов UNIX, начинающихся с точки.

Я сегодня сам наткнулся на этот вопрос, хотя у меня уже был рабочий код, я понял, что в некоторых случаях он не сработает.

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

Некоторые ответы включали метод, который я использовал в первую очередь (поиск последнего «.»), Но я вспомнил, что в Linux скрытые файлы / папки начинаются с «.». Таким образом, если файл скрыт и не имеет расширения, для расширения будет использовано полное имя файла. Чтобы избежать этого, я написал этот фрагмент кода:

Я не тестировал это полностью, но думаю, что это должно сработать.

Использование std :: string find / rfind решает ЭТУ проблему, но если вы много работаете с путями, вам следует взглянуть на boost :: filesystem :: path, поскольку это сделает ваш код намного чище, чем возня с индексами / итераторами необработанных строк.

Я предлагаю boost, поскольку это высококачественная, хорошо протестированная (с открытым исходным кодом и коммерчески) бесплатная и полностью переносимая библиотека.

Для строк типа массива char вы можете использовать это:

Может обрабатывать пути к файлам в дополнение к именам файлов. Работает как с C, так и с C ++. И кроссплатформенность.

Вы можете уменьшить количество условий. Используйте strlen(extension) в условии for . Затем, если символы не совпадают, верните false. За пределами цикла for возвращается истина.

Вы можете использовать приведенный выше код в своем приложении на C ++, как показано ниже:

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

Это только Windows (Platform SDK)

Это решение, которое я придумал. Затем я заметил, что это похоже на то, что опубликовал @serengeor.

Он работает с std::string и find_last_of , но основная идея также будет работать, если будет изменена для использования массивов char и strrchr . Он обрабатывает скрытые файлы и дополнительные точки, представляющие текущий каталог. Он не зависит от платформы.

Я использую эти две функции для получения расширения и имени файла без расширения :

у меня есть список файлов, хранящийся в .log в следующий синтаксис:

Я хочу извлечь имя и расширение из этих файлов. Можете ли вы привести пример простого способа сделать это?

чтобы извлечь имя файла без расширения, используйте boost::filesystem:: path:: stem вместо уродливого std:: string:: find_last_of(".")

если вы хотите безопасный способ (т. е. переносимый между платформами и не поставив предположений по пути), я бы рекомендовал использовать boost::filesystem .

это выглядело бы как-то так:

затем вы можете извлечь различные данные из этого пути. вот документация объекта path.

кстати: также помните, что для того, чтобы использовать путь, как

вам нужно бежать \ в строке дословно:

или использовать / вместо:

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

вы должны будете прочитать ваши имена файлов из файла в std::string . Вы можете использовать оператор извлечения строки std::ostream . После того, как у вас есть имя файла в std::string можно использовать std::string::find_last_of метод поиска последнего разделителя.

что-то вроде этого:

  1. читать std::string из входного потока ( std::ifstream ), каждый экземпляр будет полный путь
  2. сделать find_last_of на строку \
  3. извлеките подстроку из этой позиции до конца, теперь это даст вам имя файла
  4. сделать find_last_of на . , и подстрока с обеих сторон даст вам имя + расширение.

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

а затем замените косую черту на предпочтительную косую черту для ОС. Полезно, если он постоянно развертывается между Linux/Windows.

для linux или unix машин, ОС имеет две функции, связанные с пути и имена файлов. используйте man 3 basename, чтобы получить дополнительную информацию об этих функциях. Преимущество использования системной функциональности заключается в том, что вам не нужно устанавливать boost или писать свои собственные функции.

пример кода из man-страницы:

из-за неконстантного типа аргумента функции basename() это немного не прямолинейно используя это внутри кода C++. Вот простой пример из моей базы кода:

использование new / delete не является хорошим стилем. Я мог бы положить его в try / catch блок на случай, если что-то произошло между двумя вызовами.

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

спросил(а) 2013-03-22T10:32:00+04:00 8 лет, 8 месяцев назад ответил(а) 2013-03-22T10:35:00+04:00 8 лет, 8 месяцев назад

Используйте метод Path.GetExtension, предоставляемый инфраструктурой.

Расширение указанного пути (включая период "."), Или null, или String.Empty. Если путь равен null, GetExtension возвращает значение null. Если в пути нет информации о расширении, GetExtension возвращает String.Empty.

Вы получите .exe

ответил(а) 2013-03-22T10:33:00+04:00 8 лет, 8 месяцев назад

Вы пытались использовать что-то вроде

Расширение указанного пути (включая период "."), Или null, или String.Empty. Если путь равен null, GetExtension возвращает значение null. Если в пути нет информации о расширении, GetExtension возвращает String.Empty.

ответил(а) 2013-03-22T10:33:00+04:00 8 лет, 8 месяцев назад

Расширение указанного пути (включая период "."), Или null , или String.Empty . Если путь равен null , GetExtension возвращает значение null . Если в пути нет информации о расширении, GetExtension возвращает String.Empty .

Path.GetExtension проверяет весь путь для недопустимых символов. Этот шаг является избыточным, если вы уже знаете, что ваш путь действителен, например, когда вы получили его из Directory.GetFile . Он ищет разделитель char. AltDirectorySeparatorChar реализации для DirectorySeparatorChar , AltDirectorySeparatorChar и VolumeSeparatorChar .

ответил(а) 2013-03-22T10:33:00+04:00 8 лет, 8 месяцев назад

Вы можете использовать класс System.IO.FileInfo.
Он имеет свойство под названием Extension, которое дает строку, содержащую часть расширения имени файла.

ответил(а) 2013-03-22T10:38:00+04:00 8 лет, 8 месяцев назад

Альтернативный способ найти это.

Так, например, если мы хотим взять все txt файлы из каталога, мы можем сделать вот так:

Читайте также: