2017-06-13 5 views
1

ファイルをStringにmmapします。msyncの 'length`パラメータが機能しません

int fd = open(FILE_PATH, O_RDWR); 
struct stat s; 
int status = fstat(fd, &s); 
char *f = (char*) mmap (0, s.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 

、私はfを解析し、いくつかの変更を行いますcJSON。

cJSON *root = cJSON_Parse(f); 
//some JSON operation 

終了後、cJSONから文字列を再生成し、ディスクに書き戻そうとしました。

char* rendered = cJSON_Print(root); 
memcpy(f, rendered, strlen(rendered)); 
msync(f, strlen(renderer), MS_SYNC); 

mmapまたはmsyncにエラーはありません。

ファイルの内容を確認したところ、cJSONライブラリを使用して変更したものが正しく変更されていました。

ただし、ファイルが完成していません。具体的には、ディスクに書き戻したサイズ(Sublimeを使用してチェックします)は、lengthパラメータに入れたものではありません。つまり、msyncです。 strlen(rendered)ですが、ファイルの元のサイズはstrlen(f)です。

次に、length512128などのハードコードで割り当てようとしましたが、すべてが機能しないことがわかりました。 mmapからファイルに書き戻されるサイズは、依然としてmmaped charの元のサイズです。

しかしmsyncのマニュアルでは、それは言う:

addrから始まる長さlengthが更新されたメモリ領域に対応するファイルの一部。

だから私は困惑し、どのように私がディスクにフラッシュしたいアドレスの長さを割り当てることができるか教えてくれますか?

+0

'msync'は基本となるマッピングのサイズを変更できません。元のファイルサイズを 'mmap'しただけで、マップされたアドレスからサイズを変更することはできません。 – kaylum

+0

ディスクへのリード/ライトはブロック単位で行われ、mmap()はリード/ライト時に構築されます。歴史的にブロックサイズは512バイトですが、今日では4096バイトです。部分ブロックを書くことはできません。 (ファイルを切り捨てることができます。その場合、最後のブロックの一部だけが*表示されます*) – joop

+0

"メモリ領域に対応するファイルの部分"を引用するmsyncのmanページの "updated"長さの更新を参照していません。 – kaylum

答えて

0

コメントに私をインスパイアしてくれてくれてありがとう、申し訳ありませんが、私はマニュアルをよく読んでいませんでした。

msyncはマップしたサイズを拡張できません。mmapはファイルサイズより大きなサイズではありません。だからここ

はアイデアです:

  1. 増加私はresize_remap機能を実装するためにあり

新しいコンテンツでF MSYNCリマップされたファイルサイズ

  • アンマップ
  • remmap
  • result_t file_remap_resize(int* fd, char** f, int new_size){ 
        if(ftruncate(*fd, new_size) == -1){ 
         printf("failed to resize\n"); 
         return ERR_CODE; 
        } 
        if(munmap(*f, sizeof(*f)) == -1){ 
         printf("failed to unmap\n"); 
         return ERR_CODE; 
        } 
        *f = (char*)mmap (0, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
        if(!f){ 
         printf("failed to remap\n"); 
         return ERR_CODE; 
        } 
        return SUCCESS 
    } 
    

    次に、プログラムは次のようである:

    char* rendered = cJSON_Print(root); 
    file_remap_resize(&fd, &f, strlen(rendered)); 
    memcpy(f, rendered, strlen(rendered)); 
    msync(f, strlen(renderer), MS_SYNC); 
    

    、それが動作します!

    変更されたファイルをディスクにフラッシュバックすることができます。

  • 関連する問題