1

私のプログラムが 2GB を超えるデータをファイルに保存できない理由がわかりません。これがプログラミングの問題なのか、環境 (OS) の問題なのかわかりません。ここに私のソースコードがあります:

#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#include <math.h>
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*-------------------------------------*/
//for file mapping in Linux
#include<fcntl.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/time.h>
#include<sys/mman.h>
#include<sys/types.h>
/*-------------------------------------*/
#define PERMS 0600
#define NEW(type) (type *) malloc(sizeof(type))
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

void write_result(char *filename, char *data, long long length){

int fd, fq;

  fd = open(filename, O_RDWR|O_CREAT|O_LARGEFILE, 0644);

  if (fd < 0) {
  perror(filename);
  return -1;
  }

  if (ftruncate(fd, length) < 0)
  {
  printf("[%d]-ftruncate64 error: %s/n", errno, strerror(errno));
  close(fd);
  return 0;
  }

  fq = write (fd, data,length);

  close(fd);

  return;

}

main()
{
long long offset = 3000000000; // 3GB
char * ttt;
ttt = (char *)malloc(sizeof(char) *offset);
printf("length->%lld\n",strlen(ttt));  // length=0
memset (ttt,1,offset);
printf("length->%lld\n",strlen(ttt));  // length=3GB
write_result("test.big",ttt,offset);
return 1;
}

私のテストによると、プログラムは 2GB を超えるファイルを生成でき、そのような大きなメモリも割り当てることができます。ファイルにデータを書き込もうとしたときに奇妙なことが起こりました。ファイルを確認したところ、空で、1 で満たされているはずです。

誰でも親切で、これを手伝ってもらえますか?

4

3 に答える 3

0

ここで手足に出て、あなたの問題はmemset()にあるかもしれないと言います。

ここで行う最善のことは、memset()がそれを実行した後、

for (unsigned long i = 0; i < 3000000000; i++) {
  if (ttt[i] != 1) { printf("error in data at location %d", i); break; }
}

書き込もうとしているデータが正しいことを確認したら、1GBなどの小さなファイルの書き込みを調べて、同じ問題が発生するかどうかを確認する必要があります。考えられるすべての変数を排除すると、答えが見つかります。

于 2012-06-23T18:39:12.923 に答える
0

C 文字列とその内容についてもう少し読む必要がmallocありcallocます。

オリジナルでは、呼び出されmain tttたときにメモリ内にあったガベージを指していましたmalloc。これは、ヌル ターミネータ (バイナリ 0 である C 文字列の終了マーカー) が によって返されるガベージのどこにでもある可能性があることを意味しmallocます。

また、malloc割り当てられたメモリのすべてのバイトに触れるわけではないため (そして、多くのことを要求している)、スパース メモリを取得する可能性があります。つまり、メモリは、読み取りまたは書き込みが行われるまで実際には物理的に使用できません。

calloccalloc割り当てられたメモリを割り当てて 0 で埋めます。このため、失敗する傾向が少し高くなります (割り当てられたすべてのバイトに触れるため、OS が割り当てをまばらなままにしておくと、埋めた後にまばらではなくなります)。

上記の問題を修正したコードを次に示します。また、常にからの戻り値を確認し、writeそれに応じて対応する必要があります。それはあなたに任せます...

主要()
{
    long long オフセット = 3000000000; // 3GB
    char * tt;
    //ttt = (char *)malloc(sizeof(char) *offset);
    ttt = (char *)calloc( sizeof( char ), オフセット ); // malloc( ... ) の代わりに
    if( !ttt )
    {
        puts( "calloc が失敗しました。さようなら、さようなら!" );
        終了 ( 87 );
    }

    printf("length->%lld\n",strlen(ttt)); // length=0 (calloc が失敗しない場合、これは期待どおりに機能するようになりました)
    memset( ttt, 1, オフセット );
    ttt[オフセット - 1] = 0; // これで nul で終了し、以下の printf が機能します
    printf("length->%lld\n",strlen(ttt)); // 長さ=3GB
    write_result ("test.big",ttt,offset);
    1 を返します。
}

Linux の達人への注意... スパースが正しい用語ではない可能性があることはわかっています。Linux の詳細に埋もれてからしばらく経っているので、間違っていたら訂正してください。:)

于 2012-06-23T12:49:28.803 に答える
0

iDevice の内部ファイル システムの制限に達しているようです: ios - サイズ 2 GB を超えるリソース ファイルを含むエンタープライズ アプリ

2Gb 以上のファイルは不可能です。そのような量のデータを保存する必要がある場合は、他のツールの使用を検討するか、ファイル チャンク マネージャーを作成する必要があります。

于 2012-06-23T17:44:58.963 に答える