从文件夹c ++中读取所有文件

时间:2013-12-12 13:12:49

标签: c++ file directory

我有一个从文件夹中读取图像的程序。我使用for来访问文件的所有索引并将它们存储到向量中:

    for(int i=0; i<labels.size(); i++){

    ostringstream stringStream;
    stringStream << setfill ('0') << setw (4) << i;
    num2string = stringStream.str();

    string img = "C:\\opencvAssets/detected/BioID_"+num2string+".pgm";
    //cout<< img <<" \n";
    images.push_back(imread(img, CV_LOAD_IMAGE_GRAYSCALE));  //labels.push_back(i);
}

我遇到了一些麻烦,因为文件夹中缺少某些文件。因此,对于接近是令人望而却步的。如何读取所有文件并将它们存储到矢量中?

5 个答案:

答案 0 :(得分:4)

首先,您需要扫描目录并获取文件:

您可以使用FindFirstFileFindNextFile

bool find_files(){
  WIN32_FIND_DATA FindFileData;
  string img = "C:\\opencvAssets/detected/BioID_*.pgm";
  HANDLE hFind = FindFirstFile(img.c_str(), &FindFileData);
  if(hFind == INVALID_HANDLE_VALUE){
    return false;
  } 
  else do{
    cout<<FindFileData.cFileName<<endl;
  } while (FindNextFile(hFind, &FindFileData));
  FindClose(hFind);
  return true;
}

修改

对于Linux:,您可以检查here如何迭代目录,但最好的方法是使用forkexecv运行{{1命令并使用管道获取输出。 like this

<强> EDIT2 从终端,您可以找到所有这样的文件:

find

因此,您可以通过重定向到文件或使用find path/to/dir -name 'BioID_*.pgm'fork来运行它。如果您不是一个简单的解决方案,请使用execv并重定向到文件,并使用所有已创建的文件名打开该文件。

答案 1 :(得分:3)

补丁:

if (Cv::mat m = imread(img, CV_LOAD_IMAGE_GRAYSCALE)) images.push_back(m); 

但是对于严肃的任务,请使用boost :: filesystem来限制对实际现有文件的访问。

答案 2 :(得分:3)

在Linux上你可以这样做:

1)创建DIR指针, 使用opendir()

打开目录

DIR * ptr = opendir(path_of_directory);

2)创建struct dirent指针, 使用readdir();

从目录中读取文件

struct dirent * ptr = readdir(ptr); //传递DIR指针

3)在while循环中运行上面的内容。推送向量中的数据,该向量作为参考传递给此函数或返回向量。

4)确保“。”并且“..”不是文件,所以不要在向量中推送它。 //要检查这个,你可以使用std :: strcmp(dirent_pointer-&gt; d_name,“。”)== 0 所以.. if(!std :: strcmp(ptr-&gt; d_name,“。”)== 0)

希望有所帮助

答案 3 :(得分:2)

与SHR的示例一样,您需要扫描目录并获取文件。 您可以在每个Unix平台上使用特定于Windows的实现或dirent.h中的函数。

有关Unix上dirent.h的更多信息,请参阅this question

答案 4 :(得分:1)

您可以使用boost :: filesystem。但是,这不是一个仅头文件库,您可能有要求不与外部库链接,或者这样做可能非常不方便。 在Windows上(看起来像你)我喜欢使用这个类来获得与给定模式匹配的所有文件名。

#pragma once
#include <string>
#include <vector>
#include <windows.h>

#pragma comment(lib, "User32.lib")

#undef tstring
#undef tcout
#if defined(_UNICODE) || defined(UNICODE)
#define tstring std::wstring
#define tcout std::wcout
#else
#define tstring std::string
#define tcout std::cout
#endif

class FileFinder {
  WIN32_FIND_DATA ffd;
  HANDLE _handle;

public:
  FileFinder(LPCTSTR pattern) { _handle = FindFirstFile(pattern, &ffd); }
  ~FileFinder() { FindClose(_handle); }
  const TCHAR *FindFirst() const {
    return _handle != INVALID_HANDLE_VALUE ? ffd.cFileName : nullptr;
  }
  const TCHAR *FindNext() {
    return FindNextFile(_handle, &ffd) ? ffd.cFileName : nullptr;
  }
  std::vector<tstring> GetAllNames() {
    std::vector<tstring> result;
    for (auto name = FindFirst(); name; name = FindNext())
      result.push_back(name);
    return result;
  }
};

遵循RAII范例,不会因异常而泄漏资源。 它的用法示例可能是这样的。

#include <tchar.h>
#include <iostream>
#include "FileFinder.h"

int _tmain(int argc, TCHAR *argv[]) {
  DWORD dwError = 0;

  if (argc != 2) {
    _tprintf(TEXT("\nUsage: %s <directory name>\n"), argv[0]);
    return -1;
  }

  tstring pattern(argv[1]);
  pattern.erase(pattern.find_last_not_of(TEXT("\\")) + 1);
  pattern += TEXT("\\*.pgm");
  if (pattern.length() > MAX_PATH) {
    _tprintf(TEXT("\nDirectory path is too long.\n"));
    return -1;
  }
  FileFinder finder(pattern.c_str());
  auto files = finder.GetAllNames();
  for (const auto &f : files)
    tcout << f << std::endl;
  return 0;
}