2010-11-24 77 views
3

我有具有這樣的報頭中的輸入的文件:是否可以使用mmap映射文件的一部分?

P6\n 
width\n 
height\n 
depth\n 

,然後一個結構被writen,像素*,到這個文件中,這是將要被映射。

所以,我想跳過標題,並讓我的mmap函數返回該結構的ptr。我怎樣才能做到這一點?也許lseek?你能舉個例子嗎?

我會在這裏留下我的代碼部分:

printf("Saving header to output file\n"); 
    if (writeImageHeader(h, fpout) == -1) { 
     printf("Could not write to output file\n"); 
     return -1; 
    } 

    last_index = (int)ftell(fpout); 
    //printf("offset after header= %d\n",last_index); 

    //alloc mem space for one row (width * size of one pixel struct) 
    row = malloc(h->width * sizeof (pixel)); 

    /*Create a copy of the original image to the output file, which will be inverted*/ 
    printf("Starting work\n"); 
    for (i = 0; i < h->height; i++) { 
     printf("Reading row... "); 
     if (getImageRow(h->width, row, fpin) == -1) { 
      printf("Error while reading row\n"); 
     } 
     printf("Got row %d || ", (i + 1)); 

     printf("Saving row... "); 
     if (writeRow(h->width, row, fpout) == -1) { 
      printf("Error while reading row\n"); 
     } 
     printf("Done\n"); 
    } 


    /*Open file descriptor of the ouput file. 
    * O_RDWR - Read and Write operations both permitted 
    * O_CREAT - Create file if it doesn't already exist 
    * O_TRUNC - Delete existing contents of file*/ 
    if ((fdout = open(argv[2], O_RDWR, FILE_MODE)) < 0) { 
     fprintf(stderr, "Can't create %s for writing\n", argv[2]); 
     exit(1); 
    } 

    /*Get size of the output file*/ 
    if (fstat(fdout, &sbuf) == -1) { 
     perror("Stat error ---------->\n"); 
     exit(1); 
    } 
    //printf("Size of output file: %d\n",(int)sbuf.st_size); 

    /*Maps output file to memory*/ 
    if ((data = mmap((caddr_t) 0, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, 0)) == (caddr_t) (-1)) { 
     perror("Error mmaping"); 
     exit(EXIT_FAILURE); 
    } 

正如你看到的,現在我的PPM圖像映射到char*數據,但我想跳過頭和只映射到pixel*部分。

這裏是我的代碼,建議使用2個指針,一個來自mmap的char *,另一個指向+ offset。

main
c functions
header
makefile

+1

爲什麼不只是使用一點指針算術和一個更多的指針變量? – thkala 2010-11-24 01:51:16

+0

請注意,`caddr_t`是來自pre-ANSI C的廢話。與`mmap`一起使用的類型是`void *`。 – 2010-11-24 02:11:17

+0

@R ..:那麼我怎樣才能以正確的方式調用mmap?這是一個老師的例子,大聲笑 – neverMind 2010-11-24 02:36:55

回答

-1

嗯,你沒發現你是一個零供應 '偏移' 參數?假設你知道你想要的絕對偏移量,就通過它。

0

如果您閱讀mmap的手冊頁,您將發現其最終參數是off_t offset。描述:

...繼續或最多'len'字節從'fd'描述的對象映射,從字節偏移'offset'開始。

我懷疑如果你通過你的偏移作爲參數,它會做你想做的。

1

如果您需要跳過的數量小於系統頁面大小,則不能這樣做,因爲offset必須是某些系統上頁面大小的倍數。

0

所以,據我所知,我可以做這樣的事情嗎?

off_t offset_after_header = lseek(fdout, last_index, SEEK_SET); 
    printf("Pointer is on %d\n",(int)offset_after_header); 
    /*Maps output file to memory*/ 
    if ((data = mmap((caddr_t) 0, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, offset_after_header)) == (caddr_t) (-1)) { 
     perror("Error mmaping"); 
     exit(EXIT_FAILURE); 
    } 

,並從那個,我可以在pixel*

映射我的文件,我想要的類型,在這種情況下,如果這是確定的,有什麼注意事項應該帶?例如,像那些Ignacio Vazquez-Abrams所說的那樣

1

你只需要保留2個指針 - 指向mmap'd塊的開始處的指針,並指向你想要的數據的開始位置。如在:

unsigned char *block = mmap(0, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, 0); 
unsigned char *data = block + offset; 

其中offset是文件中所需數據的偏移量。

相關問題