2012-03-21 7 views
0

ストリームの半分を実装して、X整数を前後にジャンプできるようにする必要があります。その上、ファイルを開くときに、ファイル内のデータを保持する必要があります。この実装では、私はmmapを使用しようとします。私の問題は、マップされたデータが純粋にゼロである2回目にファイルを開くときです。私のopenメソッドをcreateStreamと呼ばれ、次のようになりますされていますmmapコードのどの設定で、すべてのファイルデータがゼロに設定されていますか?

void MapperOutForward::createStream(const char* filename) 
{ 
    this->filename = filename; 
    pFile = open(filename, O_RDWR | O_CREAT | O_SYNC, S_IRWXG|S_IRWXO|S_IRWXU); 
    if (pFile == -1) 
    { 
     int errsv = errno; 
     cout << "MappedStreamOut createStream open error: " << strerror(errno) << endl; 
    } 

    //getting file size and making the file big enough 
    struct stat filestatus; 
    stat(filename, &filestatus); 
    if(filestatus.st_size < mapSize + 1) 
    { 
     lseek (pFile, mapSize + 1, SEEK_SET); 
     write (pFile, "", 1); 
    } 
    lseek (pFile, 0, SEEK_SET); 

    map = (int*) mmap (0, mapSize, PROT_WRITE | PROT_READ, MAP_PRIVATE, pFile, 0); 
    close (pFile); 

    if (map == (int*) -1) 
    { 
     cout << "MappedStreamOut createStream mmap error: " << strerror(errno) << endl; 
    } 

    numberOfOffsets = 1; 
    numberOfElementsInMap = 0; 

    cout << "Kopirer 5 før og 4 efter i Create" << endl; 
    for(int i = 0; i < numberOfElementsInMap + 5; i++) 
    { 
     cout << map[i] << endl; 
    } 
    cout << "Create numberOfOffsets:numberOfElementsInMap " << numberOfOffsets << ":" << numberOfElementsInMap << endl; 
} 

出力最後に私が行っていたとき、私は、ファイルの先頭に午前開き、最初の5つの整数が0

あることを私に伝えます

openコマンドのO_CREATフラグは、ファイルが存在しない場合にのみ作成し、このコマンドを2回目に呼び出すとファイルのサイズが変更されないようにすることができます。 man open

PROT_WRITE | mmapコマンドのPROT_READフラグは、セキュリティを有効にし、ファイル内の何も変更しないように見えます。

#include "MapperOutForward.h" 

using namespace std; 

#include <cstdlib> 
#include <iostream> 

#include <fcntl.h> 
#include <sys/stat.h> 
#include <cmath> 

MapperOutForward::MapperOutForward(int mapSize) //number of pages 
{ 
    pageSize = getpagesize(); 
    this->mapSize = mapSize * pageSize; //we work in pages 
    numberOfElementsInMap = 0; 
    numberOfOffsets = 0; 
} 

MapperOutForward::~MapperOutForward() 
{ 
    munmap(map, mapSize); 
} 

void MapperOutForward::createStream(const char* filename) 
{ 
    this->filename = filename; 
    pFile = open(filename, O_RDWR | O_CREAT | O_SYNC, S_IRWXG|S_IRWXO|S_IRWXU); 
    if (pFile == -1) 
    { 
     int errsv = errno; 
     cout << "MappedStreamOut createStream open error: " << strerror(errno) << endl; 
    } 

    //getting file size and making the file big enough 
    struct stat filestatus; 
    stat(filename, &filestatus); 
    if(filestatus.st_size < mapSize + 1) 
    { 
     lseek (pFile, mapSize + 1, SEEK_SET); 
     write (pFile, "", 1); 
    } 
    lseek (pFile, 0, SEEK_SET); 

    map = (int*) mmap (0, mapSize, PROT_WRITE | PROT_READ, MAP_PRIVATE, pFile, 0); 
    close (pFile); 

    if (map == (int*) -1) 
    { 
     cout << "MappedStreamOut createStream mmap error: " << strerror(errno) << endl; 
    } 

    numberOfOffsets = 1; 
    numberOfElementsInMap = 0; 

    cout << "Kopirer 5 før og 4 efter i Create" << endl; 
    for(int i = 0; i < numberOfElementsInMap + 5; i++) 
    { 
     cout << map[i] << endl; 
    } 
    cout << "Create numberOfOffsets:numberOfElementsInMap " << numberOfOffsets << ":" << numberOfElementsInMap << endl; 
} 

