2013-03-21 4 views
5

Ich habe einen Dateideskriptor, der mit dem Ergebnis einer open() - Funktion auf einen positiven Wert gesetzt ist, so dass fd eine Datei anzeigt. Wenn ich die tatsächliche Datei lösche, ist fd immer noch eine positive Ganzzahl. Ich möchte wissen, dass, wenn ich eine Datei aus irgendeinem Grund lösche, wie kann ich wissen, dass dieser Dateideskriptor nicht mehr gültig ist. Kurz gesagt, wie kann ich wissen, dass die Datei, die fd anzeigt, immer noch da ist oder nicht. Ich versuche dies in C unter FreeBSD zu machen.Wie überprüft man, ob eine Datei mit einem Dateideskriptor noch existiert?

+0

Versuchen Sie, in die Datei zu schreiben oder zu lesen. Das sollte einen Fehler zurückgeben. – RedX

+2

@RedX, so funktioniert UNIX nicht. – LtWorf

+0

Ja ich weiß, dass ich diese Datei lesen oder öffnen muss, aber gibt es eine Möglichkeit, eine Datei mit nur fd zu öffnen oder zu lesen? Gibt es eine Funktion zum Lesen oder Öffnen mit nur fd, kein Pfad oder FILE * –

Antwort

4

Unix-Systeme können Sie offene Dateien löschen (oder löschen Sie alle Verweise auf die Datei aus dem Dateisystem). Aber der Dateideskriptor ist immer noch gültig. Alle Lese- und Schreibaufrufe sind erfolgreich, so wie sie es auch bei dem Dateinamen tun würden.

Mit anderen Worten, Sie können eine Datei nicht vollständig löschen, bis der Dateideskriptor geschlossen ist. Nach dem Schließen wird die Datei automatisch entfernt.

Mit einem gültigen Dateideskriptor können Sie überprüfen, ob der Dateiname noch vorhanden ist, z.

printf("%d\n", buf.st_nlink); // 0 means no filenames 

Wo buf ist ein struct stat mit fstat initialisiert.

+0

Danke für den Rat, aber das ist eine andere Situation, vor der ich stehe. Ich muss nur überprüfen, ob die Datei, die fd anzeigt, immer noch da ist oder nicht. Wenn nicht, was ist der Weg, das über fd zu lernen? –

+1

@HasanBozok - Sie können 'fstat' für den gültigen Dateideskriptor verwenden, um die Anzahl der festen Links zu erhalten. Wenn es 0 ist, wurden die Dateinamen gelöscht. – teppic

+0

@teppic, Gibt es einen Weg ['ioctl] (http://pubs.opengroup.org/onlinepubs/009696699/functions/ioctl.html) kann verwendet werden, um die Datei tatsächlich zu löschen? Wenn das möglich wäre, wäre das gefährlich? –

1

Bevor Schreiben in die Datei können Sie überprüfen, ob es access() mit noch da ist

if (access("/yourfile",W_OK)!=-1) { 
    //Write on the file 
} 

Sie auch auf dem Descriptor do fstat kann:

struct stat statbuf; 
fstat(fd,&statbuf); 
if (statbuf.st_nlink > 0) { 
    //File still exists 
} 

Aber es wird die Software nach unten ein langsamer viel, und auch ein Programm könnte die Datei woanders verlinken und den ursprünglichen Namen aufheben, so dass die Datei immer noch existiert, aber unter einem anderen Namen/Ort, und diese Methode würde das nicht erkennen.

Eine viel bessere Alternative wäre inotify auf GNU/Linux zu verwenden, oder kqueue auf BSD, aber ich habe nie die zweite verwendet.

Sie können diese API verwenden, um Änderungen in Verzeichnissen zu beobachten und Benachrichtigungen vom Kernel abzurufen und ein Ereignis zu erhalten, wenn Ihre Datei von einem anderen Prozess gelöscht wird, und etwas dagegen tun.

Denken Sie daran, dass diese Ereignisse nicht in Echtzeit sind, so dass Sie die Datei noch für einige Millisekunden verwenden können, bevor Sie das Ereignis erhalten.

Verwandte Themen