Größe einer Datei ermitteln, ohne diese zu oeffnen



  • Hallo,

    ich wuerde gerne die Größe einer Datei ermitteln, ohne diese vorher mit fopen zu öffnen, da dies nicht in meinem Fall nicht möglich ist.

    Gibt es da eine andere Moeglichkeit?

    Habe die Möglichkeit mit fstat gesehen (http://codewiki.wikidot.com/c:system-calls:fstat), da wird aber auch die Datei mit open geöffnet. Das ist leider schlecht, da die open-Funktion genau die filegröße benötigt (ich überschreibe diese).

    Edit: Argh, Forum verwechselt, gehört eigentlich ins C-Forum!



  • Unter Linux würdest du es mit man: stat(2) machen, in reinem C geht das nicht.



  • Ich benutze Linux, kein Windows, und das Programm wird nur unter Linux laufen, wollte ich noch anmerken.



  • Fabulus schrieb:

    Edit: Argh, Forum verwechselt, gehört eigentlich ins C-Forum!

    Nein, du bist hier schon richtig, siehe Bashars Antwort.



  • Okay, mit stat hab ich jetzt herausgefunden, wie ich die Ordner-/Dateigröße ermittel.

    Jetzt hab ich eine weitere Frage: Ist genau dies auch möglich mit dem noch vorhandenen Platz auf einem filesystem? Also kann ich den vorhandenen Platz in einem bestimmten fs oder Ordner herausfinden?


  • Mod

    Fabulus schrieb:

    Okay, mit stat hab ich jetzt herausgefunden, wie ich die Ordner-/Dateigröße ermittel.

    Jetzt hab ich eine weitere Frage: Ist genau dies auch möglich mit dem noch vorhandenen Platz auf einem filesystem? Also kann ich den vorhandenen Platz in einem bestimmten fs oder Ordner herausfinden?

    Mit statfs und Konsorten.

    Und du solltest lernen, wie man sich solche Fragen mittels Google und/oder Referenzen selber beantworten kann. Das ist eine essentielle Fähigkeit für Programmierer.



  • Fabulus schrieb:

    Ist genau dies auch möglich mit dem noch vorhandenen Platz auf einem filesystem? Also kann ich den vorhandenen Platz in einem bestimmten fs oder Ordner herausfinden?

    Das geht zwar, aber die Einschränkungen sollten dir bewusst sein:

    Wenn du X Megabytes im Dateisystem frei hast, heißt das *nicht*, dass du auch Dateien im Wert von X Megabytes anlegen kannst.

    Andersrum heißen X freie Megabytes aber auch nicht, dass du nur X Megabyte schreiben kannst. Vielleicht kannst du viel größere Dateien schreiben.

    Die Angabe wieviel Megabytes im Dateisystem frei sind ist bei modernen Dateisystemen (vor allem btrfs) eher als pi*daumen zu sehen und auf keinen Fall präzise aufs Byte. Du musst in jedem Fall einfach anfangen die Dateien zu schreiben und am Ende schauen, ob das geklappt hat. Wenn ein Programm im Vorfeld abbricht wegen nicht ausreichendem freien Speicherplatz, ist das für den User extrem nervig, aus den eben genannten Gründen.

    Vielleicht erinnerst du dich auch an manche alten Computerspiele für Windows. Der Installer prüft am Anfang, ob genug freier Speicherplatz da ist. Er lädt dafür die Anzahl der freien Bytes in einen 32-Bit unsigned integer. Wenn die Partition mehr als 4 Gigabyte freien Speicher hat, gibt es einen integer overflow und der Installer weigert sich, das Spiel zu installieren, obwohl viele hundert Gigabytes freier Speicher vorhanden sind. Mach sowas bitte nicht. 🙂



  • Christoph schrieb:

    Andersrum heißen X freie Megabytes aber auch nicht, dass du nur X Megabyte schreiben kannst. Vielleicht kannst du viel größere Dateien schreiben.

    [...]

    Du musst in jedem Fall einfach anfangen die Dateien zu schreiben und am Ende schauen, ob das geklappt hat. Wenn ein Programm im Vorfeld abbricht wegen nicht ausreichendem freien Speicherplatz, ist das für den User extrem nervig, aus den eben genannten Gründen.

    Argh. Es ist aber auch extrem nervig wenn das Programm anfängt zu kopieren und dann irgendwann abbricht, weil nicht genug Platz da ist.



  • DrGreenthumb schrieb:

    Christoph schrieb:

    Andersrum heißen X freie Megabytes aber auch nicht, dass du nur X Megabyte schreiben kannst. Vielleicht kannst du viel größere Dateien schreiben.

    [...]

    Du musst in jedem Fall einfach anfangen die Dateien zu schreiben und am Ende schauen, ob das geklappt hat. Wenn ein Programm im Vorfeld abbricht wegen nicht ausreichendem freien Speicherplatz, ist das für den User extrem nervig, aus den eben genannten Gründen.

    Argh. Es ist aber auch extrem nervig wenn das Programm anfängt zu kopieren und dann irgendwann abbricht, weil nicht genug Platz da ist.

    Ja, aber das ist üblich unter Linux. Wenn das Programm ein Terminal-Programm ist, würde ich nichts anderes erwarten, denn nichts ist nerviger als ein Programm, das normalerweise keine Rückfragen stellt, aber in irgendeinem Spezialfall dann plötzlich den ganzen Cronjob oder ähnliches blockiert, weil es auf Nutzer-Interaktion wartet.

    Bei einem interaktiven Programm mit GUI wär ein Kompromiss vielleicht, dass dem User vorm Schreiben der Dateien eine Warnung angezeigt wird "der freie Speicherplatz wird möglicherweise nicht ausreichen. Trotzdem schreiben?". In jedem Fall sollte man das Programm überzeugen können, dass es die Dateien schreibt, auch wenn der freie Speicherplatz scheinbar nicht ausreicht.

    Vor allem berücksichtigt statfs etc. keine quotas, damit ist bei größeren Linux-Systemen quasi garantiert, dass die Angabe des freien Speichers für ein normales Programm vollkommen nutzlos ist.



  • Christoph schrieb:

    Bei einem interaktiven Programm mit GUI wär ein Kompromiss vielleicht, dass dem User vorm Schreiben der Dateien eine Warnung angezeigt wird "der freie Speicherplatz wird möglicherweise nicht ausreichen. Trotzdem schreiben?". In jedem Fall sollte man das Programm überzeugen können, dass es die Dateien schreibt, auch wenn der freie Speicherplatz scheinbar nicht ausreicht.

    ja definitiv. Aber das ginge auch bei einem nicht-gui Programm. z.B. mv -f könnte den Check überspringen.

    Vor allem berücksichtigt statfs etc. keine quotas, damit ist bei größeren Linux-Systemen quasi garantiert, dass die Angabe des freien Speichers für ein normales Programm vollkommen nutzlos ist.

    das wusste ich nicht... So macht das ganze dann tatsächlich keinen Spaß mehr.



  • DrGreenthumb schrieb:

    Christoph schrieb:

    [Ignorierbare Warnung anzeigen bei zu wenig Speicherplatz]

    Aber das ginge auch bei einem nicht-gui Programm. z.B. mv -f könnte den Check überspringen.

    Wenn das Verhalten default ist, finde ich das bei cronjobs sehr störend. "Nicht genug Speicherplatz da" tritt eben so selten auf, dass man es vermutlich nicht getestet hat.

    Ein hängender Cronjob, der auf Nutzereingabe wartet, ist IMHO schlimmer als ein cronjob, der in so einem Fall einfach mittendrin abbricht. Wenn ein cronjob abbricht, wird nämlich der Admin benachrichtigt, wenn ein cronjob hängt, kann er beliebig lange hängen.



  • Christoph schrieb:

    DrGreenthumb schrieb:

    Christoph schrieb:

    [Ignorierbare Warnung anzeigen bei zu wenig Speicherplatz]

    Aber das ginge auch bei einem nicht-gui Programm. z.B. mv -f könnte den Check überspringen.

    Wenn das Verhalten default ist, finde ich das bei cronjobs sehr störend. "Nicht genug Speicherplatz da" tritt eben so selten auf, dass man es vermutlich nicht getestet hat.

    Ein hängender Cronjob, der auf Nutzereingabe wartet, ist IMHO schlimmer als ein cronjob, der in so einem Fall einfach mittendrin abbricht. Wenn ein cronjob abbricht, wird nämlich der Admin benachrichtigt, wenn ein cronjob hängt, kann er beliebig lange hängen.

    auf Benutzereingabe warten habe ich auch nicht vorgeschlagen. Ich dachte schon an einen direkten Abbruch. Der Cronjob der bei cp vorher abbricht weil nicht genug Platz vorhanden ist, ist ja meistens besser als der, wo erstmal die Hälfte kopiert kopiert.

    Kommt natürlich immer auf den Fall an. Wenn ich ein Verzeichnis mit MP3s auf den USB-Stick ziehe, will ich i.d.R. das soviel wie geht kopiert wird.



  • Nur zur Information, worum es bei mir geht:
    Ich habe viele große Dateien auf 5 zugänglichen Filesystemen mit je 5 TB, auf die kann ich auch leicht zugreifen.
    Zudem habe ich aber einen großen Server (n vielen Dutzenden TB), auf dem der User nicht zugreifen kann. Wenn ich auf eine Datei zugreifen möchte, die auf diesem Server liegt, muss diese erst auf eines der andere FS verschoben werden, was extrem lange dauert.
    Deshalb ist es wichtig, dass genug Speicherplatz vorhanden ist.
    Da ist es extrem lästig, wenn man erst später merkt, nachdem etliche GB kopiert wurden, dass kein Platz da ist.

    Nur mal zur Info, von welcher Größenordnung ich hier spreche... Ist es also wirklich nicht möglich, vorher sicherzustellen, dass der Platz ausreicht?


  • Mod

    Fabulus schrieb:

    Nur mal zur Info, von welcher Größenordnung ich hier spreche... Ist es also wirklich nicht möglich, vorher sicherzustellen, dass der Platz ausreicht?

    Es gibt eben extrem viele Variablen. Jemand anderes könnte gleichzeitig etwas schreiben oder löschen. Der Admin könnte dir eine quota setzen, während du schreibst doer diese wieder aufheben. Ein Teil eines logischen Volumes könnte ausfallen und den Platz verringern. Etc.

    Aber wenn du das Programm nur für dich selber schreibst und du diese Dinge zumindest grob ausschließen kannst (die realistischen Fälle sind wohl das gleichzeite Lesen/Schreiben und eine festgesetzte quota), dann kannst du es mit den schon genannten Mitteln rausfinden. Denk auch dran, dass kleine Dateien mindestens einen vollen Block im FS belegen, du kannst mit statfs nicht nur den freien Platz rausbekommen, sondern auch die (vielleicht hilfreichere) Angabe wie viele Blöcke frei sind und wie groß ein Block ist.



  • Das Fileszstem wird ueber ein batch-Betriebssystem laufen, soweit ich weiss und nur darauf spezialisiert werden. Ich denke deshalb wird es sowas wie gleichzeitigen Zugriff nicht geben.

    Eine weitere Frage habe ich zu statfs:
    Bisher habe ich es so gemacht (zum testen):

    void report(struct statfs* );
    
    void report(struct statfs* buf) {
    
    	printf("blocks free: %ld\n", buf->f_bfree);
    
    }
    
    int main() {
    
    	struct statfs w1;
    
    	statfs("/tsm", &w1);
    
            /* So wueder ich es gerne machen */
    	long fs=tsm->f_bfree;
    
    	/* So funktioniert es */
    	report(&w1);
    	return 0;
    }
    

    Das Problem bei der ersten Variante, wie ich es machen will, es kommt der Fehler:

    filesize.c:33:13: error: invalid type argument of ‘->’ (have ‘struct statfs’)
    

    Wie mach ich es richtig?

    Edit:
    Eine weitere Sache zu stat:
    Ich muss ja auch vergleichen, wie gross die Bloecke sind. Der Typ ist aber nun blksize_t. Wie gebe ich das denn richtig aus ueber printf?

    printf("Blocksize: %ld", buf->st_blksize);
    

    Funktioniert schon mal nicht... Oder muss ich das vorher mit sizeof oder so aufrufen?



  • SeppJ schrieb:

    Denk auch dran, dass kleine Dateien mindestens einen vollen Block im FS belegen, du kannst mit statfs nicht nur den freien Platz rausbekommen, sondern auch die (vielleicht hilfreichere) Angabe wie viele Blöcke frei sind und wie groß ein Block ist.

    Wenn ich manche Threads auf der btrfs-Mailingliste richtig interpretiere, garantiert auch diese Angabe bei btrfs nicht, dass man auch tatsächlich noch so viele Blöcke schreiben kann. Es ist bei btrfs wohl möglich, dass zwar noch Platz für viele Datenblöcke da wäre, aber kein Platz mehr für Metadaten.

    Deswegen würde ich Fabulus in jedem Fall raten, dass der User diese Warnung ignorieren kann und die Datei trotzdem kopiert wird, auch wenn das Programm glaubt, dass nicht genug Speicher da wäre.


Anmelden zum Antworten