Hoe kan ik een bestandsgrootte in C krijgen? [DUPLICEER]

Hoe kan ik de grootte van een bestand achterhalen dat ik opende met een applicatie die in C is geschreven?
Ik zou graag de grootte willen weten, omdat ik de inhoud van het geladen bestand in een tekenreeks wil plaatsen, die ik toexamen met malloc(). Gewoon schrijven malloc(10000*sizeof(char));is imho een slecht idee.


Antwoord 1, Autoriteit 100%

U moet naar het einde van het bestand zoeken en vervolgens om de positie vragen:

fseek(fp, 0L, SEEK_END);
sz = ftell(fp);

U kunt dan terug zoeken, b.v.:

fseek(fp, 0L, SEEK_SET);

of (indien proberen om naar het begin te gaan)

rewind(fp);

Antwoord 2, Autoriteit 71%

Standaardbibliotheek gebruiken:

Ervan uitgaande dat uw implementatie zinvolle SEEKS_END ondersteunt:

fseek(f, 0, SEEK_END); // seek to end of file
size = ftell(f); // get current file pointer
fseek(f, 0, SEEK_SET); // seek back to beginning of file
// proceed with allocating memory and reading the file

Linux / Posix:

U kunt statgebruiken (als u de bestandsnaam kent), of fstat(als u de bestandsdescriptor hebt).

Hier is een voorbeeld voor stat:

#include <sys/stat.h>
struct stat st;
stat(filename, &st);
size = st.st_size;

Win32:

U kunt GetFileSizeof GetFileSizeEx.


Antwoord 3, autoriteit 21%

Als je de bestandsdescriptor fstat()hebt, retourneert een stat-structuur die de bestandsgrootte bevat.

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
// fd = fileno(f); //if you have a stream (e.g. from fopen), not a file descriptor.
struct stat buf;
fstat(fd, &buf);
off_t size = buf.st_size;

Antwoord 4, autoriteit 4%

Ik heb uiteindelijk een korte en lieve fsize-functie gemaakt (let op, geen foutcontrole)

int fsize(FILE *fp){
    int prev=ftell(fp);
    fseek(fp, 0L, SEEK_END);
    int sz=ftell(fp);
    fseek(fp,prev,SEEK_SET); //go back to where we were
    return sz;
}

Het is een beetje dwaas dat de standaard C-bibliotheek zo’n functie niet heeft, maar ik begrijp waarom het moeilijk zou zijn, aangezien niet elk “bestand” een grootte heeft (bijvoorbeeld /dev/null)


Antwoord 5, autoriteit 3%

Hoe lseek/fseek/stat/fstatom bestandsgrootte te krijgen ?

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
void
fseek_filesize(const char *filename)
{
    FILE *fp = NULL;
    long off;
    fp = fopen(filename, "r");
    if (fp == NULL)
    {
        printf("failed to fopen %s\n", filename);
        exit(EXIT_FAILURE);
    }
    if (fseek(fp, 0, SEEK_END) == -1)
    {
        printf("failed to fseek %s\n", filename);
        exit(EXIT_FAILURE);
    }
    off = ftell(fp);
    if (off == -1)
    {
        printf("failed to ftell %s\n", filename);
        exit(EXIT_FAILURE);
    }
    printf("[*] fseek_filesize - file: %s, size: %ld\n", filename, off);
    if (fclose(fp) != 0)
    {
        printf("failed to fclose %s\n", filename);
        exit(EXIT_FAILURE);
    }
}
void
fstat_filesize(const char *filename)
{
    int fd;
    struct stat statbuf;
    fd = open(filename, O_RDONLY, S_IRUSR | S_IRGRP);
    if (fd == -1)
    {
        printf("failed to open %s\n", filename);
        exit(EXIT_FAILURE);
    }
    if (fstat(fd, &statbuf) == -1)
    {
        printf("failed to fstat %s\n", filename);
        exit(EXIT_FAILURE);
    }
    printf("[*] fstat_filesize - file: %s, size: %lld\n", filename, statbuf.st_size);
    if (close(fd) == -1)
    {
        printf("failed to fclose %s\n", filename);
        exit(EXIT_FAILURE);
    }
}
void
stat_filesize(const char *filename)
{
    struct stat statbuf;
    if (stat(filename, &statbuf) == -1)
    {
        printf("failed to stat %s\n", filename);
        exit(EXIT_FAILURE);
    }
    printf("[*] stat_filesize - file: %s, size: %lld\n", filename, statbuf.st_size);
}
void
seek_filesize(const char *filename)
{
    int fd;
    off_t off;
    if (filename == NULL)
    {
        printf("invalid filename\n");
        exit(EXIT_FAILURE);
    }
    fd = open(filename, O_RDONLY, S_IRUSR | S_IRGRP);
    if (fd == -1)
    {
        printf("failed to open %s\n", filename);
        exit(EXIT_FAILURE);
    }
    off = lseek(fd, 0, SEEK_END);
    if (off == -1)
    {
        printf("failed to lseek %s\n", filename);
        exit(EXIT_FAILURE);
    }
    printf("[*] seek_filesize - file: %s, size: %lld\n", filename, (long long) off);
    if (close(fd) == -1)
    {
        printf("failed to close %s\n", filename);
        exit(EXIT_FAILURE);
    }
}
int
main(int argc, const char *argv[])
{
    int i;
    if (argc < 2)
    {
        printf("%s <file1> <file2>...\n", argv[0]);
        exit(0);
    }
    for(i = 1; i < argc; i++)
    {
        seek_filesize(argv[i]);
        stat_filesize(argv[i]);
        fstat_filesize(argv[i]);
        fseek_filesize(argv[i]);
    }
    return 0;
}

Antwoord 6, Autoriteit 2%

Heb je overwogen om de bestandsgrootte niet te berekenen en zo nodig de array te laten groeien? Hier is een voorbeeld (met fouten waarop u wordt aangevoerd):

#define CHUNK 1024
/* Read the contents of a file into a buffer.  Return the size of the file 
 * and set buf to point to a buffer allocated with malloc that contains  
 * the file contents.
 */
int read_file(FILE *fp, char **buf) 
{
  int n, np;
  char *b, *b2;
  n = CHUNK;
  np = n;
  b = malloc(sizeof(char)*n);
  while ((r = fread(b, sizeof(char), CHUNK, fp)) > 0) {
    n += r;
    if (np - n < CHUNK) { 
      np *= 2;                      // buffer is too small, the next read could overflow!
      b2 = malloc(np*sizeof(char));
      memcpy(b2, b, n * sizeof(char));
      free(b);
      b = b2;
    }
  }
  *buf = b;
  return n;
}

Dit heeft het voordeel van het werken zelfs voor streams waarin het onmogelijk is om de bestandsgrootte (zoals Stdin) te krijgen.


Antwoord 7

Als u op Linux bent, kunt u serieus overwegen om de g_file_get_contenten functie van glib. Het behandelt alle code voor het laden van een bestand, het toewijzen van geheugen en het afhandelen van fouten.


Antwoord 8

#include <stdio.h>
#define MAXNUMBER 1024
int main()
{
    int i;
    char a[MAXNUMBER];
    FILE *fp = popen("du -b  /bin/bash", "r");
    while((a[i++] = getc(fp))!= 9)
        ;
    a[i] ='\0';
    printf(" a is %s\n", a);
    pclose(fp);
    return 0;
}  

HTH

Other episodes