void MapperOutForward::writeNext(int* data, int numberOfElements) 
{ 
    for(int i = 0; i < numberOfElements; i++) 
    { 
     writeHelper(data[i]); 
    } 

    cout << "Kopirer 5 før og 4 efter i writeNext" << endl; 
    for(int i = numberOfElementsInMap - 5; i < numberOfElementsInMap + 5; i++) 
    { 
     cout << map[i] << endl; 
    } 
    //cout << "WriteNext numberOfOffsets:numberOfElementsInMap " << numberOfOffsets << ":" << numberOfElementsInMap << endl; 
} 

void MapperOutForward::writeHelper(int data) 
{ 
    int sizeOfInt = 4; //bytes 
    if(numberOfElementsInMap >= mapSize/sizeOfInt) //We need to create the next part of the file 
    { 
     munmap(map, mapSize); 

     pFile = open(filename, O_RDWR | O_CREAT | O_SYNC, S_IRWXG|S_IRWXO|S_IRWXU); 

     if (pFile == -1) 
     { 
      std::cout<<"filename: "<<filename<<std::endl; 
      std::cout<<"mapSize: "<<mapSize<<std::endl; 

      int errsv = errno; 
      cout << "MappedStreamOut writeNext open error: " << strerror(errno) << endl; 
     } 

     numberOfOffsets++; 

     //Make the file bigger 
     lseek (pFile, mapSize * numberOfOffsets, SEEK_SET); 
     write (pFile, "", 1); 
     lseek (pFile, 0, SEEK_SET); 

     map = (int*) mmap (0, mapSize, PROT_WRITE | PROT_READ, MAP_PRIVATE, pFile, mapSize * (numberOfOffsets - 1)); 
     close (pFile); 

     if (map == (int*) -1) 
     { 
      cout << "MappedStreamOut writeNext mmap error: " << strerror(errno) << endl; 
     } 

     numberOfElementsInMap = 0; 
    } 

    map[numberOfElementsInMap] = data; 
    numberOfElementsInMap++; 
} 

void MapperOutForward::jumpTo(int offset) 
{ 
    int sizeOfInt = 4; //bytes 
    //cout << "numberOfElementsInMap + offset " << numberOfElementsInMap + offset << endl; 
    //cout << "mapSize/sizeOfInt " << mapSize/sizeOfInt << endl; 
    if(numberOfElementsInMap + offset >= mapSize/sizeOfInt) 
    { 
     munmap(map, mapSize); 

     pFile = open(filename, O_RDWR | O_CREAT | O_SYNC, S_IRWXG|S_IRWXO|S_IRWXU); 

     if (pFile == -1) 
     { 
      std::cout<<"filename: "<<filename<<std::endl; 
      std::cout<<"mapSize: "<<mapSize<<std::endl; 

      int errsv = errno; 
      cout << "MappedStreamOut writeNext open error: " << strerror(errno) << endl; 
     } 

     numberOfOffsets += (int) ceil((double) (numberOfElementsInMap + offset - (mapSize/sizeOfInt))/(mapSize/sizeOfInt)); // rundet op ((resterende antal ints ud over mapSize)/(Antal ints i en mapsize)) = Antal offsets der skal springes 

     //Make the file bigger 
     lseek (pFile, mapSize * numberOfOffsets, SEEK_SET); 
     write (pFile, "", 1); 
     lseek (pFile, 0, SEEK_SET); 

     map = (int*) mmap (0, mapSize, PROT_WRITE | PROT_READ, MAP_PRIVATE, pFile, mapSize * (numberOfOffsets - 1)); 
     close (pFile); 

     if (map == (int*) -1) 
     { 
      cout << "MappedStreamOut writeNext mmap error: " << strerror(errno) << endl; 
     } 

     numberOfElementsInMap = (numberOfElementsInMap + offset - (mapSize/sizeOfInt)) % (mapSize/sizeOfInt); //(resterende antal ints ud over mapSize) % (Antal ints i en mapsize) = Antal elementer ind i offsettet 
     //cout << "JumpTo offsetForward numberOfOffsets:numberOfElementsInMap " << numberOfOffsets << ":" << numberOfElementsInMap << endl; 
    } 
    else if(numberOfElementsInMap + offset < 0) 
    { 
     munmap(map, mapSize); 

     pFile = open(filename, O_RDWR | O_CREAT | O_SYNC, S_IRWXG|S_IRWXO|S_IRWXU); 

     if (pFile == -1) 
     { 
      std::cout<<"filename: "<<filename<<std::endl; 
      std::cout<<"mapSize: "<<mapSize<<std::endl; 

      int errsv = errno; 
      cout << "MappedStreamOut writeNext open error: " << strerror(errno) << endl; 
     } 

     numberOfOffsets += (int) floor((double) (numberOfElementsInMap + offset)/(mapSize/sizeOfInt)); // rundet op ((resterende antal ints ud over mapSize)/(Antal ints i en mapsize)) = Antal offsets der skal springes 

     //Make the file bigger 
     lseek (pFile, mapSize * numberOfOffsets, SEEK_SET); 
     write (pFile, "", 1); 
     lseek (pFile, 0, SEEK_SET); 

     map = (int*) mmap (0, mapSize, PROT_WRITE | PROT_READ, MAP_PRIVATE, pFile, mapSize * (numberOfOffsets - 1)); 
     close (pFile); 

     if (map == (int*) -1) 
     { 
      cout << "MappedStreamOut writeNext mmap error: " << strerror(errno) << endl; 
     } 

     numberOfElementsInMap = (mapSize + (numberOfElementsInMap + offset)) % (mapSize/sizeOfInt); //(resterende antal ints ud over mapSize) % (Antal ints i en mapsize) = Antal elementer ind i offsettet 
     //cout << "JumpTo offsetBacward numberOfOffsets:numberOfElementsInMap " << numberOfOffsets << ":" << numberOfElementsInMap << endl; 
    } 
    else 
    { 
     numberOfElementsInMap += offset; 
     //cout << "JumpTo else numberOfOffsets:numberOfElementsInMap " << numberOfOffsets << ":" << numberOfElementsInMap << endl; 
    } 
} 

