2016-04-08 25 views
2

Bir dosyanın içeriği için bellek() ile ayırın: \ n) içeriğine ayırmaya çalışıyorum.Bir dosyanın (tüm içeriğin) boyutunu nasıl belirleyebilirim, böylece bir kerede bunun için bellek ayırabilir miyim?

Daha büyük boyutlu dosyalarla kullanılabilmesi için 16000'i nasıl değiştirebilirim?

Kodum:

typedef struct node { 
    bool is_word; 
    struct node* children[27]; 
} node; 

node* root; 


bool load(const char* dictionary) 
{ 
    FILE *fp; 
    fp = fopen(dictionary, "rb"); 


    node* node_bucket = calloc(16000, sizeof(node)); 
    node* next_free_node = node_bucket; 

    // compute... 

    // to later free the memory with another function 
    root = node_bucket; 
} 

Teşekkür

+2

Ben en çok taşınabilir düşünüyorum yolu ['ftell()'] kullanmaktır (http://linux.die.net/man/3/ftell). Bu, muhtemelen sonuçta en iyi performansa sahip olmayan, sonuna kadar gitmek için dosyada aramanızı gerektirecektir. POSIX'te, dosya sistemini sormak için 'fstat()' ı kullanabilirsiniz. – unwind

+0

@ user3419211 '\ n' karakteri dışında bir dosyada kayıtlı baytların tam sayısını istiyorsunuz. "\ N" dahil –

+0

! Önerildiği gibi ftell() kullandım ve çalışıyor gibi görünüyor. – user3419211

cevap

2
dosya ne kadar büyük bilmeden dinamik bellek ayırabilir

. Genelde blok I/O yönünde kesişen 2'lik bir güç olan bir blok boyutu kullandım. Bu son blok sadece kısmen kullanıldığında biraz ziyan, ama burada size düğüm yapılar ile çalışmak uyum olabilecek bir örnek vardır: ftell() kullanıyor

#include <stdio.h> 
#include <stdlib.h> 

#define BLOCKSIZE 16384 

int main(void) { 
    unsigned char *buf = NULL; 
    unsigned char *tmp = NULL; 
    size_t totalread = 0; 
    size_t currentsize = 0; 
    size_t currentread = 0; 
    FILE *fp; 

    if((fp = fopen("test.txt", "rb")) == NULL) 
     exit(1); 
    do { 
     currentsize += BLOCKSIZE; 
     if((tmp = realloc(buf, currentsize)) == NULL) 
      exit(1); 
     buf = tmp; 
     currentread = fread(&buf[totalread], 1, BLOCKSIZE, fp); 
     totalread += currentread; 
    } while (currentread == BLOCKSIZE); 

    printf("Total size was %zu\n", totalread); 
    free(buf); 
    fclose(fp); 
    return 0; 
} 
1

basit yaklaşım dosyanın boyutunu almak için : yorum söylediği gibi

fseek(fp, 0, SEEK_END); // non-portable 
long size = ftell(fp); 

Ancak, bu, taşınabilir olmadığından "7.21.9.2 işlevini aramak" in N1570 belgeler:

2 ...... bir ikili akışı ihtiyacı Fseek anlamlı değil destek SEEK_END için arama değeri.

Alternatif olarak, kendi başınıza bir dosyanın boyutunu almak için bir fonksiyon yazabiliriz:

size_t fSize(FILE *fp) 
{ 
    void *ptr = malloc(1); 
    size_t size = 0; 
    while(fread(ptr, 1, 1, fp) == 1) 
     size++; 
    if(feof(fp)) 
     return size; 
    else 
     return 0; // reading error 
} 

Bir doğruluk verimli trade-off:

size_t fRoughSize(FILE *fp) 
{ 
    void *ptr = malloc(1024); 
    size_t size = 0; 
    while(fread(ptr, 1024, 1, fp) == 1024) 
     size += 1024; 
    if(feof(fp)) 
     return size; 
    else 
     return 0; // reading error 
} 
İlgili konular