2011-02-01 22 views
12

Powiel możliwe:
Getting Filename from file descriptor in CCzy istnieje sposób na pobranie nazwy pliku z pliku `FILE *`?

Czy istnieje prosty i (rozsądnie) przenośny sposób na uzyskanie nazwę pliku z pomocą FILE*?

Otwieram plik za pomocą f = fopen(filename, ...), a następnie przekazuję f do różnych innych funkcji, z których część może zgłosić błąd. Chciałbym zgłosić nazwę pliku w komunikacie o błędzie, ale należy unikać przekazywania dodatkowego parametru.

Mogę utworzyć niestandardową owijkę struct { FILE *f, const char *name }, ale czy jest może prostszy sposób? (Jeśli FILE* nie został otwarty przy użyciu fopen, nie obchodzi mnie wynik.)

+0

duplikat http://stackoverflow.com/questions/1188757/getting-filename-from-file-descriptor-in-c –

+1

Nie ma standardowego sposobu, który znam; 'freopen' pozwoli ci zmienić tryb odczytu/zapisu oraz binarny/normalny, ale jeśli chcesz mieć nazwę dla siebie (powiedzmy, żeby wydrukować komunikat o błędzie) masz pecha. – dmckee

+0

Ponieważ używasz systemu, który ma strukturę plików, wątpię, czy "pomijanie dodatkowego parametru" jest nawet problemem? Jaki jest twój powód, by tego nie przekazywać? Wydajność? – Lundin

Odpowiedz

12

na niektórych platformach (takich jak Linux), może być w stanie sprowadzić go czytając ogniwo /proc/self/fd/<number>, a więc:

#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 

int main(void) 
{ 
    char path[1024]; 
    char result[1024]; 

    /* Open a file, get the file descriptor. */ 
    FILE *f = fopen("/etc/passwd", "r"); 
    int fd = fileno(f); 

    /* Read out the link to our file descriptor. */ 
    sprintf(path, "/proc/self/fd/%d", fd); 
    memset(result, 0, sizeof(result)); 
    readlink(path, result, sizeof(result)-1); 

    /* Print the result. */ 
    printf("%s\n", result); 
} 

To w moim systemie wydrukuje /etc/passwd, zgodnie z życzeniem.

+0

I co to jest drukowane na anonimowej fajce? – dmckee

+0

@dmckee: 'pipe: []' – intelfx

2

To trochę trudne, ponieważ PLIK * może odczytać/zapisać z uchwytu pliku, który nie jest powiązany z nazwanym plikiem w ogóle (na przykład nienazwana rura lub gniazdo). Możesz uzyskać uchwyt pliku z fileno(), a następnie istnieją systemowe sposoby, aby dowiedzieć się o nazwie pliku. Oto dyskusja na temat, jak to zrobić w Linuksie:

Getting Filename from file descriptor in C

a pod Windows nie jest to dużo łatwiejsze albo:

http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx (jako dodatkowy krok tu użyć _get_osfhandle(), aby uzyskać plik uchwyt Windows z deskryptora pliku c-biblioteka)

Powiązane problemy