void MapperOutForward::closeStream() 
{ 
    munmap(map, mapSize); 
} 

そして、メインのファイルはここにある:クラスのman mmap

残りはここにある

#include "MapperInForward.h" 
#include "MapperOutForward.h" 
//#include "MapperOutBackward.h" 
//#include "MapperInBackward.h" 
//#include "MapperStreamFactory.h" 
#include <functional> 

int main(int argc, const char* argv[]) 
{ 
/*********************Tester Buffer Stream*************************************/ 
    close(open((char*) "mapperTest", O_WRONLY | O_CREAT | O_SYNC | O_TRUNC, S_IRWXG|S_IRWXO|S_IRWXU)); 
    //BufferStreamFactory* bsf = new BufferStreamFactory(3); 

    MapperOutForward* mso = new MapperOutForward(1); 
    mso->createStream((char*) "mapperTest"); 

    int data[4000]; 

    for(int i = 0; i < 4000; i++) 
    { 
     data[i] = i + 1; 
    } 

    mso->writeNext(data, 4000); 
    mso->closeStream(); 

    MapperOutForward* mso1 = new MapperOutForward(1); 
    mso1->createStream((char*) "mapperTest"); 

    data[0] = 9999; 

    mso1->jumpTo(0); 

    mso1->jumpTo(100); 
    mso1->writeNext(data, 1); 

    mso1->jumpTo(1000); 
    mso1->writeNext(data, 1); 

    mso1->jumpTo(-900); 
    mso1->writeNext(data, 1); 

    mso1->closeStream(); 
} 

それはすべてのUbuntu Linux上で実行されているとG ++でコンパイルされています。

これをすべて読んでくれてありがとうと私はあなたを助けてくれることを願っています。

答えて

1

MAP_PRIVATEの代わりにMAP_SHAREDが必要な場合があります。変更がファイルに書き込まれない場合は、the standardで指定します。

MAP_SHAREDMAP_PRIVATE書き込みメモリオブジェクトへ 参照の配置を記述する。 MAP_SHAREDが指定されている場合は、 の参照は下位のオブジェクトを変更します。 MAP_PRIVATEが である場合、呼び出し元プロセス によってマッピングされたデータを変更することは、呼び出し元のプロセスにのみ表示され、基礎となるオブジェクトを変更してはならない。

+0

正解としてあなたをマークすることができるようになるまで3分ほど待ってください。 – RobbingDaHood

関連する問題