Cum pot determina dimensiunea unui fișier, în octeți?
#include
unsigned int fsize(char* file){
//what goes here?
}
Va trebui să utilizați o funcție de bibliotecă pentru a prelua detaliile unui fișier. Deoarece C este complet independent de platformă, va trebui să ne comunicați ce platformă/sistem de operare vă dezvoltați!
Puteți deschide fișierul, mergeți la 0 relative offset din partea de jos a fișierului cu
#define SEEKBOTTOM 2
fseek(handle, 0, SEEKBOTTOM)
valoarea returnată de la fseek este dimensiunea fișierului.
Nu am codat mult timp în C, dar cred că ar trebui să funcționeze.
Soluția lui Matt ar trebui să funcționeze, cu excepția faptului că este C ++ în loc de C, iar comunicarea inițială nu ar trebui să fie necesară.
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;
}
Ți-ai fixat și brățara pentru tine. ;)
Actualizare: Aceasta nu este cu adevărat cea mai bună soluție. Se limitează la fișiere de 4 GB pe Windows și este probabil mai lent decât să folosească un apel specific pentru platformă, cum ar fi GetFileSizeEx
sau stat64
.
** Nu faceți acest lucru ( de ce? ):
Citând documentul standard C99 pe care l-am găsit online: "Setarea indicatorului poziției fișierului la sfârșitul fișierului, ca și în cazul fseek (fișier, 0, SEEK_END), are un comportament nedefinit pentru un flux binar caractere) sau pentru orice flux cu codare dependentă de stat care nu se încheie cu siguranță în starea de schimbare inițială. **
Modificați definiția la int astfel încât mesajele de eroare să poată fi transmise și apoi utilizați fseek () și ftell () pentru a determina dimensiunea fișierului.
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
}
O căutare rapidă în Google a găsit o metodă folosind fseek și ftell și un fir cu această întrebare cu răspunsuri că nu se poate face doar în C într-un alt mod.
You could use a portability library like NSPR (the library that powers Firefox) or check its implementation (rather hairy).
Nu utilizați int
. Fișiere de peste 2 gigabytes în dimensiune sunt comune ca murdărie în aceste zile
Nu utilizați unsigned int
. Fișiere cu dimensiunea de peste 4 gigaocteți sunt comune, întrucât unele murdăriri puțin mai frecvente
IIRC biblioteca standard definește off_t
ca un număr întreg nesemnat de 64 de biți, ceea ce ar trebui să fie folosit de toată lumea. Putem redefini ca aceasta sa fie de 128 de biti in cativa ani cand vom incepe sa avem 16 fisiere exabyte in jurul nostru.
If you're on windows, you should use GetFileSizeEx - it actually uses a signed 64 bit integer, so they'll start hitting problems with 8 exabyte files. Foolish Microsoft! :-)
Și dacă construiți o aplicație Windows, utilizați API-ul GetFileSizeEx deoarece fișierul CRT I/O este dezordonat, în special pentru determinarea lungimii fișierului, datorită particularităților în reprezentările de fișiere pe diferite sisteme;)
Bazat pe codul lui NilObject:
#include
off_t fsize(const char *filename) {
struct stat st;
if (stat(filename, &st) == 0)
return st.st_size;
return -1;
}
Schimbări:
const char
struct stat
, din care lipsea numele variabilei. -1
pentru eroare in loc de 0
, ceea ce ar fi ambiguu pentru un fisier gol. off_t
este un tip semnat, astfel încât acest lucru este posibil. Dacă doriți fsize ()
pentru a imprima un mesaj pe eroare, puteți folosi acest lucru:
#include
#include
#include
#include
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;
}
La sistemele pe 32 de biți trebuie să compilați această opțiune cu -D_FILE_OFFSET_BITS = 64
, altfel off_t
va menține valori de până la 2 GB. Vedeți secțiunea "Utilizarea LFS" din Suport pentru fișiere mari în Linux pentru detalii.
Am folosit acest set de cod pentru a găsi lungimea fișierului.
//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);
Iată o funcție simplă și curată care returnează dimensiunea fișierului.
long get_file_size(char *path)
{
FILE *fp;
/* Open file for reading */
fp = fopen(path, "r");
fseek(fp, 0, SEEK_END);
return ftell(fp);
}
Incearca asta --
fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);
Ceea ce face mai întâi este să căutați la sfârșitul dosarului; apoi, raportați unde este pointerul fișierului. În cele din urmă (acest lucru este opțional) se întoarce la începutul fișierului. Rețineți că fp
ar trebui să fie un flux binar.
file_size conține numărul de octeți care conține fișierul. Rețineți că, deoarece (în conformitate cu climits.h), tipul nesemnificativ lung este limitat la 4294967295 octeți (4 gigaocteți), va trebui să găsiți un alt tip de variabilă dacă aveți de-a face cu fișiere mai mari decât acestea.