Verzeichnisgröße ermitteln

himero

Jungspund
Beiträge
15
Hallo!

Brauch eure Hilfe bei folgendem Problem: Ich will ein C/C++ Programm schreiben, dass mir die Größe eines angegebenen Ordners/Verzeichnis anzeigt. Mit stat kann ich mir ja leider nur die Größe einzelner Files ermitteln lassen. Hat jemand eine Idee, wie ich das realisieren kann?

Vielen Dank
 

hazelnoot

www.mywm.dl.am
Beiträge
377
unter linux kannst du schon die groesse eines verzeichnisses ermitteln da verzeichnisse wie dateien gehandhabt werden...

unter windows ist dies nicht der fall

mfg
hazelnoot
 

tuxlover

Der den Tux knuddelt
Beiträge
2.106
wieso ist der thread eigentlich unter C/C++ eingeordnet. jemand sollte ihn verschieben da wo er hingehört.
 

hazelnoot

www.mywm.dl.am
Beiträge
377
Dann ist das ja mit stat ebenso Schwachsinn.

wieso? unter linux/unix kann man die groesse eines verzeichnisses ermitteln(wegen dem oben genannten grund: unter linux sind dirs ebenfalls dateien) mit stat(st_size)!!!! aber auch nur unter linux/unix unter windows wuerde das nicht gehen!! probiers aus ich weis dass es geht!!!

mfg hazelnoot
 

himero

Jungspund
Beiträge
15
du, df und die ganzen Befehle bringen mir nichts - ich muss das ganze in einem c/++ Programm realisieren können. Hab das mal mit stat(st_size) versucht - siehe Code im Anhang. Leider bekomme ich bei Angabe eines Verzeichnisses nur die Blockgröße der Platte (4096).
 
Zuletzt bearbeitet:

hazelnoot

www.mywm.dl.am
Beiträge
377
dann koenntest du es noch so machen dass du einfach das verzeichniss durchgehst und alle groessen der dateien addierst ungefaehr so:

Code:
int funktionGetSizeOfDir(const char *dir){
   int size = 0;

   gehe das dir durch{
       hohle aktuelles file
       if(aktuelles file ist ein directory){/*das kannst in der statstruktur ueber den parameter mode mit der bitmask S_IFDIR herasfinden*/
             size += funktionGetSizeOfDir(aktuelles file);
       }else{
             size += sizeVonDemAktuellen file;
       }       
   } 
   return size;
}

denke so koenntest du das machen

ich hoffe ich konnte dir helfen also ich wuerde es so machen waenn stat, wie ich gemerkt habe, nicht das gewuenschte ergebnis liefert.
 

himero

Jungspund
Beiträge
15
Vielen Dank schonmal!
Das Gerüst schaut gut aus - nur habe ich Probleme mit der Umsetzung. Wie genau kann ich das dir durchgehen und die files holen?
 

hazelnoot

www.mywm.dl.am
Beiträge
377
aaalso das koenntest du folgendermassen loesen:
Code:
/*includes*/
#include <sys/types.h>
#include <dirent.h>

/*bla bla bla*/

DIR *dir;
struct dirent *pnt;

dir = opendir(dir);/*gibt bei fehler NULL zurueck*/

/*nun hohlen wir uns die erste datei*/
pnt = readdir(dir);
printf("name der ersten file/dir: %d", (*pnt).d_name);

tja denke das erklaert alles waenn du wiederhohlt readdir aufrufst bekommst du die 2te datei nochmal die dritte usw waenn alles wech ist bekommst NULL zurueck mit seekdir kannst dann drinnen umeinandersausen

die dirent struktur enthaelt folgendes:
(das sind die dinge an die ich mich erinnern kann)
also einen long mit der nodenr glaub d_ino dann eben den verzeichnissnamen d_name und einen int d_namelen wo die laenge des dateinamens drinnensteht das ist das was ich im gedaechtnis habe koennen noch etwas mehr sein aber mehr hab ich bis jetzt noch nicht gebraucht :-)

mfg
hazelnoot
 

himero

Jungspund
Beiträge
15
Hallo!

Ich habe es nun geschafft, die Verzeichnisgröße zu ermitteln (siehe Code im Anhang). Leider gelingt dies nur, wenn ausschließlich reguläre Dateien in diesem Verzeichnis sind. Sobald ich ein weiteres Verzeichnis darin befindet, bekomme ich Probleme. Hat jemand eine Idee dies zu realisieren.

Vielen Dank
 
Zuletzt bearbeitet:

himero

Jungspund
Beiträge
15
Hab's mal versucht - leider bekomme ich einen Segmentation fault Fehler. Vielleicht kann mir jemand sagen, wo der Fehler im Code liegt!?
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <iostream.h>
#include <string>
#include <stdlib.h>
#include <string>
#include <unistd.h>
using namespace std;

