|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Jan 2013
Messaggi: 205
|
[C] Calcolare dimensione directory
Ciao a tutti questo è il mio codice che mi permette di leggere il contenuto di una directory
Codice:
#include <stdio.h> #include <dirent.h> #include <stdlib.h> int main (void) { DIR *directory; struct stat dim; struct dirent *dir; directory=opendir("H:/"); if(directory!=NULL){ while((dir= readdir(directory))!=NULL) { puts(dir->d_name); } } else{ perror("Impossibile aprire destinazione!"); } closedir(directory); system("pause"); free(dir); return 0; } ora io ho due domande : 1) Come faccio a vedere(o calcolare) la dimensione di questa directory? 2) Se questa directory avesse altre cartelle come faccio a leggere anche il loro contenuto? grazie come sempre a tutti in anticipo! ![]() |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Puoi usare le primitive contenute in <sys/stat.h>.
Vale a dire, una volta ottenuto il nome del file, ne fai uno stat(). La stat() ti ritornera' le informazioni che ti servono, quali la dimensione del file, se il file e' un regolare/directory/link/... oltre che data di creazione, modifica, ... Se il file e' regolare, sommi le dimensioni. Se il file e' directory, la puoi scandire ricorsivamente (e' piu' facile, ma puoi ovviamente fare anche iterativamente)
__________________
In God we trust; all others bring data |
![]() |
![]() |
![]() |
#3 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Per Windows:
![]() ![]() ScanDir.h Codice:
#ifndef _MY_SCANDIR_ #define _MY_SCANDIR_ // Dati usati dalla funzione DirWalkRecurse typedef struct { TCHAR szInitPath[_MAX_DIR]; // Path iniziale TCHAR szCurrPath[_MAX_DIR]; // Path corrente TCHAR szPathParent[_MAX_DIR]; // Path genitore di szCurrPath TCHAR szCurrDir[_MAX_DIR]; // Path temporaneo; ci servirà per la ricerca dei files int nDepth; // Profondità BOOL fRecurse; // impostare a TRUE per ottenere la scansione delle sottodirectory. TCHAR szBuf[1024]; // Buffer per l'output formattato int nIndent; // Contatore per l'indentazione BOOL fOk; // Loop control flag BOOL fIsDir; // Loop control flag WIN32_FIND_DATA FindData; // Informazioni sui file } DIRWALKDATA, *LPDIRWALKDATA; void DirWalk (LPCTSTR pszRootPath, BOOL fRecurse, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA)); #endif Codice:
#define ARRAY_SIZE(Array) (sizeof(Array) / sizeof((Array)[0])) #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <tchar.h> #include <stdlib.h> #include <stdio.h> #include "ScanDir.h" BOOL IsChildDir (WIN32_FIND_DATA *lpFindData) { return ( (lpFindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (lpFindData->cFileName[0] != __TEXT('.')) ); } BOOL FindNextChildDir (HANDLE hFindFile, WIN32_FIND_DATA *lpFindData) { BOOL fFound = FALSE; do { fFound = FindNextFile(hFindFile, lpFindData); } while (fFound && !IsChildDir(lpFindData)); return(fFound); } HANDLE FindFirstChildDir (LPTSTR szPath, WIN32_FIND_DATA *lpFindData) { BOOL fFound; HANDLE hFindFile = FindFirstFile(szPath, lpFindData); if (hFindFile != INVALID_HANDLE_VALUE) { fFound = IsChildDir(lpFindData); if (!fFound) fFound = FindNextChildDir(hFindFile, lpFindData); if (!fFound) { FindClose(hFindFile); hFindFile = INVALID_HANDLE_VALUE; } } return(hFindFile); } void GetParentDirectory(LPCTSTR szPath, LPTSTR szParent) { size_t nLen; nLen = _tcslen(szPath); _tcscpy(szParent, szPath); if ( szPath[0] == '\\' ) return; while ( nLen > 0 ) { if ( *(szParent + nLen-1) == '\\' ) { *(szParent + nLen-1) = '\0'; break; } --nLen; } } // Percorre la struttura della directory. // Se il campo pDW->fRecurse è TRUE, percorre ricorsivamente anche le sottodirectory. void DirWalkRecurse (LPDIRWALKDATA pDW, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA)) { HANDLE hFind; pDW->szCurrDir[0] = '\0'; pDW->nDepth++; pDW->nIndent = 3 * pDW->nDepth; _stprintf(pDW->szBuf, __TEXT("%*s"), pDW->nIndent, __TEXT("")); // Imposta il buffer alla directory iniziale e chiama la funzione evento // fornita dall'utente. _tcscpy(&pDW->szBuf[pDW->nIndent], pDW->szCurrPath); if ( pfnOnChange ) (*pfnOnChange)(pDW); //printf("pDW->szBuf -----> %s\n", pDW->szBuf); // Inizia a leggere il contenuto della directory iniziale _tcscpy(pDW->szCurrDir, pDW->szCurrPath); _tcscat(pDW->szCurrDir, __TEXT("\\*.*")); hFind = FindFirstFile( pDW->szCurrDir, &pDW->FindData); pDW->fOk = (hFind != INVALID_HANDLE_VALUE); while (pDW->fOk) { pDW->fIsDir = pDW->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; if ( !pDW->fIsDir || (!pDW->fRecurse && IsChildDir(&pDW->FindData)) ) { _stprintf( pDW->szBuf, pDW->fIsDir ? __TEXT("%*s[%s]") : __TEXT("%*s%s"), pDW->nIndent, __TEXT(""), pDW->FindData.cFileName); // Per ogni file ( o sottodirectory ) trovato, // chiamiamo la funzione fornita dall'utente // passandogli i dati relativi tramite il puntatore alla struct pDW. if ( pfnOnChange ) (*pfnOnChange)(pDW); //printf("pDW->szBuf -----> %s\n", pDW->szBuf); } pDW->fOk = FindNextFile(hFind, &pDW->FindData); } if (hFind != INVALID_HANDLE_VALUE) FindClose(hFind); // se fRecurse è TRUE, leggiamo ricorsivamente le sottodirectory if (pDW->fRecurse) { // Ottiene la prima directory figlia hFind = FindFirstChildDir( pDW->szCurrDir, &pDW->FindData ); pDW->fOk = (hFind != INVALID_HANDLE_VALUE); while (pDW->fOk) { // Passa alla directory figlia _tcscat(pDW->szCurrPath, __TEXT("\\")); _tcscat(pDW->szCurrPath, pDW->FindData.cFileName); DirWalkRecurse(pDW, pfnOnChange); // Ritorna alla directory genitore GetParentDirectory(pDW->szCurrPath, pDW->szPathParent); _tcscpy(pDW->szCurrPath, pDW->szPathParent); pDW->fOk = FindNextChildDir(hFind, &pDW->FindData); } if (hFind != INVALID_HANDLE_VALUE) FindClose(hFind); } pDW->nDepth--; } // Funzioni esportate ///////////////////////////////////////////////////////////// // Il parametro pszRootPath è il percorso completo della directory da esaminare // Il parametro fRecurse è un valore booleano che indica // se vogliamo leggere anche le sottodirectory. Se impostato a FALSE, la funzione // legge solo la directory passata nel parametro pszRootPath // Il parametro pfnOnChange è un puntatore a una funzione evento che deve essere // implementata dal client ( il programma che utilizza la DLL ) void DirWalk (LPCTSTR pszRootPath, BOOL fRecurse, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA)) { DIRWALKDATA DW; DW.szBuf[0] = '\0'; DW.szCurrDir[0] = '\0'; DW.szCurrPath[0] = '\0'; DW.szInitPath[0] = '\0'; DW.szPathParent[0] = '\0'; // nDepth è usato per controllare l'indentazione. Il valore -1 // fa si che il primo livello sia visualizzato allineato a sinistra DW.nDepth = -1; DW.fRecurse = fRecurse; _tcscpy(DW.szInitPath, pszRootPath); _tcscpy(DW.szCurrPath, pszRootPath); // Leggiamo il contenuto della directory passata nel parametro pszRootPath. // Se il parametro fRecurse è TRUE, leggiamo anche le sottodirectory DirWalkRecurse(&DW, pfnOnChange); } Codice:
#include <windows.h> #include <stdio.h> #include "scandir.h" void CALLBACK OnChange(LPDIRWALKDATA pDW) { printf("# -> %s\n", pDW->szBuf); } int main(int argc, char* argv[]) { if( argc < 2 ) return -1; DirWalk(argv[1], TRUE, OnChange); return 0; } |
![]() |
![]() |
![]() |
#4 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Per la dimensione della directory, su Windows, puoi utilizzare diverse api:
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx |
![]() |
![]() |
![]() |
#5 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Questo invece è l'esempio per Linux, tratto dal bel libro di W. Richard Stevens e Stephen A. Rago:
![]() apue.h Codice:
/* Our own header, to be included before all standard system headers */ #ifndef _APUE_H #define _APUE_H #if defined(SOLARIS) #define _XOPEN_SOURCE 500 /* Single UNIX Specification, Version 2 for Solaris 9 */ #define CMSG_LEN(x) _CMSG_DATA_ALIGN(sizeof(struct cmsghdr)+(x)) #elif !defined(BSD) #define _XOPEN_SOURCE 600 /* Single UNIX Specification, Version 3 */ #endif #include <sys/types.h> /* some systems still require this */ #include <sys/stat.h> #include <sys/termios.h> /* for winsize */ #ifndef TIOCGWINSZ #include <sys/ioctl.h> #endif #include <stdio.h> /* for convenience */ #include <stdlib.h> /* for convenience */ #include <stddef.h> /* for offsetof */ #include <string.h> /* for convenience */ #include <unistd.h> /* for convenience */ #include <signal.h> /* for SIG_ERR */ #define MAXLINE 4096 /* max line length */ /* * Default file access permissions for new files. */ #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) /* * Default permissions for new directories. */ #define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH) typedef void Sigfunc(int); /* for signal handlers */ #if defined(SIG_IGN) && !defined(SIG_ERR) #define SIG_ERR ((Sigfunc *)-1) #endif #define min(a,b) ((a) < (b) ? (a) : (b)) #define max(a,b) ((a) > (b) ? (a) : (b)) /* * Prototypes for our own functions. */ char *path_alloc(int *); /* {Prog pathalloc} */ long open_max(void); /* {Prog openmax} */ void clr_fl(int, int); /* {Prog setfl} */ void set_fl(int, int); /* {Prog setfl} */ void pr_exit(int); /* {Prog prexit} */ void pr_mask(const char *); /* {Prog prmask} */ Sigfunc *signal_intr(int, Sigfunc *); /* {Prog signal_intr_function} */ int tty_cbreak(int); /* {Prog raw} */ int tty_raw(int); /* {Prog raw} */ int tty_reset(int); /* {Prog raw} */ void tty_atexit(void); /* {Prog raw} */ #ifdef ECHO /* only if <termios.h> has been included */ struct termios *tty_termios(void); /* {Prog raw} */ #endif void sleep_us(unsigned int); /* {Ex sleepus} */ ssize_t readn(int, void *, size_t); /* {Prog readn_writen} */ ssize_t writen(int, const void *, size_t); /* {Prog readn_writen} */ void daemonize(const char *); /* {Prog daemoninit} */ int s_pipe(int *); /* {Progs streams_spipe sock_spipe} */ int recv_fd(int, ssize_t (*func)(int, const void *, size_t));/* {Progs recvfd_streams recvfd_sockets} */ int send_fd(int, int); /* {Progs sendfd_streams sendfd_sockets} */ int send_err(int, int, const char *); /* {Prog senderr} */ int serv_listen(const char *); /* {Progs servlisten_streams servlisten_sockets} */ int serv_accept(int, uid_t *); /* {Progs servaccept_streams servaccept_sockets} */ int cli_conn(const char *); /* {Progs cliconn_streams cliconn_sockets} */ int buf_args(char *, int (*func)(int, char **)); /* {Prog bufargs} */ int ptym_open(char *, int); /* {Progs3 ptyopen_streams ptyopen_bsd ptyopen_linux} */ int ptys_open(char *); /* {Progs3 ptyopen_streams ptyopen_bsd ptyopen_linux} */ #ifdef TIOCGWINSZ pid_t pty_fork(int *, char *, int, const struct termios *, const struct winsize *); /* {Prog ptyfork} */ #endif int lock_reg(int, int, int, off_t, int, off_t); /* {Prog lockreg} */ #define read_lock(fd, offset, whence, len) \ lock_reg((fd), F_SETLK, F_RDLCK, (offset), (whence), (len)) #define readw_lock(fd, offset, whence, len) \ lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len)) #define write_lock(fd, offset, whence, len) \ lock_reg((fd), F_SETLK, F_WRLCK, (offset), (whence), (len)) #define writew_lock(fd, offset, whence, len) \ lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len)) #define un_lock(fd, offset, whence, len) \ lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len)) pid_t lock_test(int, int, off_t, int, off_t); /* {Prog locktest} */ #define is_read_lockable(fd, offset, whence, len) \ (lock_test((fd), F_RDLCK, (offset), (whence), (len)) == 0) #define is_write_lockable(fd, offset, whence, len) \ (lock_test((fd), F_WRLCK, (offset), (whence), (len)) == 0) void err_dump(const char *, ...); /* {App misc_source} */ void err_msg(const char *, ...); void err_quit(const char *, ...); void err_exit(int, const char *, ...); void err_ret(const char *, ...); void err_sys(const char *, ...); void log_msg(const char *, ...); /* {App misc_source} */ void log_open(const char *, int, int); void log_quit(const char *, ...); void log_ret(const char *, ...); void log_sys(const char *, ...); void TELL_WAIT(void); /* parent/child from {Sec race_conditions} */ void TELL_PARENT(pid_t); void TELL_CHILD(pid_t); void WAIT_PARENT(void); void WAIT_CHILD(void); #endif /* _APUE_H */ scandir.c Codice:
#include "apue.h" #include <dirent.h> #include <limits.h> /* function type that is called for each filename */ typedef int Myfunc(const char *, const struct stat *, int); static Myfunc myfunc; static int myftw(char *, Myfunc *); static int dopath(Myfunc *); static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot; int main(int argc, char *argv[]) { int ret; if (argc != 2) { printf("usage: scandir <starting-pathname>"); return -1; } ret = myftw(argv[1], myfunc); /* does it all */ ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock; if (ntot == 0) ntot = 1; /* avoid divide by 0; print 0 for all counts */ printf("regular files = %7ld, %5.2f %%\n", nreg, nreg*100.0/ntot); printf("directories = %7ld, %5.2f %%\n", ndir, ndir*100.0/ntot); printf("block special = %7ld, %5.2f %%\n", nblk, nblk*100.0/ntot); printf("char special = %7ld, %5.2f %%\n", nchr, nchr*100.0/ntot); printf("FIFOs = %7ld, %5.2f %%\n", nfifo, nfifo*100.0/ntot); printf("symbolic links = %7ld, %5.2f %%\n", nslink, nslink*100.0/ntot); printf("sockets = %7ld, %5.2f %%\n", nsock, nsock*100.0/ntot); exit(ret); } /* * Descend through the hierarchy, starting at "pathname". * The caller's func() is called for every file. */ #define FTW_F 1 /* file other than directory */ #define FTW_D 2 /* directory */ #define FTW_DNR 3 /* directory that can't be read */ #define FTW_NS 4 /* file that we can't stat */ static char *fullpath; /* contains full pathname for every file */ static int /* we return whatever func() returns */ myftw(char *pathname, Myfunc *func) { int len; //fullpath = path_alloc(&len); /* malloc's for PATH_MAX+1 bytes */ len = PATH_MAX * sizeof(char) + 1; fullpath = (char*)malloc(len); if ( !fullpath ) { printf("Memoria insufficiente, addio!\n"); return -1; } strncpy(fullpath, pathname, len); /* protect against */ fullpath[len-1] = 0; /* buffer overrun */ return(dopath(func)); } /* * Descend through the hierarchy, starting at "fullpath". * If "fullpath" is anything other than a directory, we lstat() it, * call func(), and return. For a directory, we call ourself * recursively for each name in the directory. */ static int /* we return whatever func() returns */ dopath(Myfunc* func) { struct stat statbuf; struct dirent *dirp; DIR *dp; int ret; char *ptr; if (lstat(fullpath, &statbuf) < 0) /* stat error */ return(func(fullpath, &statbuf, FTW_NS)); if (S_ISDIR(statbuf.st_mode) == 0) /* not a directory */ return(func(fullpath, &statbuf, FTW_F)); /* * It's a directory. First call func() for the directory, * then process each filename in the directory. */ if ((ret = func(fullpath, &statbuf, FTW_D)) != 0) return(ret); ptr = fullpath + strlen(fullpath); /* point to end of fullpath */ *ptr++ = '/'; *ptr = 0; if ((dp = opendir(fullpath)) == NULL) /* can't read directory */ return(func(fullpath, &statbuf, FTW_DNR)); while ((dirp = readdir(dp)) != NULL) { if (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0) continue; /* ignore dot and dot-dot */ strcpy(ptr, dirp->d_name); /* append name after slash */ if ((ret = dopath(func)) != 0) /* recursive */ break; /* time to leave */ } ptr[-1] = 0; /* erase everything from slash onwards */ if (closedir(dp) < 0) { printf("can't close directory %s", fullpath); return -1; } return(ret); } static int myfunc(const char *pathname, const struct stat *statptr, int type) { switch (type) { case FTW_F: switch (statptr->st_mode & S_IFMT) { case S_IFREG: nreg++; break; case S_IFBLK: nblk++; break; case S_IFCHR: nchr++; break; case S_IFIFO: nfifo++; break; case S_IFLNK: nslink++; break; case S_IFSOCK: nsock++; break; case S_IFDIR: printf("for S_IFDIR for %s", pathname); break; } break; case FTW_D: ndir++; break; case FTW_DNR: printf("can't read directory %s", pathname); break; case FTW_NS: printf("stat error for %s", pathname); break; default: printf("unknown type %d for pathname %s", type, pathname); } return(0); } |
![]() |
![]() |
![]() |
#6 | |
Member
Iscritto dal: Jan 2013
Messaggi: 205
|
Quote:
Codice:
#include <stdio.h> #include <dirent.h> #include <sys/stat.h> int main (int argc, char **argv) { DIR *directory; struct stat dim; struct dirent *dir; directory=opendir("H:/"); if(directory!=NULL){ while((dir= readdir(directory))!=NULL) { puts(dir->d_name); stat(dir->d_name, &dim); printf ("\tDimensione : %f KB\n\n", float(dim.st_size)/1024); } } else{ perror("Impossibile aprire destinazione!"); } closedir(directory); free(dir); system ("PAUSE"); return 0; } ![]() ![]() ![]() Ultima modifica di sam333 : 07-03-2013 alle 13:42. |
|
![]() |
![]() |
![]() |
#7 | |
Member
Iscritto dal: Jan 2013
Messaggi: 205
|
Quote:
![]() Ultima modifica di sam333 : 07-03-2013 alle 13:43. |
|
![]() |
![]() |
![]() |
#8 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Si c'è:
![]() Codice:
#include <unistd.h> #include <stdio.h> #include <dirent.h> #include <string.h> #include <sys/stat.h> #include <stdlib.h> void getDirInfo(char *dir, int depth) { DIR *dp; struct dirent *entry; struct stat statbuf; if( (dp = opendir(dir)) == NULL ) { fprintf(stderr, "Impossibile aprire la directory: \"%s\". Addio!\n", dir); return; } chdir(dir); while( (entry = readdir(dp)) != NULL ) { lstat(entry->d_name, &statbuf); if( S_ISDIR(statbuf.st_mode) ) { /* ignoriamo . and .. */ if( strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0 ) continue; printf("%*s%s/\n", depth, "", entry->d_name); /* nuovo livello d'indentazione */ getDirInfo(entry->d_name, depth + 4); } else { printf("%*s%s\n", depth, "", entry->d_name); } } chdir(".."); closedir(dp); } int main(int argc, char* argv[]) { char *topdir, pwd[2] = "."; if (argc != 2) topdir = pwd; else topdir = argv[1]; printf("Scansione della directory \"%s\"\n", topdir); getDirInfo(topdir, 0); printf("Finito!\n"); return 0; } Ultima modifica di Vincenzo1968 : 07-03-2013 alle 14:36. |
![]() |
![]() |
![]() |
#9 |
Member
Iscritto dal: Jan 2013
Messaggi: 205
|
grazie mille!
![]() 1) c'è un'alternativa alla libreria "unistd.h"?perchè non è solo per linux?non credo che ci sia su visual c++ 2)sai per caso come mai mi da le dimensioni sballate? ![]() |
![]() |
![]() |
![]() |
#10 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
Per quanto riguarda la prima domanda, potresti usare delle librerie che astraggono dal particolare sistrema operativo, tipo QT o Boost. Oppure puoi, più semplicemente, impacchettare le due versioni all'interno di direttive condizionali(#ifdef __linux__, etc). Per quanto riguarda la domanda 2, no, non lo so. Il consiglio di Sottovento va nella direzione giusta. Non capisco cosa intendi per "se gli do il nome del file preciso". Per forza devi darglielo preciso altrimenti come si fa? ![]() ![]() |
|
![]() |
![]() |
![]() |
#11 | |
Member
Iscritto dal: Jan 2013
Messaggi: 205
|
Quote:
![]() Comunque o provato a riadattare il codice e come al solito non ci riesco-_- #ifdef _linux #include <unistd.h> #else #include "stdafx.h" #include <stdio.h> #include <dirent.h> #include <sys/stat.h> #endif non va bene?mi dice #endif imprevisto e che la libreria è stata ignorata Ultima modifica di sam333 : 07-03-2013 alle 17:21. |
|
![]() |
![]() |
![]() |
#12 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Ecco:
![]() Codice:
#include <unistd.h> #include <stdio.h> #include <dirent.h> #include <string.h> #include <sys/stat.h> #include <stdlib.h> #include <stdint.h> void getDirInfo(char *dir, int depth, uint64_t *pDim) { DIR *dp; struct dirent *entry; struct stat statbuf; if( (dp = opendir(dir)) == NULL ) { fprintf(stderr, "Impossibile aprire la directory: \"%s\". Addio!\n", dir); return; } chdir(dir); while( (entry = readdir(dp)) != NULL ) { lstat(entry->d_name, &statbuf); //*pDim += statbuf.st_size; if( S_ISDIR(statbuf.st_mode) ) { /* ignoriamo . and .. */ if( strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0 ) continue; *pDim += statbuf.st_size; printf("%*s%s/\n", depth, "", entry->d_name); /* nuovo livello d'indentazione */ getDirInfo(entry->d_name, depth + 4, pDim); } else { *pDim += statbuf.st_size; printf("%*s%s\n", depth, "", entry->d_name); } } chdir(".."); closedir(dp); } int main(int argc, char* argv[]) { uint64_t dim = 0; char *topdir, pwd[2] = "."; if (argc != 2) topdir = pwd; else topdir = argv[1]; printf("Scansione della directory \"%s\"\n", topdir); getDirInfo(topdir, 0, &dim); printf("\nLa dimensione in byte della directory \"%s\" e': %llu\n", topdir, (unsigned long long)dim); exit(0); } Ultima modifica di Vincenzo1968 : 08-03-2013 alle 17:07. |
![]() |
![]() |
![]() |
#13 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Se invece vuoi ottenere la dimensione totale, cioè compresa la dimensione di file e directory nascoste, devi fare così:
Codice:
#include <unistd.h> #include <stdio.h> #include <dirent.h> #include <string.h> #include <sys/stat.h> #include <stdlib.h> #include <stdint.h> void getDirInfo(char *dir, int depth, uint64_t *pDim) { DIR *dp; struct dirent *entry; struct stat statbuf; if( (dp = opendir(dir)) == NULL ) { fprintf(stderr, "Impossibile aprire la directory: \"%s\". Addio!\n", dir); return; } chdir(dir); while( (entry = readdir(dp)) != NULL ) { lstat(entry->d_name, &statbuf); *pDim += statbuf.st_size; if( S_ISDIR(statbuf.st_mode) ) { /* ignoriamo . and .. */ if( strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0 ) continue; //*pDim += statbuf.st_size; printf("%*s%s/\n", depth, "", entry->d_name); /* nuovo livello d'indentazione */ getDirInfo(entry->d_name, depth + 4, pDim); } else { //*pDim += statbuf.st_size; printf("%*s%s\n", depth, "", entry->d_name); } } chdir(".."); closedir(dp); } int main(int argc, char* argv[]) { uint64_t dim = 0; char *topdir, pwd[2] = "."; if (argc != 2) topdir = pwd; else topdir = argv[1]; printf("Scansione della directory \"%s\"\n", topdir); getDirInfo(topdir, 0, &dim); printf("\nLa dimensione in byte della directory \"%s\" e': %llu\n", topdir, (unsigned long long)dim); exit(0); } |
![]() |
![]() |
![]() |
#14 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Per le direttive di compilazione condizionale puoi dare un'occhiata alla soluzione postata da AnonimoVeneziano per il punto A del contest 19.
Eccolo: Codice:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <ctype.h> #if _WIN32 #include <Windows.h> #define RESTRICT __restrict typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; typedef char int8_t; typedef short int16_t; typedef int int32_t; typedef long long int64_t; #define fseeko _fseeki64 #define ftello _ftelli64 const char* files_dir = ".\\All\\*"; #else #include <stdint.h> #include <stdbool.h> #include <dirent.h> #define RESTRICT restrict #define TRUE true #define FALSE false const char* files_dir = "./All/"; #endif #define DEFAULT_LINE_NUM 100000 #define MB_MULTIPLIER 1024*1024ULL #define GB_MULTIPLIER 1024*1024*1024ULL #define IS_SPECIAL_DIRECTORY(x) (x[0] == '.' && \ (x[1] == '.' || x[1] == '\0')) uint8_t file_nums = 0; size_t text_size = 0; char* RESTRICT full_text = NULL; uint32_t lines_num = 0; int64_t output_size_bytes = 0; int64_t written_bytes = 0; char* RESTRICT * RESTRICT lines_ptrs = NULL; const char* usage_string = "Usage: c19input NameInputFile [-DFileSize]\n\n" "The size of the output file is defined in this way:\n\n" "-D1MB\toutput file is 1MB\n-D1GiB\t output file is 1 GB\n\n" "The maximum file size is 55 GiB"; size_t get_file_size(const char* RESTRICT fname) { size_t size; FILE* f = fopen(fname, "r"); fseeko(f, 0L, SEEK_END); size = ftello(f); fclose(f); return size; } void read_files(char* RESTRICT * RESTRICT fnames, int fnums) { size_t pos_counter = 0; size_t* RESTRICT files_size = (size_t* RESTRICT)malloc(sizeof(size_t)*fnums); for (int i = 0; i < fnums; ++i) { files_size[i] = get_file_size(fnames[i]); text_size += files_size[i]; } full_text = (char * RESTRICT) malloc(sizeof(char)*(text_size+1)); // Read the entire text of files into the array for (int i = 0; i < fnums; ++i) { FILE* f = fopen(fnames[i], "r"); pos_counter += fread(full_text+pos_counter, sizeof(char), files_size[i], f); fclose(f); } full_text[text_size] = '\0'; free(files_size); } #if !_WIN32 bool load_files(const char* directory) { DIR* RESTRICT dir_obj = opendir(directory); struct dirent* RESTRICT dir_struct; char * RESTRICT * RESTRICT files_names; const uint16_t path_size = strlen(directory); int count = 0; if (dir_obj == NULL) return TRUE; while ((dir_struct = readdir(dir_obj)) != NULL) { //printf("File name: %s\n", dir_struct->d_name); if (!IS_SPECIAL_DIRECTORY(dir_struct->d_name)) ++file_nums; } rewinddir(dir_obj); files_names = malloc(file_nums*sizeof(char*)); while ((dir_struct = readdir(dir_obj)) != NULL) { if (!IS_SPECIAL_DIRECTORY(dir_struct->d_name)) { int name_size = strlen(dir_struct->d_name); int size = path_size + name_size + 1; files_names[count] = malloc(sizeof(char)*size); strncpy(files_names[count], directory, path_size); strncpy(files_names[count]+path_size, dir_struct->d_name, name_size); //printf("%s\n", files_names[count]); ++count; } } closedir(dir_obj); //printf("%d\n", file_nums); //printf("Size of dir: %d\n", path_size); // Read files read_files(files_names, file_nums); for (int i = 0; i < file_nums; ++i) free((void*)files_names[i]); free((void**)files_names); return FALSE; } #else bool load_files(const char* directory) { WIN32_FIND_DATA find_data; HANDLE hFind; char * RESTRICT * RESTRICT files_names; const uint16_t path_size = strlen(directory)-1; int count = 0; hFind = FindFirstFile(directory, &find_data); if ( hFind == INVALID_HANDLE_VALUE) return TRUE; do { //printf("File name: %s\n", dir_struct->d_name); if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) ++file_nums; } while (FindNextFile(hFind, &find_data)); FindClose(hFind); hFind = FindFirstFile(directory, &find_data); files_names = (char* RESTRICT * RESTRICT) malloc(file_nums*sizeof(char*)); do { if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { int name_size = strlen(find_data.cFileName); int size = path_size + name_size + 1; files_names[count] = (char* RESTRICT)malloc(sizeof(char)*size); strncpy(files_names[count], directory, path_size); strncpy(files_names[count]+path_size, find_data.cFileName, name_size+1); //printf("%s\n", files_names[count]); ++count; } } while (FindNextFile(hFind, &find_data)); FindClose(hFind); //printf("%d\n", file_nums); //printf("Size of dir: %d\n", path_size); // Read files read_files(files_names, file_nums); for (int i = 0; i < file_nums; ++i) free((void*)files_names[i]); free((void**)files_names); return FALSE; } #endif // Determines the number of lines and normalizes the text void process_lines() { lines_ptrs = (char* RESTRICT * RESTRICT) malloc(sizeof(char*)*DEFAULT_LINE_NUM); uint32_t correction = 0; uint32_t curr_max_lines = DEFAULT_LINE_NUM; lines_ptrs[0] = full_text; bool has_character = FALSE; for (size_t i = 0; i <= text_size; ++i) { switch (full_text[i]) { default: { full_text[i-correction] = full_text[i]; has_character = TRUE; break; } case '\t': { full_text[i-correction] = ' '; break; } case '\n': { if (full_text[i-correction-1] != '\0') { if (has_character) lines_ptrs[++lines_num] = &full_text[i-correction+1]; full_text[i-correction] = '\0'; has_character = FALSE; } else ++correction; break; } case '\r': { if (full_text[i-correction-1] != '\0') { if (has_character) lines_ptrs[++lines_num] = &full_text[i-correction+1]; full_text[i-correction] = '\0'; has_character = FALSE; } else ++correction; break; } case ' ': { if (full_text[i-correction-1] != ' ' && has_character) full_text[i-correction] = ' '; else ++correction; break; } } // Expand line buffer if (lines_num >= curr_max_lines) { curr_max_lines = 2*curr_max_lines; char* RESTRICT * RESTRICT new_lines_ptr = (char* RESTRICT * RESTRICT) malloc(sizeof(char*)*curr_max_lines); memcpy((void* RESTRICT)new_lines_ptr, (const void* RESTRICT)lines_ptrs, lines_num); free((void*)lines_ptrs); lines_ptrs = new_lines_ptr; } } } void shuffle_lines() { for (uint32_t i = lines_num-1; i > 0; --i) { uint32_t rand_idx = rand() % (i+1); char* temp = lines_ptrs[i]; lines_ptrs[i] = lines_ptrs[rand_idx]; lines_ptrs[rand_idx] = temp; } } bool generate_output(FILE* output) { for (uint32_t i = 0; i < lines_num && written_bytes < output_size_bytes; ++i) { int32_t str_len = strlen(lines_ptrs[i]); if (str_len + written_bytes > output_size_bytes) str_len = output_size_bytes - written_bytes - 1; written_bytes += fwrite(lines_ptrs[i], sizeof(char), str_len, output) + 1; fputc('\n', output); } if (written_bytes >= output_size_bytes) return FALSE; return TRUE; } void show_usage() { printf("%s\n\n", usage_string); } int main(int argc, char **argv) { bool error = FALSE; FILE* output_file = NULL; if (argc == 2) { output_size_bytes = 1024*1024ULL; } else if (argc == 3) { char *arg2 = argv[2]; uint8_t unit_idx = 0; char size[3] = { 0 }; uint64_t size_num; if (strncmp(arg2, "-D", 2)) goto parse_error; while (*(arg2+2+unit_idx) != '\0' && isdigit(*(arg2+2+unit_idx))) { if ( unit_idx >= 3 ) goto parse_error; size[unit_idx++] = *(arg2+2+unit_idx); } size_num = atoi(size); if (size_num == 0) goto parse_error; if (!strncmp(arg2+2+unit_idx, "GiB", 3)) size_num = size_num*GB_MULTIPLIER; else if (!strncmp(arg2+2+unit_idx, "MB", 2)) size_num = size_num*MB_MULTIPLIER; else goto parse_error; output_size_bytes = size_num; } else { parse_error: show_usage(); return 1; } srand(time(NULL)); //printf("Started loading the files\n"); clock_t t = clock(); error = load_files(files_dir); printf("Files loaded, it took: %f seconds\n", ((float)(clock() - t)) / CLOCKS_PER_SEC); if (error) { if (full_text) free(full_text); return 1; } output_file = fopen(argv[1], "w"); //printf("Started processing the files\n"); t = clock(); process_lines(); printf("File processing finished, it took: %f seconds\n", ((float)(clock() - t)) / CLOCKS_PER_SEC); //printf("Started final file output\n"); t = clock(); do { shuffle_lines(); } while (generate_output(output_file)); printf("Final file output finished, it took: %f seconds\n", ((float)(clock() - t)) / CLOCKS_PER_SEC); free((void*)full_text); free((void*)lines_ptrs); fclose(output_file); return 0; } ![]() Ultima modifica di Vincenzo1968 : 07-03-2013 alle 17:45. |
![]() |
![]() |
![]() |
#15 | |
Member
Iscritto dal: Jan 2013
Messaggi: 205
|
Quote:
![]() ![]() ![]() |
|
![]() |
![]() |
![]() |
#16 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
|
![]() |
![]() |
![]() |
#17 |
Member
Iscritto dal: Jan 2013
Messaggi: 205
|
|
![]() |
![]() |
![]() |
#18 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
![]() ScanDir.h: Codice:
#ifndef _MY_SCANDIR_ #define _MY_SCANDIR_ // Dati usati dalla funzione DirWalkRecurse typedef struct { TCHAR szInitPath[_MAX_DIR]; // Path iniziale TCHAR szCurrPath[_MAX_DIR]; // Path corrente TCHAR szPathParent[_MAX_DIR]; // Path genitore di szCurrPath TCHAR szCurrDir[_MAX_DIR]; // Path temporaneo; ci servirà per la ricerca dei files int nDepth; // Profondità BOOL fRecurse; // impostare a TRUE per ottenere la scansione delle sottodirectory. TCHAR szBuf[1024]; // Buffer per l'output formattato int nIndent; // Contatore per l'indentazione BOOL fOk; // Loop control flag BOOL fIsDir; // Loop control flag WIN32_FIND_DATA FindData; // Informazioni sui file } DIRWALKDATA, *LPDIRWALKDATA; void getDirInfo(LPCTSTR pszRootPath, BOOL fRecurse, uint64_t *pDim, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA)); #endif Codice:
#define ARRAY_SIZE(Array) (sizeof(Array) / sizeof((Array)[0])) #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <tchar.h> #include <stdlib.h> #include <stdio.h> #include <stdint.h> #include "ScanDir.h" BOOL IsChildDir (WIN32_FIND_DATA *lpFindData) { return ( (lpFindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (lpFindData->cFileName[0] != __TEXT('.')) ); } BOOL FindNextChildDir (HANDLE hFindFile, WIN32_FIND_DATA *lpFindData) { BOOL fFound = FALSE; do { fFound = FindNextFile(hFindFile, lpFindData); } while (fFound && !IsChildDir(lpFindData)); return(fFound); } HANDLE FindFirstChildDir (LPTSTR szPath, WIN32_FIND_DATA *lpFindData) { BOOL fFound; HANDLE hFindFile = FindFirstFile(szPath, lpFindData); if (hFindFile != INVALID_HANDLE_VALUE) { fFound = IsChildDir(lpFindData); if (!fFound) fFound = FindNextChildDir(hFindFile, lpFindData); if (!fFound) { FindClose(hFindFile); hFindFile = INVALID_HANDLE_VALUE; } } return(hFindFile); } void GetParentDirectory(LPCTSTR szPath, LPTSTR szParent) { size_t nLen; nLen = _tcslen(szPath); _tcscpy(szParent, szPath); if ( szPath[0] == '\\' ) return; while ( nLen > 0 ) { if ( *(szParent + nLen-1) == '\\' ) { *(szParent + nLen-1) = '\0'; break; } --nLen; } } // Percorre la struttura della directory. // Se il campo pDW->fRecurse è TRUE, percorre ricorsivamente anche le sottodirectory.m void DirWalkRecurse (LPDIRWALKDATA pDW, uint64_t *pDim, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA)) { HANDLE hFind; pDW->szCurrDir[0] = '\0'; pDW->nDepth++; pDW->nIndent = 3 * pDW->nDepth; _stprintf(pDW->szBuf, __TEXT("%*s"), pDW->nIndent, __TEXT("")); // Imposta il buffer alla directory iniziale e chiama la funzione evento // fornita dall'utente. _tcscpy(&pDW->szBuf[pDW->nIndent], pDW->szCurrPath); if ( pfnOnChange ) (*pfnOnChange)(pDW); //printf("pDW->szBuf -----> %s\n", pDW->szBuf); // Inizia a leggere il contenuto della directory iniziale _tcscpy(pDW->szCurrDir, pDW->szCurrPath); _tcscat(pDW->szCurrDir, __TEXT("\\*.*")); hFind = FindFirstFile( pDW->szCurrDir, &pDW->FindData); pDW->fOk = (hFind != INVALID_HANDLE_VALUE); while (pDW->fOk) { pDW->fIsDir = pDW->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; if ( !pDW->fIsDir || (!pDW->fRecurse && IsChildDir(&pDW->FindData)) ) { _stprintf( pDW->szBuf, pDW->fIsDir ? __TEXT("%*s[%s]") : __TEXT("%*s%s"), pDW->nIndent, __TEXT(""), pDW->FindData.cFileName); *pDim += (pDW->FindData.nFileSizeHigh * (MAXDWORD+1)) + pDW->FindData.nFileSizeLow; // Per ogni file ( o sottodirectory ) trovato, // chiamiamo la funzione fornita dall'utente // passandogli i dati relativi tramite il puntatore alla struct pDW. if ( pfnOnChange ) (*pfnOnChange)(pDW); //printf("pDW->szBuf -----> %s\n", pDW->szBuf); } pDW->fOk = FindNextFile(hFind, &pDW->FindData); } if (hFind != INVALID_HANDLE_VALUE) FindClose(hFind); // se fRecurse è TRUE, leggiamo ricorsivamente le sottodirectory if (pDW->fRecurse) { // Ottiene la prima directory figlia hFind = FindFirstChildDir( pDW->szCurrDir, &pDW->FindData ); pDW->fOk = (hFind != INVALID_HANDLE_VALUE); while (pDW->fOk) { // Passa alla directory figlia _tcscat(pDW->szCurrPath, __TEXT("\\")); _tcscat(pDW->szCurrPath, pDW->FindData.cFileName); DirWalkRecurse(pDW, pDim, pfnOnChange); // Ritorna alla directory genitore GetParentDirectory(pDW->szCurrPath, pDW->szPathParent); _tcscpy(pDW->szCurrPath, pDW->szPathParent); pDW->fOk = FindNextChildDir(hFind, &pDW->FindData); } if (hFind != INVALID_HANDLE_VALUE) FindClose(hFind); } pDW->nDepth--; } // Funzioni esportate ///////////////////////////////////////////////////////////// // Il parametro pszRootPath è il percorso completo della directory da esaminare // Il parametro fRecurse è un valore booleano che indica // se vogliamo leggere anche le sottodirectory. Se impostato a FALSE, la funzione // legge solo la directory passata nel parametro pszRootPath // Il parametro pfnOnChange è un puntatore a una funzione evento che deve essere // implementata dal client ( il programma che utilizza la DLL ) void getDirInfo(LPCTSTR pszRootPath, BOOL fRecurse, uint64_t *pDim, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA)) { DIRWALKDATA DW; DW.szBuf[0] = '\0'; DW.szCurrDir[0] = '\0'; DW.szCurrPath[0] = '\0'; DW.szInitPath[0] = '\0'; DW.szPathParent[0] = '\0'; // nDepth è usato per controllare l'indentazione. Il valore -1 // fa si che il primo livello sia visualizzato allineato a sinistra DW.nDepth = -1; DW.fRecurse = fRecurse; _tcscpy(DW.szInitPath, pszRootPath); _tcscpy(DW.szCurrPath, pszRootPath); // Leggiamo il contenuto della directory passata nel parametro pszRootPath. // Se il parametro fRecurse è TRUE, leggiamo anche le sottodirectory DirWalkRecurse(&DW, pDim, pfnOnChange); } Codice:
#include <windows.h> #include <stdio.h> #include <stdint.h> #include "scandir.h" void CALLBACK OnChange(LPDIRWALKDATA pDW) { printf("# -> %s\n", pDW->szBuf); } int main(int argc, char* argv[]) { uint64_t dim = 0; if( argc < 2 ) return -1; getDirInfo(argv[1], TRUE, &dim, OnChange); printf("\nLa dimensione della directory \"%s\" e': %llu byte\n", argv[1], (unsigned long long)dim); return 0; } Ultima modifica di Vincenzo1968 : 07-03-2013 alle 22:43. |
![]() |
![]() |
![]() |
#19 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
|
![]() |
![]() |
![]() |
#20 | |
Senior Member
Iscritto dal: May 2007
Città: Milano
Messaggi: 7103
|
Quote:
Inviato dal mio Sony Xperia P
__________________
Apple Watch Ultra + iPhone 15 Pro Max + Rog Ally + Legion Go |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 09:28.