2010-11-24 51 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是文件中所需数据的偏移量。

相关问题