class DiskUtil4 {

private:
DIR *_dir;
struct dirent *_dirpointer;
struct stat _filesize;
unsigned long _size;
int _locStatus;

public:

DiskUtil4();
~DiskUtil4();

int GetUsedDirectorySpace(string path_, unsigned long& filesize_) {

if((_dir=opendir(path_.c_str())) == 0) {
cout<<"Error while opening path"<<endl;
}
while((_dirpointer = readdir(_dir)) != 0) {
if(stat((char*)_dirpointer->d_name, &_filesize) == -1) {
return -1;
}

else if((_dirpointer->d_name != ".") || (_dirpointer->d_name != "..")) {

if(_filesize.st_mode & S_IFDIR) {
GetUsedDirectorySpace(_dirpointer->d_name, filesize_);
}
else if(_filesize.st_mode & S_IFREG) {

_size = _filesize.st_size;
filesize_ = filesize_ + _size;
cout<<"Filename: "<<_dirpointer->d_name<<endl;
cout<<"Filesize: "<<_size<<endl;
}
}
else {
filesize_ = filesize_ + _filesize.st_blksize;
}
}
closedir(_dir);
}
};

DiskUtil4::DiskUtil4() {
unsigned long _size=0;
}

DiskUtil4::~DiskUtil4() {
}

int main() {

DiskUtil4 probe;
string path_="/home/a121653/Projekte";
unsigned long test=0;


probe.GetUsedDirectorySpace(path_.c_str(),test);
cout<<"Directory Size: "<<test/1024<<"KB"<<endl;
}
 

hazelnoot

www.mywm.dl.am
Beiträge
377
@himero

waenn du meinen "pseudocode" umgesetzt haettest dann wuerdest kein problem haben da dieser code eine rekursion enthaelt:
Code:
int funktionGetSizeOfDir(const char *dir){
   int size = 0;

   gehe das dir durch{
       hohle aktuelles file
       if(aktuelles file ist ein directory){/*das kannst in der statstruktur ueber den parameter mode mit der bitmask S_IFDIR herasfinden*/
             [B]size += funktionGetSizeOfDir(aktuelles file);[/B]/*hier ist die rekurstion die selbe funktion mit dem aktuellen dir aufrufen*/
       }else{
             size += sizeVonDemAktuellen file;
       }       
   } 
   return size;
}

hab den pseudocode mal ausprogrammiert:
Code:
#include <stdio.h>
#include <sys/stat.h>
#include <dirent.h>

int getDirSize(const char *dirname){
   DIR *dir;
   char fullDirName[500];
   struct dirent *dirPnt;
   struct stat aktFile;
   int size = 0;
   
   /*open the akt dir*/
   sprintf(fullDirName, "%s/", dirname);
   if((dir = opendir(fullDirName)) == NULL){
      printf("Konnte %s nich oeffnen\n", fullDirName);
      return 0;
   }
   
   /*go through the directory*/
   while( (dirPnt = readdir(dir)) != NULL ){
      if(strcmp((*dirPnt).d_name, "..") == 0 ||
         strcmp((*dirPnt).d_name, ".") == 0){
         continue;
      }
   
      /*create the akt filepath*/
      sprintf(fullDirName, "%s/%s", dirname, (*dirPnt).d_name);
      if(stat(fullDirName, &aktFile) == -1){
         continue;
      }
      
      /*file*/
      if(aktFile.st_mode & S_IFREG){
         size += aktFile.st_size;
      }else if(aktFile.st_mode & S_IFDIR){/*dir*/
         size += getDirSize(fullDirName);
      }
      
      //printf("%s\n", fullDirName);
   }
   
   closedir(dir);
   
   return size;
}

int main(void){
   printf("%d\n", getDirSize("/home/hazelnoot"));
}

hoffe das funkt so hat schnell gehen muessen da ich noch physik lernen muss :-( und dann tanzkurs habe :-(((((((((((((((((((

mfg hazelnoot
 
Zuletzt bearbeitet:

himero

Jungspund
Beiträge
15
Danke - hab den Fehler gefunden. Allerdings habe ich nun ein Problem bei der Erkennung von Link's. Ich brauche dir Größe der Link's im Verzeichnis und nicht die Größe der Datei auf die der Link zeigt. Eigentlich sollte dies doch mit lstat anstelle von stat funktionieren, oder? Habe allerdings bei der Anwendung Probleme
 

himero

Jungspund
Beiträge
15
Im Anhang befindet sich mein Programm. Die Stelle an der mein Problem liegt, ist gekennzeichnet. Vielleicht hat jemand eine Idee, wie ich das Problem lösen kann. Ich brauche die Ausgabe der Größe des Link's und nicht die Ausgabe der Größe der Datei auf die
der Link zeigt.
 

Anhänge

  • DirSpace.doc
    13,5 KB · Aufrufe: 1

Ähnliche Themen

Port Forwarding mit iptables

wget: Lädt bestimmte Dateitypen nicht

SELinux und IPTV

RHEL 8.0 Partitionsreihenfolge in der Kickstart-Datei festlegen

Apache HTTP Server startet nicht

Oben