2013-02-03 104 views
0

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

+5

目前标准库没有“文件系统”的概念。您必须使用特定于平台的解决方案(或Boost.Filesystem)。 –

+0

请参阅相关:http://stackoverflow.com/questions/7377596/directory-recursion/7377707#7377707 – sehe

回答

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上测试过,所以请让我知道它是否有用。

+0

嗯,我只是复制并粘贴您的代码,并与一个小调整了起来,并工作!感谢您发布您的代码,这非常有帮助。谢谢! – lxdr

+0

不客气! :) –