7

大きなファイルを読み取るためのCコードを作成する必要があります。コードは以下のとおりです。

int read_from_file_open(char *filename,long size)
{
    long read1=0;
    int result=1;
    int fd;
    int check=0;
    long *buffer=(long*) malloc(size * sizeof(int));
    fd = open(filename, O_RDONLY|O_LARGEFILE);
    if (fd == -1)
    {
       printf("\nFile Open Unsuccessful\n");
       exit (0);;
    }
    long chunk=0;
    lseek(fd,0,SEEK_SET);
    printf("\nCurrent Position%d\n",lseek(fd,size,SEEK_SET));
    while ( chunk < size )
    {
        printf ("the size of chunk read is  %d\n",chunk);
        if ( read(fd,buffer,1048576) == -1 )
        {
            result=0;
        }
        if (result == 0)
        {
            printf("\nRead Unsuccessful\n");
            close(fd);
            return(result);
        }

        chunk=chunk+1048576;
        lseek(fd,chunk,SEEK_SET);
        free(buffer);
    }

    printf("\nRead Successful\n");

    close(fd);
    return(result);
}

ここで私が直面している問題は、渡された引数(サイズパラメーター)が264000000バイト未満である限り、読み取ることができるように見えることです。サイクルごとにチャンク変数のサイズが大きくなっています。

264000000バイト以上を渡すと、読み取りは失敗します。つまり、使用されたチェックによると、読み取りは-1を返します。

なぜこれが起こっているのか誰かが私に指摘できますか?DD64を使用せず、通常モードでccを使用してコンパイルしています。

4

3 に答える 3

10

そもそも、なぜlseek()自分のサイクルに必要なのか?read()は、読み取ったバイト数だけファイル内のカーソルを進めます。

そして、トピックに: long と、それぞれのチャンクは最大値 を持ち、2147483647それより大きい数値は実際には負になります。

off_tchunk: を宣言するために使用しoff_t chunk、 size asを使用しsize_tます。lseek()それが失敗する最大の理由です。

free()そして、繰り返しますが、他の人が気づいたように、サイクル内でバッファリングしたくありません。

すでに読み取ったデータを上書きすることにも注意してください。さらに、read()必ずしも要求したほど多くを読み取るとは限らないため、読み取りたいバイト数ではなく、実際に読み取ったバイト数だけチャンクを進める方が適切です。

すべてを考慮すると、正しいコードはおそらく次のようになります。

// Edited: note comments after the code
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif

int read_from_file_open(char *filename,size_t size)
{
int fd;
long *buffer=(long*) malloc(size * sizeof(long));
fd = open(filename, O_RDONLY|O_LARGEFILE);
   if (fd == -1)
    {
       printf("\nFile Open Unsuccessful\n");
       exit (0);;
    }
off_t chunk=0;
lseek(fd,0,SEEK_SET);
printf("\nCurrent Position%d\n",lseek(fd,size,SEEK_SET));
while ( chunk < size )
  {
   printf ("the size of chunk read is  %d\n",chunk);
   size_t readnow;
   readnow=read(fd,((char *)buffer)+chunk,1048576);
   if (readnow < 0 )
     {
        printf("\nRead Unsuccessful\n");
        free (buffer);
        close (fd);
        return 0;
     }

   chunk=chunk+readnow;
  }

printf("\nRead Successful\n");

free(buffer);
close(fd);
return 1;

}

また、単純化できると信じているため、結果変数と関連するすべてのロジックを自由に削除しました。

編集: 一部のシステム (特に BSD)O_LARGEFILEには が必要ないため、 が含まれていないことに注意しました。そのため、最初に #ifdef を追加しました。これにより、コードの移植性が向上します。

于 2012-08-03T08:57:20.187 に答える
2

lseek 関数は、大きなファイル サイズをサポートするのが難しい場合があります。lseek64を使ってみる

リンクをチェックして、lseek64 関数を使用するときに定義する必要がある関連マクロを確認してください。

于 2012-08-03T07:07:45.310 に答える
0

32 ビット マシンの場合、4 GB を超えるファイルを読み取る際に問題が発生します。したがって、gcc コンパイラを使用している場合は、マクロ-D_LARGEFILE_SOURCE=1-D_FILE_OFFSET_BITS=64.

こちらのリンクもご確認ください

他のコンパイラを使用している場合は、同様のタイプのコンパイラ オプションを確認してください。

于 2012-08-03T09:24:31.320 に答える