是否可以使用 mmap 仅映射文件的一部分?
我有一个输入文件,它有一个像这样的标题:
P6\n
width\n
height\n
depth\n
然后将一个结构体,像素*,写入该文件,该文件将被映射。
因此,我想跳过标头并使 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* ,另一个等于该 + 偏移量。
I have a input file which has a header like this:
P6\n
width\n
height\n
depth\n
and then a struct is writen, pixel*, into this file, which is going to be mapped.
So, I want to skip the header and make my mmap function return the ptr to that structure. How can I do this? with lseek perhaps? Could you please exemplify?
I will leave part of my code here:
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);
}
As you see, right now my ppm image is mapped to char*
data, but I want to skip the header and map just to the pixel*
part.
Here's my code with the suggestion of using 2 pointers, a char* from mmap and another one equals that + offset.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您阅读
mmap
的手册页,您会发现它的最终参数是off_t offset
。描述:我怀疑如果您将偏移量作为该参数传递,它将执行您想要的操作。
If you read the man page for
mmap
, you wil find that its final parameter isoff_t offset
. The description:I suspect if you pass your offset in as that parameter, it will do what you want.
如果您需要跳过的量小于系统页面大小,则不能,因为在某些系统上,
offset
必须是页面大小的倍数。You can't if the amount you need to skip is less than the system page size, since
offset
must be a multiple of the page size on some systems.您只需要保留 2 个指针 - 指向 mmap 块开头的指针,以及指向您想要的数据开头的指针。如:
其中
offset
是文件中所需数据的偏移量。You just need to keep 2 pointers - the pointer to the start of the
mmap
'd block, and the pointer to the start of the data you want inside there. As in:where
offset
is the offset in the file to the data you want.那么,据我了解,我可以做这样的事情吗?
由此,我可以将我的文件映射到我想要的任何类型,在本例中为
pixel*
如果可以,我应该注意什么?例如,就像伊格纳西奥·巴斯克斯·艾布拉姆斯所说
So, from what I understand, can I do something like this?
and, from that, I could map my file to whatever type I want, in this case the
pixel*
If this is ok, what cautions should I take? For example, like those Ignacio Vazquez-Abrams said
嗯,您确实注意到您提供的“偏移”参数为零?假设你知道你想要的绝对偏移量,你就可以通过它。
Um, you did notice the 'offset' parameter that you are supplying with a zero? Assuming you know the absolute offset of what you want, you pass it.