1

100GBのサイズのファイルを開き、毎回ファイルマッピングを使用してチャンクごとにデータを読み取りたいと思います。オフセットが2GBより大きい場合、常に何もマッピングを開始しません。私は64ビットアドレス指定をサポートしていない関数かもしれないと思いました。しかし、ラージファイルサポートを追加した後(ラージファイルサポート定義、ラージファイルオープンオプション、およびコマンド-D_FILE_OFFSET_BITS = 64 -D_LARGE_FILEを使用したコンパイルを含む)。ただし、同じ問題が発生します。簡略化されたコードは次のとおりです。

#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>
#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

int total_piece, PAGE, buffer, share, offset, count, chunk;

void get_size(char * strFileName)   
{  
    struct stat temp;  
    stat(strFileName, &temp);

    PAGE = getpagesize();             
    total_piece = temp.st_size/PAGE;
    chunk = 1024*1024*1024*0.4/PAGE; 

    if (temp.st_size%PAGE!=0)     
    total_piece++;
}

char *
mmaping (char *source)
{
  int src;
  char *sm;
  struct stat statbuf;

  if ((src = open (source, O_RDONLY)) < 0)  //I thought error comes from this line. So I tried to use large file support as following. But still the same. 
    {
      perror (" open source ");
      exit (EXIT_FAILURE);
    }
/*
  if ((src = open64(source, O_RDONLY|O_LARGEFILE, 0644))<0)  
    {
      perror (" open source ");
      exit (EXIT_FAILURE);
    }
*/
  if (fstat (src, &statbuf) < 0)
    {
      perror (" fstat source ");
      exit (EXIT_FAILURE);
    }

  printf("share->%d PAGES per node\n",share);

  if (share>=chunk)
  buffer = chunk;
  else
  buffer = share;

  printf("total pieces->%d\n",total_piece);
  printf("data left->%d\n",share);
  printf("buffer size->%d\n",buffer);
  printf("PAGE size->%d\n",PAGE);

  sm = mmap (0,buffer*PAGE, PROT_READ, MAP_SHARED | MAP_NORESERVE,src, offset*PAGE); 

  if (MAP_FAILED == sm)
    {
      perror (" mmap source ");
      exit (EXIT_FAILURE);
    }

  return sm;
}

main(int argc, char**argv){

   get_size(argv[1]);

   share = total_piece;

   offset = 0;

   while (share>0)
   {

      char *x = mmaping(argv[1]);

      printf("data->%0.30s\n",x); //bus error will occur when offset reaches 2GiB, which proves my thought: it maps          nothing.

      munmap(x,buffer*PAGE);  

      share-=buffer;

      offset+=buffer;

   }

   return 0;
}

誰かが親切でこれを手伝ってくれる?

4

1 に答える 1

5

確かに、Linuxでは32ビットである「int」型の変数は、100GBファイルのバイト単位のサイズを含むのに十分な大きさではありません。ファイルサイズ/オフセットの場合は、代わりに「off_t」タイプを使用する必要があります(これは、これまでのようにLFSサポートを有効にすると、符号付き64ビット整数であるoff64_tのエイリアスになります)。

同様に、mmapの「length」引数は、intではなくsize_t型です。

LFSの有無にかかわらず、32ビットと64ビットの両方のターゲットにコードを移植できるようにするには、どの整数型をどこで使用するかについて注意する必要があります。

于 2012-04-23T09:32:44.920 に答える