Как проверить, является ли файл обычным файлом или символической ссылкой, используя boost::filesystem?

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

Я сначала использовал это:

std::ifstream in(name.c_str());
if (!in.is_open()) {
  // throw exception!
}

но он не выдавал исключение, когда name ссылался на имя каталога.

Теперь я использую это:

if (!fs::exists(name) || fs::is_directory(name)) {
  // throw exception!
}

Но он (предположительно) не выдаст, если это символическая ссылка на каталог. То же самое верно и для этого:

if (!fs::is_regular_file(name) && !fs::is_symlink(name)) {
  // throw exception!
}

Есть ли способ лучше?


person Frank    schedule 18.04.2012    source источник


Ответы (1)


Что касается Boost.Filesystem v3, проверка того, является ли это обычным файлом, уже делает то, что вы хотите. Ниже приведен простой код:

#include <boost/filesystem.hpp>

#include <iostream>

namespace fs = boost::filesystem;

int main(int argc, char* argv[]) {
  if (argc > 1) {
    auto status = fs::status(argv[1]);

    if (status.type() == fs::regular_file)
      std::cout << argv[1] << " is a valid path." << std::endl;
    else
      std::cout << argv[1] << " is not a valid path." << std::endl;

    if (fs::symlink_status(argv[1]).type() == fs::symlink_file)
      std::cout << "It is also a symlink." << std::endl;

  } else {
    std::cerr << "A path must be given." << std::endl;
  }

  return 0;
}

Вот некоторые результаты:

% ./fstest /bin # it is a symlink path
/bin is not a valid path.
It is also a symlink.
% ./fstest /bin/ # it is a symlink path but dereferenced? (trailing /)
/bin/ is not a valid path.
% ./fstest /bin/zsoelim # it is a symlink                                                                                                               
/bin/zsoelim is a valid path.
It is also a symlink.
% ./fstest /bin/soelim # it is not a symlink 
/bin/soelim is a valid path.

Итак, как вы можете видеть, boost::filesystem::status(path) возвращает информацию о фактическом пути, является ли он символической ссылкой (переход к реальному местоположению) или нет. С другой стороны, boost::filesystem::symlink_status(path) возвращает информацию о том, является ли сам файл символической ссылкой или нет.

Дополнительную информацию можно найти в boost docs.

person Etherealone    schedule 31.12.2014