【问题标题】:How to read in a directory of files如何读取文件目录
【发布时间】:2013-02-03 20:58:38
【问题描述】:

我正在用 C++ 编写一个程序,它将处理存储在同一目录中的大量(数千个)PPM 图像。但是,我首先需要读取像素值。它们是标准命名空间中的内置函数还是我可以导入的库,它允许我一次读取所有文件,而不假设我已经使用某种循环结构知道文件名?如果有什么不同,我会在 Mac 上编写程序。

【问题讨论】:

标签: c++


【解决方案1】:

为了避免包含boost::filesystem和所需的依赖,我最终实现了这个函数:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdexcept>

//include headers required for directory traversal
#if defined(_WIN32)
    //disable useless stuff before adding windows.h
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
#else
    #include "dirent.h"
#endif


/**
Traverses the provided directory (non-recursively) and extracts the absolute paths to all the files in it.

Doesn't support non-ASCII file names.

@param directory the absolute path to the directory
@return a vector of file names (including extension)
*/
std::vector<std::string> Filesystem::GetFilesInDirectory(const std::string &directory)
{
    std::vector<std::string> output;

#if defined(_WIN32)

    //select all files
    std::string tempDirectory = directory + "*";

    //initialize the WIN32_FIND_DATA structure
    WIN32_FIND_DATA directoryHandle = {0};

    //set the directory
    std::wstring wideString = std::wstring(tempDirectory.begin(), tempDirectory.end());
    LPCWSTR directoryPath = wideString.c_str();

    //iterate over all files
    HANDLE handle = FindFirstFile(directoryPath, &directoryHandle);
    while(INVALID_HANDLE_VALUE != handle)
    {
        //skip non-files
        if (!(directoryHandle.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
        {
            //convert from WCHAR to std::string
            size_t size = wcslen(directoryHandle.cFileName);
            std::vector<char> buffer;
            buffer.resize(2 * size + 2);
            size_t convertedCharacters = 0;
            wcstombs_s(&convertedCharacters, buffer.data(), 2 * size + 2, directoryHandle.cFileName, _TRUNCATE);
            //trim the null characters (ASCII characters won't fill the vector, since they require fewer bytes)
            //convertedCharacters includes the null character, which we want to discard
            std::string file(buffer.begin(), buffer.begin() + convertedCharacters - 1);

            //add the absolute file path
            output.emplace_back(file);
        }

        if(false == FindNextFile(handle, &directoryHandle)) break;
    }

    //close the handle
    FindClose(handle);

#else

    DIR *directoryHandle = opendir(directory.c_str());
    if (NULL != directoryHandle)
    {
        dirent *entry = readdir(directoryHandle);
        while (NULL != entry)
        {
            //skip directories and select only files (hopefully)
            //if ((DT_DIR != entry->d_type) && (DT_UNKNOWN == entry->d_type))
            if (DT_REG == entry->d_type)
            {
                output.emplace_back(entry->d_name);
            }

            //go to next entry
            entry = readdir(directoryHandle);
        }
        closedir(directoryHandle);
    }

#endif

    return output;
}

我对上述不灵活/大部分无用/依赖于平台的代码并不感到自豪,如果可能的话,我肯定会选择 BOOST。顺便说一句,它没有在 MAC 上进行测试,所以请告诉我它是否有效。

【讨论】:

  • 好吧,我刚刚复制并粘贴了您的代码,稍作调整就让它运行起来了!感谢您发布您的代码,这非常有帮助。谢谢!
猜你喜欢
  • 2011-08-26
  • 2013-02-03
  • 2012-06-25
  • 1970-01-01
  • 2012-09-16
  • 1970-01-01
  • 2015-07-10
  • 2010-10-18
相关资源
最近更新 更多