Jak mogę obliczyć rozmiar pliku w bajtach?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
char* filenie FILE* file? -1
Jak mogę obliczyć rozmiar pliku w bajtach?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
char* filenie FILE* file? -1
Odpowiedzi:
Na podstawie kodu NilObject:
#include <sys/stat.h>
#include <sys/types.h>
off_t fsize(const char *filename) {
struct stat st;
if (stat(filename, &st) == 0)
return st.st_size;
return -1;
}
Zmiany:
const char.struct statdefinicję, w której brakowało nazwy zmiennej.-1w przypadku błędu zamiast 0, co byłoby niejednoznaczne dla pustego pliku. off_tjest typem ze znakiem, więc jest to możliwe.Jeśli chcesz fsize()wydrukować komunikat o błędzie, możesz użyć tego:
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
off_t fsize(const char *filename) {
struct stat st;
if (stat(filename, &st) == 0)
return st.st_size;
fprintf(stderr, "Cannot determine size of %s: %s\n",
filename, strerror(errno));
return -1;
}
W systemach 32-bitowych należy to skompilować z opcją -D_FILE_OFFSET_BITS=64, w przeciwnym razie off_tbędą przechowywane tylko wartości do 2 GB. Szczegółowe informacje można znaleźć w sekcji „Korzystanie z LFS” w dokumencie Obsługa dużych plików w systemie Linux .
fseek+ ftellzgodnie z propozycją Dereka.
fseek+ ftellzgodnie z propozycją Dereka. Nie C Standardowy wyraźnie stanowi, że fseek()aby SEEK_ENDna plik binarny jest niezdefiniowane zachowanie. 7.19.9.2 fseekFunkcja ... Strumień binarny nie musi w znaczący sposób obsługiwać fseekwywołań o wartości pochodzeniaSEEK_END i, jak wspomniano poniżej, z przypisu 234 na str. 267 połączonego C standardowa, która specyficznie etykiet fseekdo SEEK_ENDw binarnego strumienia niezdefiniowana zachowanie. .
Nie używaj int. Pliki o rozmiarze ponad 2 gigabajtów są obecnie powszechne jako brud
Nie używaj unsigned int. Pliki o rozmiarze powyżej 4 gigabajtów są powszechne jako nieco mniej powszechny brud
IIRC biblioteka standardowa definiuje off_tjako 64-bitową liczbę całkowitą bez znaku, której każdy powinien używać. Możemy przedefiniować to na 128 bitów w ciągu kilku lat, kiedy zaczniemy trzymać w pobliżu 16 eksabajtów.
Jeśli korzystasz z systemu Windows, powinieneś użyć GetFileSizeEx - w rzeczywistości używa on 64-bitowej liczby całkowitej ze znakiem, więc zaczną napotykać problemy z 8 plikami eksabajtowymi. Głupi Microsoft! :-)
Rozwiązanie Matta powinno działać, z tym wyjątkiem, że jest to C ++ zamiast C, a początkowe polecenie tell nie powinno być konieczne.
unsigned long fsize(char* file)
{
FILE * f = fopen(file, "r");
fseek(f, 0, SEEK_END);
unsigned long len = (unsigned long)ftell(f);
fclose(f);
return len;
}
Naprawiono też aparat ortodontyczny. ;)
Aktualizacja: to naprawdę nie jest najlepsze rozwiązanie. Jest ograniczony do plików 4 GB w systemie Windows i prawdopodobnie działa wolniej niż zwykłe wywołanie specyficzne dla platformy, takie jak GetFileSizeExlub stat64.
long intz ftell(). (unsigned long)rzucanie nie poprawia zasięgu, który jest już ograniczony przez funkcję. ftell()zwraca -1 w przypadku błędu i to zostaje zaciemnione przy rzutowaniu. Zaproponuj fsize()zwrot tego samego typu coftell() .
** Nie rób tego ( dlaczego? ):
Cytując standardowy dokument C99, który znalazłem online: „Ustawienie wskaźnika pozycji pliku na koniec pliku, tak jak w przypadku
fseek(file, 0, SEEK_END), ma niezdefiniowane zachowanie dla strumienia binarnego (z powodu możliwych końcowych znaków zerowych) lub dowolnego strumienia z kodowaniem zależnym od stanu to z pewnością nie kończy się w początkowym stanie zmiany. **
Zmień definicję na int, aby można było przesyłać komunikaty o błędach, a następnie użyj fseek()i, ftell()aby określić rozmiar pliku.
int fsize(char* file) {
int size;
FILE* fh;
fh = fopen(file, "rb"); //binary mode
if(fh != NULL){
if( fseek(fh, 0, SEEK_END) ){
fclose(fh);
return -1;
}
size = ftell(fh);
fclose(fh);
return size;
}
return -1; //error
}
fseekoi ftello(lub fseeki ftelljeśli utkniesz bez poprzedniego i zadowolony z ograniczeniami rozmiary plików można pracować z) jest poprawny sposób określenia długości pliku. statrozwiązania oparte na systemie nie działają na wielu "plikach" (takich jak urządzenia blokowe) i nie są przenośne do systemów innych niż POSIX-ish.
Standard POSIX ma własną metodę uzyskiwania rozmiaru pliku.
Dołącz sys/stat.hnagłówek, aby użyć funkcji.
stat(3) .st_sizenieruchomość.Uwaga : ogranicza rozmiar do 4GB. Jeśli nie jest to Fat32system plików, użyj wersji 64-bitowej!
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
struct stat info;
stat(argv[1], &info);
// 'st' is an acronym of 'stat'
printf("%s: size=%ld\n", argv[1], info.st_size);
}
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
struct stat64 info;
stat64(argv[1], &info);
// 'st' is an acronym of 'stat'
printf("%s: size=%ld\n", argv[1], info.st_size);
}
ANSI C. bezpośrednio nie zapewnia drogę do określenia długości pliku.
Będziemy musieli użyć naszego umysłu. Na razie użyjemy metody wyszukiwania!
#include <stdio.h>
int main(int argc, char** argv)
{
FILE* fp = fopen(argv[1]);
int f_size;
fseek(fp, 0, SEEK_END);
f_size = ftell(fp);
rewind(fp); // to back to start again
printf("%s: size=%ld", (unsigned long)f_size);
}
Jeśli plik to
stdinlub potok. POSIX, ANSI C nie będzie działać.
Zwróci,0jeśli plik jest potokiem lubstdin.Opinia : Zamiast tego powinieneś użyć standardu POSIX . Ponieważ ma obsługę 64-bitową.
struct _stat64i __stat64()dla _Windows.
A jeśli tworzysz aplikację dla Windows, użyj GetFileSizeEx API, ponieważ I / O pliku CRT jest niechlujne, szczególnie przy określaniu długości pliku, ze względu na osobliwości reprezentacji plików na różnych systemach;)
Jeśli nie masz nic przeciwko korzystaniu z biblioteki std c:
#include <sys/stat.h>
off_t fsize(char *file) {
struct stat filestat;
if (stat(file, &filestat) == 0) {
return filestat.st_size;
}
return 0;
}
Szybkie wyszukiwanie w Google znalazło metodę wykorzystującą fseek i ftell oraz wątek z tym pytaniem z odpowiedziami, że nie można tego zrobić w C w inny sposób.
Możesz użyć biblioteki przenośności, takiej jak NSPR (biblioteka, która obsługuje przeglądarkę Firefox) lub sprawdzić jej implementację (raczej włochata).
Użyłem tego zestawu kodu, aby znaleźć długość pliku.
//opens a file with a file descriptor
FILE * i_file;
i_file = fopen(source, "r");
//gets a long from the file descriptor for fstat
long f_d = fileno(i_file);
struct stat buffer;
fstat(f_d, &buffer);
//stores file size
long file_length = buffer.st_size;
fclose(i_file);
Spróbuj tego --
fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);
To, co to robi, to najpierw szukanie do końca pliku; następnie zgłoś, gdzie znajduje się wskaźnik pliku. Na koniec (jest to opcjonalne) przewija się z powrotem do początku pliku. Zwróć na to uwagęfp powinien to być strumień binarny.
file_size zawiera liczbę bajtów, które zawiera plik. Zwróć uwagę, że ponieważ (według climits.h) typ long unsigned jest ograniczony do 4294967295 bajtów (4 gigabajty), musisz znaleźć inny typ zmiennej, jeśli masz do czynienia z plikami większymi niż to.
ftellnie zwraca wartości reprezentującej liczbę bajtów, które można odczytać z pliku.
Mam funkcję, która działa dobrze tylko z stdio.h. Bardzo mi się podoba i działa bardzo dobrze i jest dość zwięzły:
size_t fsize(FILE *File) {
size_t FSZ;
fseek(File, 0, 2);
FSZ = ftell(File);
rewind(File);
return FSZ;
}
Oto prosta i przejrzysta funkcja, która zwraca rozmiar pliku.
long get_file_size(char *path)
{
FILE *fp;
long size = -1;
/* Open file for reading */
fp = fopen(path, "r");
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fp.close();
return
}
Możesz otworzyć plik, przejść do przesunięcia 0 względem dołu pliku za pomocą
#define SEEKBOTTOM 2
fseek(handle, 0, SEEKBOTTOM)
wartość zwracana przez fseek to rozmiar pliku.
Długo nie kodowałem w C, ale myślę, że powinno działać.
Patrząc na pytanie, ftellmożna łatwo uzyskać liczbę bajtów.
long size = ftell(FILENAME);
printf("total size is %ld bytes",size);
ftelloczekuje deskryptora pliku, a nie nazwy pliku jako argumentu.
ftellnie oczekuje deskryptora pliku, oczekuje FILE*zamiast tego. Najpierw zobacz stronę podręcznika!
fseek()najpierw do wyszukania końca pliku, a także ftell()oczekuje , że FILE *nie ma ciągu! Dobrze by było, gdybyś uściślił swoją odpowiedź.