简体   繁体   English

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

[英]Read all files from a folder c++

I am having a program which reads images from a folder. 我有一个从文件夹中读取图像的程序。 I am using a for to access all the index of the files and store them into a vector: 我使用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);
}

I am having some troubles, since some of the files delibrately is missing from the folder. 我遇到了一些麻烦,因为文件夹中缺少某些文件。 Thus, for approach is prohibitive. 因此,对于接近是令人望而却步的。 How can I read all the files and store them into a vector?? 如何读取所有文件并将其存储到矢量?

First you need to scan directory and get files: 首先,您需要扫描目录并获取文件:

You can use FindFirstFile and FindNextFile 您可以使用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;
}

EDIT: 编辑:

For Linux: you can check here how to iterate directory, but the best way is to use fork and execv to run a find command and get output with pipes. 对于Linux:您可以在这里查看如何迭代目录,但最好的方法是使用forkexecv运行find命令并使用管道获取输出。 like this 像这样

EDIT2 From terminal you can find all files like this: EDIT2从终端你可以找到这样的所有文件:

find path/to/dir -name 'BioID_*.pgm'

So you can run it with redirect to file or use fork and execv . 所以你可以通过重定向到文件或使用forkexecv来运行它。 If you wan't a simple solution use it from system with redirect to a file, and open the file with all the founded file names. 如果您不是一个简单的解决方案,请在system使用它并重定向到文件,并使用所有已创建的文件名打开该文件。

a patch: 补丁:

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

but for serious tasks use boost::filesystem to restrict access to actually existing files. 但对于严肃的任务,使用boost :: filesystem来限制对实际现有文件的访问。

On Linux you can do it : 在Linux上你可以这样做:

1) Create a DIR pointer, Open the directory using opendir() 1)创建DIR指针,使用opendir()打开目录

DIR *ptr = opendir( path_of_directory ); DIR * ptr = opendir(path_of_directory);

2) Create struct dirent pointer, Read the file from directory using readdir(); 2)创建struct dirent指针,使用readdir()从目录读取文件;

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

3) Run the above in a while loop. 3)在while循环中运行上面的内容。 Push_back the data in a vector which is passed to this function as reference or return the vector. 推送向量中的数据,该向量作为参考传递给此函数或返回向量。

4) Make sure that "." 4)确保“。” and ".." is not a file, so dont push that in vector. 并且“..”不是文件,所以不要在向量中推送它。 // To check this you can use std::strcmp( dirent_pointer->d_name, "." ) == 0 so.. if( !std::strcmp( ptr->d_name, "." ) == 0 ) //要检查这个,你可以使用std :: strcmp(dirent_pointer-> d_name,“。”)== 0 so .. if(!std :: strcmp(ptr-> d_name,“。”)== 0)

Hope that helps 希望有所帮助

As in the example by SHR, you need to scan the directory and get files. 与SHR的示例一样,您需要扫描目录并获取文件。 You can use the Windows-specific implementation, or the functions in dirent.h on every Unix platform. 您可以在每个Unix平台上使用特定于Windows的实现或dirent.h中的函数。

See this question for more information about dirent.h on Unix. 有关Unix上dirent.h的更多信息,请参阅此问题

You can use boost::filesystem. 你可以使用boost :: filesystem。 However, this is not a header only library and you may have requirements not to link with external libraries or it may be very inconvenient to do so. 但是,这不是一个仅头文件库,您可能有要求不与外部库链接,或者这样做可能非常不方便。 On Windows (which looks like you are) I like to use this class to get all the filenames matching given pattern. 在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;
  }
};

It follows RAII paradigm and will not leak resources due to an exception. 它遵循RAII范例,不会因异常而泄漏资源。 Example of it's usage could be like this. 它的用法示例可能是这样的。

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM