¿Cómo se obtiene una lista de archivos dentro de un directorio para que cada uno pueda ser procesado?¿Cómo obtengo una lista de archivos en un directorio en C++?
Respuesta
El estándar C++ no proporciona una forma de hacerlo. Pero boost::filesystem
puede hacer eso: http://www.boost.org/doc/libs/1_37_0/libs/filesystem/example/simple_ls.cpp
Resolver esto requerirá una solución específica de la plataforma. Busque opendir() en Unix/Linux o FindFirstFile() en Windows. O bien, hay muchas bibliotecas que manejarán la parte específica de la plataforma para usted.
Aquí hay un ejemplo en C en Linux. Eso si, estás en Linux y no le importa hacer este pequeño fragmento en ANSI C
#include <dirent.h>
DIR *dpdf;
struct dirent *epdf;
dpdf = opendir("./");
if (dpdf != NULL){
while (epdf = readdir(dpdf)){
printf("Filename: %s",epdf->d_name);
// std::cout << epdf->d_name << std::endl;
}
}
closedir(dpdf);
Si estás en Windows & usando MSVC, la biblioteca MSDN tiene sample code that does this.
Y aquí está la código de ese enlace:
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
void ErrorHandler(LPTSTR lpszFunction);
int _tmain(int argc, TCHAR *argv[])
{
WIN32_FIND_DATA ffd;
LARGE_INTEGER filesize;
TCHAR szDir[MAX_PATH];
size_t length_of_arg;
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError=0;
// If the directory is not specified as a command-line argument,
// print usage.
if(argc != 2)
{
_tprintf(TEXT("\nUsage: %s <directory name>\n"), argv[0]);
return (-1);
}
// Check that the input path plus 2 is not longer than MAX_PATH.
StringCchLength(argv[1], MAX_PATH, &length_of_arg);
if (length_of_arg > (MAX_PATH - 2))
{
_tprintf(TEXT("\nDirectory path is too long.\n"));
return (-1);
}
_tprintf(TEXT("\nTarget directory is %s\n\n"), argv[1]);
// Prepare string for use with FindFile functions. First, copy the
// string to a buffer, then append '\*' to the directory name.
StringCchCopy(szDir, MAX_PATH, argv[1]);
StringCchCat(szDir, MAX_PATH, TEXT("\\*"));
// Find the first file in the directory.
hFind = FindFirstFile(szDir, &ffd);
if (INVALID_HANDLE_VALUE == hFind)
{
ErrorHandler(TEXT("FindFirstFile"));
return dwError;
}
// List all the files in the directory with some info about them.
do
{
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
_tprintf(TEXT(" %s <DIR>\n"), ffd.cFileName);
}
else
{
filesize.LowPart = ffd.nFileSizeLow;
filesize.HighPart = ffd.nFileSizeHigh;
_tprintf(TEXT(" %s %ld bytes\n"), ffd.cFileName, filesize.QuadPart);
}
}
while (FindNextFile(hFind, &ffd) != 0);
dwError = GetLastError();
if (dwError != ERROR_NO_MORE_FILES)
{
ErrorHandler(TEXT("FindFirstFile"));
}
FindClose(hFind);
return dwError;
}
void ErrorHandler(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL);
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf)/sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
Tienes que usar las llamadas al sistema operativo (por ejemplo, la API Win32) o un contenedor alrededor de ellas. Tiendo a usar Boost.Filesystem ya que es una interfaz superior en comparación con el desastre que es la API de Win32 (además de ser multiplataforma).
Si está buscando utilizar la API Win32, Microsoft tiene una lista of functions y examples en msdn.
Esto es lo que yo uso:
/* Returns a list of files in a directory (except the ones that begin with a dot) */
void GetFilesInDirectory(std::vector<string> &out, const string &directory)
{
#ifdef WINDOWS
HANDLE dir;
WIN32_FIND_DATA file_data;
if ((dir = FindFirstFile((directory + "/*").c_str(), &file_data)) == INVALID_HANDLE_VALUE)
return; /* No files found */
do {
const string file_name = file_data.cFileName;
const string full_file_name = directory + "/" + file_name;
const bool is_directory = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
if (file_name[0] == '.')
continue;
if (is_directory)
continue;
out.push_back(full_file_name);
} while (FindNextFile(dir, &file_data));
FindClose(dir);
#else
DIR *dir;
class dirent *ent;
class stat st;
dir = opendir(directory);
while ((ent = readdir(dir)) != NULL) {
const string file_name = ent->d_name;
const string full_file_name = directory + "/" + file_name;
if (file_name[0] == '.')
continue;
if (stat(full_file_name.c_str(), &st) == -1)
continue;
const bool is_directory = (st.st_mode & S_IFDIR) != 0;
if (is_directory)
continue;
out.push_back(full_file_name);
}
closedir(dir);
#endif
} // GetFilesInDirectory
El código de Windows no funciona cuando se compila con Unicode habilitado. Lo solucioné llamando explícitamente a las funciones ASCII, que tienen una 'A' adjuntada. Específicamente, use WIN32_FIND_DATAA, FindFirstFileA y FindNextFileA y todo funciona. Obviamente, este es un truco, pero yo vivo en un país de habla inglesa, así que funciona para mí. : 0 Gracias por el código de ejemplo! – Joe
¿Qué encabezados incluye para que esto funcione? – emlai
No se puede usar dirent si está creando una lib. – Katianie
HANDLE WINAPI FindFirstFile(
__in LPCTSTR lpFileName,
__out LPWIN32_FIND_DATA lpFindFileData
);
Configuración de los atributos para que busque sólo para los directorios.
O haces esto y luego leer el test.txt:
#include <windows.h>
int main() {
system("dir /b > test.txt");
}
El "/ B" significa que sólo se devuelven los nombres de archivo, sin más información.
Esto se ve muy bien y fácil, pero no entiendo cómo usar esto. ¿Podría explicar qué es '/ b' y dónde le daremos el directorio? – smttsp
void getFilesList(String filePath,String extension, vector<string> & returnFileName)
{
WIN32_FIND_DATA fileInfo;
HANDLE hFind;
String fullPath = filePath + extension;
hFind = FindFirstFile(fullPath.c_str(), &fileInfo);
if (hFind == INVALID_HANDLE_VALUE){return;}
else {
return FileName.push_back(filePath+fileInfo.cFileName);
while (FindNextFile(hFind, &fileInfo) != 0){
return FileName.push_back(filePath+fileInfo.cFileName);}
}
}
String optfileName ="";
String inputFolderPath ="";
String extension = "*.jpg*";
getFilesList(inputFolderPath,extension,filesPaths);
vector<string>::const_iterator it = filesPaths.begin();
while(it != filesPaths.end())
{
frame = imread(*it);//read file names
//doyourwork here (frame);
sprintf(buf, "%s/Out/%d.jpg", optfileName.c_str(),it->c_str());
imwrite(buf,frame);
it++;
}
tiene 2 devoluciones en el método getFilesList, el código después de la devolución FileName.push_back (filePath + fileInfo.cFileName); no es alcanzable – mmohab
Usted puede utilizar el siguiente código para conseguir todos los archivos en una simple modificación en la respuesta directory.A Andreas Bonini para eliminar la ocurrencia de "" y ".."
he acaba de pedir un question similares y aquí está mi solución basada en la respuesta recibida (usando boost::filesystem
biblioteca):
#include <string>
#include <iostream>
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::filesystem;
int main()
{
path p("D:/AnyFolder");
for (auto i = directory_iterator(p); i != directory_iterator(); i++)
{
if (!is_directory(i->path())) //we eliminate directories in a list
{
cout << i->path().filename().string() << endl;
}
else
continue;
}
}
de salida es como:
file1.txt
file2.dat
Su respuesta es la mejor ... – user1098761
Después de combinar muchos fragmentos, finalmente encontré uno que no trae errores, aceptará un argumento std :: string y es reutilizable.
#include <atlstr.h>
void getFiles(CString directory) {
Console console;
HANDLE dir;
WIN32_FIND_DATA file_data;
CString file_name, full_file_name;
if ((dir = FindFirstFile((directory + "/*"), &file_data)) == INVALID_HANDLE_VALUE)
{
// Invalid directory
}
while (FindNextFile(dir, &file_data)) {
file_name = file_data.cFileName;
full_file_name = directory + file_name;
if (strcmp(file_data.cFileName, ".") != 0 && strcmp(file_data.cFileName, "..") != 0)
{
std::string fileName = full_file_name.GetString();
// Do stuff with fileName
}
}
}
Para acceder al método, a llamarlo:
getFiles("i:\\Folder1");
¿Puede mencionar si esto es para Windows o Linux o ambos? –
C++ 11/Linux versión:
#include <dirent.h>
if (auto dir = opendir("some_dir/")) {
while (auto f = readdir(dir)) {
if (!f->d_name || f->d_name[0] == '.')
continue; // Skip everything that starts with a dot
printf("File: %s\n", f->d_name);
}
closedir(dir);
}
- 1. ¿Cómo obtengo un tamaño de directorio (archivos en el directorio) en C#?
- 2. ¿Cómo obtengo una lista de archivos modificados en svn?
- 3. En Perforce, ¿cómo obtengo una lista de los archivos desprotegidos?
- 4. OutOfMemory cuando lista archivos en un directorio
- 5. ¿Cómo se obtiene una lista de directorio en C?
- 6. Recuento de archivos en un directorio usando C++
- 7. ¿Cómo obtengo la lista de todos los nombres de archivo en un directorio usando VB6?
- 8. Leyendo archivos desde un directorio en Scala
- 9. Obtener una lista de todos los archivos en un directorio (recursivo)
- 10. ¿Cómo obtengo la lista de archivos recientes en GNU Emacs?
- 11. ¿Cómo obtengo una lista de directorios en Perl?
- 12. ¿Es posible obtener una lista de archivos en un directorio de un sitio web? ¿Cómo?
- 13. Linux: busque una palabra en particular en una lista de archivos bajo un directorio
- 14. Archivos en el directorio en C++
- 15. ¿Cómo se muestran los archivos de texto en el directorio seleccionado en un cuadro de lista?
- 16. ¿Cómo obtener la lista de archivos en un directorio en un script de shell?
- 17. ¿Cómo hacer una lista de archivos en un directorio de Android?
- 18. ¿Cómo obtener la lista de todos los archivos con extensión ESY en un directorio?
- 19. ¿Cómo obtengo la lista de identificadores de archivos abiertos por proceso en C#?
- 20. ¿Cómo puedo hacer una lista de todos los archivos en un directorio con Perl?
- 21. Obtener rutas absolutas de todos los archivos en un directorio
- 22. ¿Cómo atravesar los archivos en un directorio?
- 23. ¿Cómo obtengo una lista única de archivos modificados en un repositorio dentro de un rango de commits en Git?
- 24. Obteniendo una lista de archivos en un directorio con un glob
- 25. Copia de archivos desde un directorio en un directorio existente
- 26. lista de archivos Ponerse en una carpeta en C
- 27. lista de PHP todos los archivos en el directorio
- 28. Muchos archivos en un directorio?
- 29. Tratando de conseguir una lista de archivos en un directorio por fecha creada usando LINQ
- 30. Obtener una lista de todos los archivos dentro de un directorio en vb.net
no se olvide de 'closedir (DPDF)' después – jsj
cómo ¿Puedo obtener un archivo (tipo de archivo) en este caso? epdf es un "dirent *" –
No se puede usar dirent si está creando una lib. – Katianie