2016-08-29 23 views
0

私は、構造体のレコードの最大数を生成する必要があるプロジェクトを作成する必要があります(私はバイナリモードでは最良のオプションだと思う)それら。生成されるファイルのサイズは{1gb、10gb、20gb ...}異なるはずですが、どのようにそれらのファイルにアクセスするためにメモリを割り当てることができますか?あなたはその多くのRAMを持っていますかCで大きなファイルを読み書きする

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

void inicializa_lista(Lista *l, int t) 
{ 
    l->tamInfo = t; 
    l->cabeca = NULL; 
} 

int insereNoInicio(Lista *l, void *info) 
{ 
    Elemento *p = aloca_elemento(l->tamInfo, info); 

    if(p == NULL) 
     return 0;/*Erro na alocação.*/ 

    p->info = malloc(l->tamInfo); 

    if(p->info == NULL) 
    { 
     free(p); 
     return 0;/*Erro.*/ 
    } 

    memcpy(p->info, info, l->tamInfo); 

    p->proximo = l->cabeca; 

    l->cabeca = p; 

    return 1; 
} 

int insereNoFim(Lista *l, void *info) 
{ 
    if(lista_vazia(*l)) 
     return insereNoInicio(l, info); 

    Elemento *p = aloca_elemento(l->tamInfo, info); 

    if(p == NULL) 
     return 0; 

    Elemento *aux = l->cabeca; 

    while(aux->proximo != NULL) 
     aux = aux->proximo; 

    p->proximo = NULL; 

    aux->proximo = p; 

    return 1; 
} 

int removeNoInicio(Lista *l, void *info) 
{ 
    if(lista_vazia(*l)) 
     return ERRO_LISTA_VAAZIA; 

    Elemento *p = l->cabeca; 

    l->cabeca = p->proximo;/*equivalentes l->cabeca = l->cabeca->proximo;*/ 

    memcpy(info, p->info, l->tamInfo); 

    free(p->info); 

    free(p); 

    return 1; 
} 

int removeNoFim(Lista *l, void *info) 
{ 
    if(lista_vazia(*l)) 
     return ERRO_LISTA_VAAZIA; 

    if(l->cabeca->proximo == NULL)/* somente quando a lista tem um elemento */ 
     return removeNoInicio(l, info); 

    Elemento *p = l->cabeca; 

    while(p->proximo->proximo != NULL) 
     p = p->proximo; 

    memcpy(info, p->proximo->info, l->tamInfo); 

    free(p->proximo->info); 
    free(p->proximo); 

    p->proximo = NULL; 

    return 1; 
} 

int lista_vazia(Lista l) 
{ 
    return l.cabeca == NULL; 
} 

Elemento *aloca_elemento(int tamInfo, void *info) 
{ 
    Elemento *p = malloc(sizeof(Elemento)); 

    if(p == NULL) 
     return NULL; 

    p->info = malloc(tamInfo); 

    if(p->info == NULL) 
    { 
     free(p); 

     return NULL; 
    } 

    memcpy(p->info, info, tamInfo); 

    return p; 
} 

void mostra_lista(Lista l, void (*mostra_info)(void *)) 
{ 
    if(lista_vazia(l)) 
     printf("A lista está vazia\n"); 
    else 
    { 
     Elemento *p = l.cabeca; 

     printf("Dados da Lista:\n"); 

     while(p != NULL) 
     { 
      mostra_info(p->info); 
      p = p->proximo; 
     } 
    } 
} 

void limpa_lista(Lista *l) 
{ 
    Elemento *p = l->cabeca; 

    while(p != NULL) 
    { 
     Elemento *aux = p->proximo; 

     free(p->info); 
     free(p); 

     p = aux; 
    } 

    l->cabeca = NULL; 
} 

int insereNaPosicao(Lista *l,void *info,int pos){ 
    if(pos<0) 
     return ERRO_POSICAO_INVALIDA; 
    if(pos==0) 
     return insereNoFim(l,info); 
    Elemento *p=l->cabeca; 
    int cont =0; 
    while(cont<pos-1 && p->proximo!=NULL){ 
     p=p->proximo; 
     cont++; 
    } 
    if(cont!=pos-1) 
     return ERRO_POSICAO_INVALIDA; 
    Elemento *novo = aloca_elemento(l->tamInfo,info); 
    if(novo==NULL) 
     return 0; // ERRO ALOCACAO 
    novo->proximo=p->proximo; 
    p->proximo=novo; 
    return 1; 
} 

int removeNaPosicao(Lista *l,void *info,int pos){ 
    if(lista_vazia(*l)) return ERRO_LISTA_VAAZIA; 
    if(pos<0) return ERRO_POSICAO_INVALIDA; 
    Elemento *p = l->cabeca; 
    if(pos==0){ 
     removeNoInicio(l,info); 
    } 
    int cont; 
    while(cont<pos-1 &&p->proximo!=NULL){ 
     p=p->proximo; 
     cont++; 
    } 
    if(cont!=pos-1) return ERRO_POSICAO_INVALIDA; 
    Elemento *aux = p->proximo; 
    p->proximo = aux ->proximo; 
    free(aux->info); 
    free(aux); 
    return 1; 
} 


