Jakie są różnice i w jakich przypadkach jeden lub drugi w jakiś sposób okaże się lepszy?Czy w systemie Windows powinienem użyć funkcji CreateFile lub fopen?
Odpowiedz
Przede wszystkim funkcja fopen
może być używana tylko do prostych operacji przenośnych z plikami.
CreateFile
po drugiej stronie można używać nie tylko do operacji na plikach, ale także do katalogów (przy użyciu odpowiednich opcji), potoków i różnych urządzeń z systemem Windows.
CreateFile
ma wiele dodatkowych przydatnych przełączników, jak FILE_FLAG_NO_BUFFERING
, FILE_ATTRIBUTE_TEMPORARY
i FILE_FLAG_SEQUENTIAL_SCAN
, które mogą być bardzo przydatne w różnych scenariuszach.
Możesz użyć CreateFile
z nazwą pliku dłuższą niż MAX_PATH
znaków. Może to być ważne w przypadku niektórych aplikacji serwerowych lub takich, które muszą być w stanie otworzyć dowolny plik (np. Skaner antywirusowy lub aplikacja do tworzenia kopii zapasowych). Jest to możliwe dzięki użyciu semantyki przestrzeni nazw, chociaż ten tryb ma swoje własne obawy, takie jak zdolność do utworzenia pliku o nazwie ".."
lub L"\xfeff\x20\xd9ab"
(powodzenia, próbując usunąć je później).
Możesz użyć CreateFile
w różnych scenariuszach bezpieczeństwa. Mam na myśli nie tylko wykorzystanie atrybutów bezpieczeństwa. Jeśli bieżący proces ma uprawnienie SE_BACKUP_NAME lub SE_RESTORE_NAME (jak zwykle Administratorzy) i włącza ten przywilej, można użyć CreateFile
do otwarcia dowolnego pliku również pliku, do którego nie masz dostępu poprzez deskryptor zabezpieczeń.
Jeśli chcesz tylko odczytać zawartość pliku, możesz użyć map CreateFile
, CreateFileMapping
i MapViewOfFile
, aby utworzyć mapowanie pliku. Wtedy możesz pracować z plikiem jak z blokiem pamięci, co może zwiększyć szybkość twojej aplikacji.
Istnieją także inne zastosowania funkcji, które są opisane szczegółowo w the corresponding MSDN article.
Więc mogę podsumować: tylko jeśli masz twardą wymagania przenośności lub jeśli trzeba zdać FILE*
do jakiejś zewnętrznej biblioteki, wtedy musisz użyć fopen
. We wszystkich innych przypadkach zalecam użycie CreateFile
. Aby uzyskać najlepsze wyniki, radziłbym również zapoznać się z interfejsem API systemu Windows, ponieważ istnieje wiele funkcji, które można wykorzystać.
ZAKTUALIZOWANY: Nie jest to bezpośrednio związane z pytaniem, ale polecam również przejrzeć funkcje transactional I/O, które są obsługiwane począwszy od systemu Windows Vista. Korzystając z tej funkcji, można zatwierdzić kilka operacji na plikach, katalogach lub rejestrze jako jedną transakcję, której nie można przerwać. To bardzo potężne i ciekawe narzędzie. Jeśli nie jesteś jeszcze gotowy do korzystania z transakcyjnych funkcji wejścia/wyjścia, możesz zacząć od CreateFile
i przenieść aplikację na transakcyjne operacje we/wy później.
To naprawdę zależy od rodzaju programu, który piszesz. Jeśli ma być przenośny, fopen
ułatwi Ci życie. fopen
zadzwoni pod numer CreateFile
"za kulisami".
Niektóre bardziej zaawansowane opcje (kontrola pamięci podręcznej, kontrola dostępu do plików itp.) Są dostępne tylko w przypadku korzystania z interfejsu Win32 API (zależą one od uchwytu pliku Win32, w przeciwieństwie do wskaźnika FILE
w stdio), więc jeśli piszą czystą aplikację Win32, możesz użyć CreateFile.
CreateFile pozwala Ci
- otworzyć pliku do asynchronicznego I/O
- wskazówki optymalizacyjne Przełęcz jak FILE_FLAG_SEQUENTIAL_SCAN
- ustawić zabezpieczenia i dziedziczą ustawienia bez problemów wątków
Oni nie zwracają ten sam typ uchwytu, z obiektem fopen/FILE można wywoływać inne funkcje uruchomieniowe, takie jak fputs (a także konwertowanie go do "macierzystego" uchwytu pliku)
O ile jest to możliwe, preferuj opakowania jednostkowe, które obsługują RAII, takie jak Fstream lub zwiększ obiekty IO pliku.
Należy oczywiście zadbać o tryb udostępniania, więc fopen() i STL są niewystarczające.