读取文件字符串MMAP [英] Reading a file to string with mmap

查看:297
本文介绍了读取文件字符串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 like addr, length, or offset (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 neither MAP_PRIVATE or MAP_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 function getpagesize().

这是不实际需要,但必须考虑到,无论哪种方式,映射将始终在系统页面大小的倍数进行帐户,因此,如果你想计算出有多少内存通过返回的指针实际上是可利用,更新尺寸就象这样:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