#include "smt4497-P4.h" using namespace ss; using namespace std; extern Dbg _dbg(true); static size_t accSize = 0; int main(int argc, char* argv[], char* envp[]) { setlocale(LC_ALL, "spanish"); const char* pDir = argv[1]; int found; char** pfileList; static FileSys fs; pfileList = fs.ArchivosEnDirectorio(&found, pDir, false); _dbg.CheckError(argc < 2, 1, "Error en argumentos\n"); SearchTextInFile(argv[1], argv[2]); printf("\nPor favor, pulse la tecla ENTRAR para terminar...\n"); (void)getchar(); return 0; } BOOL ShowFilesInDirectory(int found, char* pName) { BOOL res = FALSE; CHAR buffer[MAX_PATH]; DWORD win32APIResponse = GetFullPathNameA(pName, sizeof(buffer), buffer, NULL); if (!_dbg.CheckError(win32APIResponse == 0, "Error al llamar a GetFullPathNameA()")) { res = TRUE; printf("Se han encontrado %d archivos en la carpeta %s\n", found, buffer); } return res; } size_t GetFileSize(char* pfileName) { WIN32_FILE_ATTRIBUTE_DATA info; BOOL attrs = GetFileAttributesExA(pfileName, GetFileExInfoStandard, &info); return info.nFileSizeLow + ((int64_t)info.nFileSizeHigh << 32); } VOID PrintFilesInDirectory(char* pfileList[]) { int i = 0; // prints file list while a null pointer isn't found while (pfileList[i] != nullptr) { CHAR buffer[64]; PSTR formatted = StrFormatByteSize64A(GetFileSize(pfileList[i]), buffer, sizeof(buffer)); printf("#%d: %s (%s)\n", i, pfileList[i], formatted); i++; } } static size_t BytesInFile(char* listaArchivos[], int nroArchivos) { size_t total = 0; int i = 0; WIN32_FILE_ATTRIBUTE_DATA info; for (i = 0; i < nroArchivos; i++) { if (_dbg.CheckError(FALSE == GetFileAttributesExA(listaArchivos[i], GetFileExInfoStandard, &info), "Error en GetFileAttributesExA para el archivo %s\n", listaArchivos[i])) continue; // Salta a la siguiente iteración del bucle si hay error int64_t tam = ((int64_t)info.nFileSizeHigh >> 32) + info.nFileSizeLow; total += tam; } return total; } static size_t BytesInFileThread(char* listaArchivos[], int nroArchivos, size_t* pTotal) { size_t total = 0; int i = 0; WIN32_FILE_ATTRIBUTE_DATA info; for (i = 0; i < nroArchivos; i++) { if (_dbg.CheckError(FALSE == GetFileAttributesExA(listaArchivos[i], GetFileExInfoStandard, &info), "Error en GetFileAttributesExA para el archivo %s\n", listaArchivos[i])) continue; // Salta a la siguiente iteración del bucle si hay error int64_t tam = ((int64_t)info.nFileSizeHigh >> 32) + info.nFileSizeLow; total += tam; } *pTotal += total; return total; } static size_t BytesInFileMultithread(char* path, unsigned int additionalThreads, bool useLastSearch) { static FileSys fs; static int found = 0; static char** pfileList = nullptr; if (!useLastSearch) { pfileList = fs.ArchivosEnDirectorio(&found, path, false); if (!ShowFilesInDirectory(found, path)) { return 0; printf("\t\tLa búsqueda de archivos ha tardado %f segs\n", fs.TiempoUltimoMetodo()); } } _dbg.CronoInicio(); size_t totalSize = 0; if (additionalThreads == 0) { totalSize = BytesInFile(pfileList, found); } else { thread* threads = new thread[additionalThreads]; for (int i = 0; i < additionalThreads; i++) { threads[i] = thread(BytesInFileThread, pfileList, found, &totalSize); _dbg.CheckError(threads[i].native_handle() == NULL, "Error creando hilo %d", i); } for (int i = 0; i < additionalThreads; i++) { threads[i].join(); } delete[] threads; } auto secs = _dbg.CronoLee(); printf("\tCalculados %lld bytes\n", totalSize); printf("\t\tCalculado en: %f segs por %s (%d hilos adicionales).\n\n", secs, __FUNCTION__, additionalThreads); return totalSize; } static int SearchTextInFile(const char* dirBusqueda, const char* textoABuscar) { Dbg dbg; FileSys fs; int ocurrencias, encontrados = 0, nroArchivos, idxMarca = 0; char** listaArchivos = fs.ArchivosEnDirectorio(&nroArchivos, dirBusqueda, false); if (dbg.CheckError(listaArchivos == nullptr, "No se han encontrado archivos en la carpeta %s\n", dirBusqueda)) { return -1; } char marcasAvance[] = "-\\|/"; // Para animación simple size_t bytesTotal, bytesAcumulados = 0; bytesTotal = BytesInFile(listaArchivos, nroArchivos); if (dbg.CheckError(bytesTotal == 0, "No se han encontrado archivos en la carpeta %s\n", dirBusqueda)) { return -1; } ShowFilesInDirectory(nroArchivos, (char*)dirBusqueda); printf("\nBuscando texto \"%s\" en %lld bytes\n", textoABuscar, bytesTotal); dbg.CronoInicio(); for (int i = 0; i < nroArchivos; i++) { // Busca el texto en el archivo usando un método de FileSys ocurrencias = fs.BuscaDatoEnArchivo(textoABuscar, strlen(textoABuscar), listaArchivos[i], &bytesAcumulados, 10000); if (ocurrencias > 0) { encontrados++; dbg.DbgPrint("#%d: %d ocurrencias en %s\n", encontrados, ocurrencias, listaArchivos[i]); } else if (ocurrencias < 0) { dbg.DbgPrint("Error %s\n", listaArchivos[i]); } // Muestra el avance del proceso if (i == nroArchivos - 1) bytesAcumulados = bytesTotal; // Para que muestre 100% al final, aunque no sea exacto printf("\r%c %.02f %% %d/%d ", marcasAvance[idxMarca++ % (sizeof(marcasAvance) - 1)], (double)bytesAcumulados * 100 / bytesTotal, i + 1, nroArchivos); } double segs = dbg.CronoLee(); printf("\nSe han encontrado %d archivos con el texto\n", encontrados, textoABuscar, dirBusqueda); printf("\t\tCalculado en: %f segs por %s\n", segs, __FUNCTION__); return encontrados; }