2011-08-11 5 views
5

Proste pytanie:Operacje na plikach C: Sprawdź tryb dostępu do wskaźnika otwartych plików

Jak sprawdzić tryb dostępu już otwartego wskaźnika pliku?

Tak mówią funkcja jest zdany już otwarty wskaźnik pliku:

//Pseudo code 
    bool PseudoFunction(FILE *Ptr) 
    { 
     if(... Insert check for read-only access rights) 
     { 
      //It's read only access mode 
      return true; 
     } 
     //File pointer is not read-only and thus write operations are permitted 
     return false; 
    } 

Co chciałbym użyć w instrukcji if, aby sprawdzić wskaźnik pliku został otwarty tylko do odczytu (lub nie, jak w przypadku może być), bez zapisywania do pliku i bez polegania na przekazywaniu (ewentualnie sprzecznych) argumentów przez użytkownika?

System to Windows, kod :: blokuje kompilator, ale w interesie przenoszenia kodu preferowana jest kompatybilność krzyżowa.

Uwaga, to nie pyta o prawa do plików, ale jaki tryb dostępu został użyty przez wskaźnik PLIK.

SELF-ODPOWIEDŹ [Nie można dołączyć osobną odpowiedź ze względu na ograniczenia praw użytkowników]:

Jest lepsza odpowiedź innym plakacie poniżej, który zawiera odpowiednie #defines

Jak wcześniej sugerowane , wygląda na to, że znacznik PLIKU _flag (zdefiniowany pod _iobuf) jest kluczem do ustalenia, czy plik jest tylko do odczytu. Może się wahać chociaż, ale te same podstawowe pojęcia powinny być łatwo dostosować, przykładowy kod:

#define READ_ONLY_FLAG 1 

bool PrintFlagPtr(const char FileName[], const char AccessMode[]) 
{ 
    FILE *Ptr = NULL; 
    Ptr = fopen(FileName,AccessMode); 
    printf("%s: %d ",AccessMode,Ptr->_flag); 

    int IsReadOnly = Ptr->_flag; 
    fclose(Ptr); 
    Ptr = NULL; 


    if((IsReadOnly&READ_ONLY_FLAG) == READ_ONLY_FLAG) 
    { 
     printf("File is read only!\n"); 
     return true; 
    } 

    printf("\n"); 
    return false; 
} 

, że gdy wszystkie różne kombinacje tryb dostępu stosowane są z powyższej funkcji, produkuje moc:

Output: 
w: 2 
r: 1 File is read only! 
a: 2 
wb: 2 
rb: 1 File is read only! 
ab: 2 
w+: 128 
r+: 128 
a+: 128 
w+b: 128 
r+b: 128 
a+b: 128 

Jestem ciekawy, dlaczego nigdy nie zostało to zasugerowane (lub nigdy nie było używane), biorąc pod uwagę kompatybilność krzyżową funkcji front-end (po prostu funkcja o tej samej nazwie, z deklaracjami zależnymi od platformy) przekazującą const int pochodzącą z dany wskaźnik FILE _flag byłby dość prostym i łatwym rozwiązaniem problemu.

+0

Unikaj używania wyroczni, aby odkryć coś, co jest dobrze znane w twoim programie. Jakiś kod tworzy PLIK, ten kod również wie, * jak * został utworzony. Dodaj argument do swojej funkcji. –

+0

Faktycznie, poleganie na tym, aby użytkownik poinformował nas, jakie prawa dostępu ma plik, jest nieprawidłowy (jak podano), ponieważ jest to luka w zabezpieczeniach. I to jest programowanie, a nie prognozy - część kodu już wie, jakie prawa dostępu są, aby móc popełnić błąd podczas używania poleceń putc i podobnych. – SSight3

+0

Nie mam pojęcia, dlaczego uważasz, że użytkownik ma coś z tym wspólnego. Wymaga od programisty C przekazywania argumentów do funkcji. Jeśli nie ufasz programistom, wszystkie zakłady są wyłączone. –

Odpowiedz

2

Warning: ta odpowiedź jest specyficzne dla Visual Studio 2010.


stdio.Plik h, który pochodzi z Visual Studio 2010 określa typ pliku tak:

struct _iobuf { 
    char *_ptr; 
    int _cnt; 
    char *_base; 
    int _flag; 
    int _file; 
    int _charbuf; 
    int _bufsiz; 
    char *_tmpfname; 
}; 
typedef struct _iobuf FILE; 

Kiedy fopening plik z trybu „rb”, to dostaje wartość 0x00000001.

W funkcji fopen, niektóre z flagami jesteś w interesed mogą być odwzorowywane jak poniżej:

r _IOREAD 
w _IOWRT 
a _IOWRT 
+ _IORW 

Te stałe są zdefiniowane w stdio.h:

#define _IOREAD   0x0001 
#define _IOWRT   0x0002 
#define _IORW   0x0080 

podległe pliki deskryptor zawiera więcej informacji, jeszcze nie wykopałem.

+0

Ponieważ twoja odpowiedź zawiera więcej informacji niż moja odpowiedź (nie mogłem znaleźć #defines w kodzie :: bloki [działa dla kodu :: blokuje też], ale podobny kontekst), wybiorę twój.Dodałbym tylko sugestię funkcji front-endowej, która umożliwia dostęp do pliku _file, więc w różnych systemach operacyjnych funkcja może być ponownie zdefiniowana zgodnie z potrzebami. Dziękuję Ci! – SSight3

1

Nie ma standardowego sposobu, aby to osiągnąć.

+0

Co się dzieje z dostępem do _flag pod wskaźnikiem PLIK? Z pewnością zawiera on atrybuty do odczytu/zapisu jako flagi int i wystarczy porównać go z dowolnymi wstępnie zdefiniowanymi liczbami, aby się dowiedzieć? Chociaż jestem pewien, że to może być źle na to patrzone, nie rozumiem, dlaczego nie tak długo, jak _flag jest traktowany jako const i traktowany pod osłonami (i na pewno lepszy niż być może niewygodna praca dookoła?). Wydaje się dziwne, że program może wiedzieć, że wskaźnik PLIKU jest tylko do odczytu (i dlatego nie chce pisać), ale ja jako programista nie mogę. – SSight3

+1

FILE jest nieprzejrzysty, nie wiesz, których członków ma. – AProgrammer

+0

Samo pisanie klasy PLIK {}; i zmuszanie kompilatora do narzekania na wcześniej zadeklarowaną instancję FILE ujawnia, jakich członków ma. Będąc dobrze zdefiniowaną klasą _iobuf, zawsze można w razie potrzeby wyszukać w Internecie. – SSight3

3

W systemie Linux (i ewentualnie wszystkich systemów UNIX) można użyć fcntl aby uzyskać tryb dostępu do pliku:

int get_file_status(FILE* f) { 
    int fd = fileno(f); 
    return fcntl(fd, F_GETFL); 
} 

Zauważ, że zwracana jest wartość nie jest liczbą całkowitą jako kombinacja flag jak O_RDONLY lub O_RDWR, a nie ciągi znaków "r" lub "w+". Dla niektórych z tych flag patrz http://pubs.opengroup.org/onlinepubs/007908799/xsh/open.html.

Not sure about Windows, zobacz On Windows/mingw, what is the equivalent of `fcntl(fd, F_GETFL) | O_ACCMODE`?.

+0

Pytanie, z którym łączyłeś się w systemie Windows, wydaje się mieć 7 miesięcy i nie ma odpowiedzi. – SSight3

Powiązane problemy