int compara_float(void *a,void *b){ 
    float *p1=a,*p2=b; 
    if(*p1>*p2) return 1; 
    if(*p1<*p2) return -1; 
    return 0; 
} 


int insereEmOrdem(Lista *l,void *info,int(*compara)(void*,void*)){ 
    int cont =0; 
    Elemento *p = l->cabeca; 
    while(p!=NULL && compara(info,p->info)>0){ 
     cont++; 
     p=p->proximo; 
    } 
    return insereNaPosicao(l,info,cont); 

} 

///// HEADER

#define ERRO_LISTA_VAAZIA -1 
#define ERRO_POSICAO_INVALIDA -2 


typedef struct{ 
    char* nome; 
    int matricula; 
    int notas; 
    int faltas; 
}Diario; 

typedef struct ele 
{ 
    void *info; 
    struct ele *proximo; 
}Elemento; 

typedef struct 
{ 
    int tamInfo; 
    Elemento *cabeca; 
}Lista; 

void inicializa_lista(Lista *l, int t); 

int insereNoInicio(Lista *l, void *info); 

int insereNoFim(Lista *l, void *info); 

int removeNoInicio(Lista *l, void *info); 

int removeNoFim(Lista *l, void *info); 

int lista_vazia(Lista l); 

Elemento *aloca_elemento(int tamInfo, void *info); 

void mostra_lista(Lista l, void (*mostra_info)(void *)); 

void limpa_lista(Lista *l); 

int insereNaPosicao(Lista *l,void *info,int pos); 

int insereEmOrdem(Lista *l,void *info,int(*compara)(void*,void*)); 

int compara_float(void *a,void *b); 
+2

プログラムを構造化して、ファイル全体を同時にメモリに保存する必要はありません。あなたは、あなたがリストと一緒に行う必要があるすべてのことを完全には記述していないので、その一般的な助言より多くの援助を提供することはできません。 – kaylum

+0

巨大な行列を逆にしようとしているのでない限り、@ kaylumに同意します。その大量のデータをメモリにロードする必要はありません。あなたのアプリケーションが何であるか分かりませんが、SQLiteデータベースにデータを保存し、オープンソースのCライブラリを使ってデータにアクセスすることをお勧めします。 – Dave

答えて

1

を:私は、次のコードリストは、私が使用している、データを格納するためのリンクリストを使用していますか?トリックを気にするよりも、メモリをファイルにダンプするだけで、その逆もありません。

しかし、私はあなたにそれほど記憶がないと確信しています(私はすでに数年のうちに未来の読者が真の不信仰で眉を上げているのを見ています)。したがって、データを適切な量のRAMに収まるように分割して分割する必要があります。

実際のデータはDiarioという名前の構造体にありますが、それは正しいですか?それはできるだけ小さいスライスにします。それの完全な内容は、バイナリファイルの必要がないプレーンテキストとして記述することができ、必要なのはシンプルなCSVファイルだけです。

CSVを書き込むのは簡単ですが、読み込みはもう少し複雑ですが、固定形式の場合は比較的簡単です。

エントリを検索することは、ファイル全体を検索することです。これはしばらく時間がかかることがあります。私は検索時間を短縮するために何らかのインデックスを追加することを提案します。

0

どのようにデータを使用するかによって異なります。技術的には、RAMと仮想メモリの間にメモリがあります。しかし、ファイルを使ってランダムにデータにアクセスすると、おそらくシステムがスラッシュする(遅くなる)可能性があります。あなたは、ファイルに連続してアクセスすることができます。

いくつかのかなり標準的なtechinques: 1)は、複数のtheadsを使用:1つ以上のデータを処理し、ファイルにアクセスして、いくつかの(俳優パターン) 2)データに 3を並べ替え)を複数のキャッシュ今

、あなたの前にこれらを実装すると、これはまさにSQLデータベースがあなたにとって(そして何か他のものに対して)何をするのかということです。最低でも、小さなデータモデリング(あなたのケースでは1つのテーブルデータベース)により、これらのテクニクを使用してデータ処理アルゴリズムをどれだけ高速化するかをテストできます。

Ps:私はそうするように言われたので、以前は構造のようなツリーを実装しました。構造はうまくいきましたが、実装には時間がかかりました。しかし、小さなデータモデリングを行う方が早く、構造がうまくいくことがわかっていたのでアルゴリズムを最初に実行していましたが、algrithmはうまく拡張できないことが判明したので、プロジェクトを少しリファクタリングする必要がありました。この中で、データベースの変更はかなり簡単です。

+0

私の問題は学術目的であり、ファイル操作を使用するだけです。私は現在デッドロックされている、私のプログラムは、各ノードを返すリストを介してポインタで各レコードを返すが、どのように私はレコードを保存するためにfwriteを使用する必要がありますか? – jacktheropper

+0

バイナリファイルの場合、diarioのポインタをcharポインタにキャストします。そして、sizeof(struct diario)を書き込むバイト数として使用します。 –

関連する問題