Vra

Hoe kan ek uitvind die grootte van'n lêer, in grepe?

#include <stdio.h>

unsigned int fsize(char* file){
  //what goes here?
}
Was dit nuttig?

Oplossing

Op grond van NilObject se kode:

#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; 
}

Wysigings:

  • Made die lêernaam argument 'n const char.
  • Gerectificeerd die struct stat definisie, wat ontbreek die veranderlike naam.
  • Opbrengste -1 op fout in plaas van 0, wat dubbelsinnig sou wees vir 'n leë lêer. off_t is 'n getekende tipe so dit is moontlik.

As jy wil fsize() om 'n boodskap oor fout te druk, kan jy dit gebruik:

#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;
}

Op 32-bit stelsels wat jy moet hierdie stel met die opsie -D_FILE_OFFSET_BITS=64, anders sal off_t net hou waardes tot 2 GB. Sien die artikel "Die gebruik van LFS" van groot lêer ondersteuning in Linux vir meer inligting.

Ander wenke

Moenie int. Lêers oor 2 GB in grootte is algemeen as vuil deesdae

Moenie unsigned int. Lêers oor 4 GB in grootte is algemeen as 'n paar effens-minder-algemeen vuil

IIRC die standaard biblioteek definieer off_t as 'n ongetekende 64 bis integriteit, en dit is wat almal moet gebruik nie. Ons kan herdefinieer wat tot 128 stukkies in 'n paar jaar wees wanneer ons begin met 16 Exabyte lêers rond hang.

As jy op vensters, moet jy gebruik GetFileSizeEx - dit gebruik eintlik 'n getekende 64 bis integriteit, sodat hulle sal begin slaan probleme met 8 Exabyte lêers. Dwase Microsoft! : -)

Matt se oplossing moet werk, behalwe dat dit C ++ in plaas van C, en die aanvanklike vertel nie nodig wees nie.

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;
}

Vaste jou stut vir jou ook. ;)

Update: Dit is nie regtig die beste oplossing. Dit is beperk tot 4 GB lêers op Windows en dis waarskynlik stadiger as net die gebruik van 'n platform-spesifieke oproep soos GetFileSizeEx of stat64.

** Moenie hierdie ( waarom ):?

  

Haal die C99 standaard doc dat ek aanlyn gevind: "die lêer posisie aanwyser Kader tot einde van lêer, soos met fseek (lêer, 0, SEEK_END), het gedrag ongedefinieerd vir 'n binêre stroom (as gevolg van moontlike sleep nul karakters) of vir enige stroom met state-afhanklike enkodering wat nie sekerlik nie eindig in die eerste skof staat. **

Verander die definisie om so int wat fout boodskappe kan gestuur word, en dan gebruik fseek () en ftell () om die grootte van die lêer te bepaal.

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
}

As jy fyn is met behulp van die st c biblioteek:

#include <sys/stat.h>
off_t fsize(char *file) {
    struct stat filestat;
    if (stat(file, &filestat) == 0) {
        return filestat.st_size;
    }
    return 0;
}

POSIX

Die POSIX standaard het sy eie metode te kry grootte van die lêer.
Insluit die sys/stat.h kop na die gebruik van die funksie.

Sinopsis

  • Kry lêer met behulp van statistieke stat(3).
  • Kry die st_size die eiendom.

Voorbeelde

Nota:Dit beperk die grootte te 4GB.Indien nie Fat32 lêerstelsel gebruik dan die 64-bis weergawe!

#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 (standaard)

Die ANSI C nie direk bied die manier om te bepaal die lengte van die lêer.
Ons sal hê om te gebruik om ons gedagtes.Vir nou, sal ons gebruik maak van die soek benadering!

Sinopsis

  • Soek die lêer aan die einde gebruik te maak van fseek(3).
  • Kry die huidige posisie met behulp van ftell(3).

Voorbeeld

#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);
}

As die lêer is stdin of'n pyp. POSIX, ANSI C sal nie werk nie.
Dit sal gaan terugkeer 0 as die lêer is'n pyp of stdin.

Mening:Jy moet gebruik POSIX standaard plaas.Omdat, dit het 64bit ondersteuning.

'n vinnige soektog in Google gevind n metode met behulp van fseek en ftell en 'n draad met hierdie vraag met antwoorde wat dit nie in pas C gedoen kan word in 'n ander manier.

Jy kan gebruik 'n port biblioteek soos NSPR (die biblioteek wat magte Firefox) of kyk die implementering daarvan (eerder harige).

Ek gebruik hierdie stel om die lêer in lengte te vind.

//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);

Probeer hierdie -

fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);

Wat dit beteken is eerste, daarna streef om die einde van die lêer; dan, rapporteer waar die lêer wyser is. Laastens (dit is opsioneel) dit terug gespoeld terug na die begin van die lêer. Let daarop dat fp moet 'n binêre stroom wees.

FILE_SIZE bevat die aantal grepe die lêer bevat. Let daarop dat sedert (volgens climits.h) die unsigned long tipe is beperk tot 4294967295 grepe (4 GB) wat jy nodig het om 'n ander veranderlike tipe vind as jy geneig om te gaan met lêers groter as dié is.

Hier is 'n eenvoudige en skoon funksie wat die grootte van die lêer terug.

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 
}

Jy gaan nodig om 'n biblioteek funksie gebruik om die besonderhede van 'n lêer op te haal. Soos C is heeltemal platform onafhanklike, gaan jy nodig het om ons te laat weet wat platform / bedryfstelsel jy die ontwikkeling vir!

As ons kyk na die vraag, kan ftell maklik die aantal grepe.

  long size ;
  size = ftell(FILENAME);
  printf("total size is %ld bytes",size);

Jy kan die lêer oop te maak, gaan na 0 geneutraliseer relatiewe vanaf die onderkant van die lêer met

#define SEEKBOTTOM   2

fseek(handle, 0, SEEKBOTTOM)  

die waarde teruggekeer van fseek is die grootte van die lêer.

Ek het nie kode in C vir 'n lang tyd, maar ek dink dit behoort te werk.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top