读取文件字符串MMAP [英] Reading a file to string with mmap
问题描述
我试图读取文件为一个字符串使用mmap。
I'm trying to read a file to a string using mmap.
我在下面这个例子: http://www.lemoda.net/ C / MMAP,例如/ index.html的
我的code看起来像这样
My code looks like this
unsigned char *f;
int size;
int main(int argc, char const *argv[])
{
struct stat s;
const char * file_name = argv[1];
int fd = open (argv[1], O_RDONLY);
/* Get the size of the file. */
int status = fstat (fd, & s);
size = s.st_size;
f = (char *) mmap (0, size, PROT_READ, 0, fd, 0);
for (i = 0; i < size; i++) {
char c;
c = f[i];
putchar(c);
}
return 0;
}
但访问f出现[I]我总是收到一个segemation故障。
我在做什么错了?
But I always receive a segemation fault when accessing f[i]. What am I doing wrong?
推荐答案
strace的
是你的朋友在这里:
$ strace的./mmap-example MMAP-example.c
...
... (lots of output)
...
open("mmap-example.c", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=582, ...}) = 0
mmap(NULL, 582, PROT_READ, MAP_FILE, 3, 0) = -1 EINVAL (Invalid argument)
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
的 MMAP
手册页告诉你所有你需要知道;)
The mmap
man page tells you all you need to know ;)
-
EINVAL
我们不喜欢地址
,长度
或偏移
(例如,他们太
大或页边界上对齐)。 -
EINVAL
(因为Linux 2.6.12)长度
为0。 -
EINVAL
标记
既不含MAP_PRIVATE
或MAP_SHARED
,或结果
包含这两个值。
EINVAL
We don't likeaddr
,length
, oroffset
(e.g., they are too large, or not aligned on a page boundary).EINVAL
(since Linux 2.6.12)length
was 0.EINVAL
flags
contained neitherMAP_PRIVATE
orMAP_SHARED
, or
contained both of these values.
的 -EINVAL
错误是由标志引起的不能为0。无论是 MAP_PRIVATE
或 MAP_SHARED
已被采摘。我已经能够让使用它的工作 MAP_PRIVATE
在Linux上,X86-64。
The -EINVAL
error is caused by flags that cannot be 0. Either MAP_PRIVATE
or MAP_SHARED
has to be picked. I have been able to make it work by using MAP_PRIVATE
on Linux, x86-64.
所以,你只需MAP_PRIVATE添加到的mmap()
:
So, you have just to add MAP_PRIVATE to mmap()
:
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/io.h>
#include <sys/mman.h>
int main(int argc, char const *argv[])
{
unsigned char *f;
int size;
struct stat s;
const char * file_name = argv[1];
int fd = open (argv[1], O_RDONLY);
/* Get the size of the file. */
int status = fstat (fd, & s);
size = s.st_size;
f = (char *) mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0);
for (int i = 0; i < size; i++) {
char c;
c = f[i];
putchar(c);
}
return 0;
}
请注意:我的第一个答案没有包括对另一个可能的原因 EINVAL
:
大小
必须是系统的页大小的整数倍。至
获得页面大小使用功能为getpagesize()
。
size
must be an integral multiple of the page size of the system. To obtain the page size use the functiongetpagesize()
.
这是不实际需要,但必须考虑到,无论哪种方式,映射将始终在系统页面大小的倍数进行帐户,因此,如果你想计算出有多少内存通过返回的指针实际上是可利用,更新尺寸
就象这样:
This is not actually required, but you must take into account that either way, mapping will be always performed in multiples of the system page size, so if you'd like to calculate how much memory is actually been available through the returned pointer, update size
as this:
int pagesize = getpagesize();
size = s.st_size;
size += pagesize-(size%pagesize);
这篇关于读取文件字符串MMAP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!