搜索
查看: 540|回复: 9

请教内存映射文件(mmap),谢谢

[复制链接]

1

主题

5

帖子

27

积分

新手入门

Rank: 1

积分
27
发表于 2017-11-2 21:58:21 | 显示全部楼层 |阅读模式
大家好,本人新手,这几天在研究内存映射文件,然后看了一个原生的winApi,然后使用了aardio封装的mmap库,使用时提示 拒绝访问

代码如下:

import console;
import fsys.mmap;
import fsys.file;


fmap = fsys.mmap("d:/d.txt","a");
ptr = fmap.mapView(3)



/*
a,b = fmap.write("hello",5);
console.log(a,b)
*/



buffer,str = fmap.read(5);
console.log(buffer,str)


fmap.unmapView(ptr);
fmap.close();

console.pause(true);



回复

使用道具 举报

1

主题

5

帖子

27

积分

新手入门

Rank: 1

积分
27
 楼主| 发表于 2017-11-2 21:59:03 | 显示全部楼层
是测试代码,有点乱,请各们指点一下,并给出一个实例,比如读写大文件,把内存映射文件原理也通俗的解说一下,网上说的太专业了,有点迷糊。
回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
发表于 2017-11-2 22:28:22 | 显示全部楼层
comeon123 发表于 2017-11-2 21:59
是测试代码,有点乱,请各们指点一下,并给出一个实例,比如读写大文件,把内存映射文件原理也通俗的解说一 ...

不可能每个介绍内存映射文件的文章都让你迷糊吧,
难道这世界上就没有一个人写的能让你明白的?!

另外你的代码测试没有权限拒绝什么的。
共享名字可以不写,写也不要写个"a",写个不会跟系统其他进程冲突的名字。
fsys.mmap已经封装的非常简单,write函数写入数据,read函数读出数据,这个跟使用文件对象一样简单,
你要通俗易懂的话用这两个函数就可以了。

mapView这些函数对新手的确不太合适,一般没必要用这些。
回复

使用道具 举报

1

主题

5

帖子

27

积分

新手入门

Rank: 1

积分
27
 楼主| 发表于 2017-11-2 23:09:36 | 显示全部楼层
Jacen.He 发表于 2017-11-2 22:28
不可能每个介绍内存映射文件的文章都让你迷糊吧,
难道这世界上就没有一个人写的能让你明白的?!

谢谢版主的指点,我记住了,
能否给个实例,也让新手学习一下mapview,,谢谢版主
回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
发表于 2017-11-2 23:16:36 | 显示全部楼层
comeon123 发表于 2017-11-2 23:09
谢谢版主的指点,我记住了,
能否给个实例,也让新手学习一下mapview,,谢谢版主


库函数的用法查询“库函数文档”

如果有疑问,注意表达清楚你的问题,对哪个函数的用法哪个参数不了解。
回复

使用道具 举报

1

主题

5

帖子

27

积分

新手入门

Rank: 1

积分
27
 楼主| 发表于 2017-11-3 15:35:54 | 显示全部楼层
Jacen.He 发表于 2017-11-2 23:16
库函数的用法查询“库函数文档”

如果有疑问,注意表达清楚你的问题,对哪个函数的用法哪个参数不了 ...

我第一次听说内存映射文件,是遇到一个大文件的读写,然后到网上找了一些案例,通过其他语言实现了
大概步骤如下:
1,打开文件
2,创建文件映射
3,把映射视图到进程空间
4,开始操作自己的业务
5,关闭文件,关闭映射视图


然后用aardio时,我仔细看了一下mmap的封装,发现几个问题

1,把数据写文件
import console;
import fsys.mmap;

fileMap = fsys.mmap("d:/test.txt","hello");
for(i=1;100000;1){
        fileMap.write('abcefghaaaa\r\n');
}

fileMap.close();
console.pause(true);

然后运行程序,等程序结束之后,发现文件中确实写入数据,但是都是二进制,然后我把mmap库封装的构造函数,在创建文件
时以读写方式打开,去掉了二进制,如:
var file,err = ..fsys.file( path,"w+",3/*_FILE_SHARE_READ | _FILE_SHARE_WRITE*/,creation, 0x8000000/*_FILE_FLAG_SEQUENTIAL_SCAN*/,secAttrib);
if(!file) return null,err;

然后又运行了一下程序,结果发现数据也写入进来了并能清楚的看到数据了,但是后面多了一段二进制数据,不知道为什么?难道是每次调用write都写入64M数据吗?我在构造mmap时,第3个参数指定了大小,也是不可以



2,读出数据
读取数据,我就不知道怎么玩了,因为fsys.mmap在构造时,会清空文件并创建一个新文件。 最后我只能这样做的,但是没有运行起来,
import console;
import fsys.mmap;

fileMap1 = fsys.mmap("d:/test.txt","world");
for(i=1;100000;1){
        fileMap1.write('abcefghaaaa\r\n');
}

第二次创建mmap时,我传了一个文件映射对象,但是在这里好像没有创建成功
fielMap2 = fsys.mmap(fileMap1);
str = fielMap2.readTable();
console.log(str)

fileMap1.close();
fileMap2.close();
console.pause(true);

我遇到的问题是,如果我要读取一个文件,怎么做呢?


上面的问题,如果我通过I/O读取的方式,很愉快的就可以解决,但是我就想用内存映射文件的方式解决,所以遇到问题了,还请版主帮忙解决一下,如果表达有误,请见谅,谢谢。
回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
发表于 2017-11-3 16:04:20 | 显示全部楼层
comeon123 发表于 2017-11-3 15:35
我第一次听说内存映射文件,是遇到一个大文件的读写,然后到网上找了一些案例,通过其他语言实现了
大概 ...


即然用其他语言都已经会用内存映射文件了,
应该比其他人更快掌握这个东西才对,怎么反而迷糊了呢?!

你代码里的  fileMap.write('abcefghaaaa\r\n');
我试了写的数据都是正常的,没有问题。你写的 '\r\n'本就是二进制数据,文本模式应该写 '\n',即然用其他语言都会写了,怎么会犯这种低级错误呢?!

"w+" 模式只是会自动的把‘\n’替换为'\r\n'而已,即然你用的已经是'\r\n',就没有必要去改,内存映射文件以二进制模式写就可以了,并不是说你就不可以写文本了,文本本质也都是二进制,在aardio里字符串不用区分文本和二进制,没有这些烦恼。

--------------------------------------------------------------------------------------

fsys.mmap 的用法很简单,看看文档就会用的,用法跟aardio文件流对象是基本一样的:
import console;
import fsys.mmap;

//打开一个内存映射文件
var mm = fsys.mmap("/test.txt");

//写数据进去
mm.write('abcefghaaaa\r\n');

//移动到文件开始
mm.seek("set",0);

//读数据出来
var str  = mm.read(10)

console.log(str);
console.pause(
true);


回复

使用道具 举报

1

主题

5

帖子

27

积分

新手入门

Rank: 1

积分
27
 楼主| 发表于 2017-11-3 17:05:45 | 显示全部楼层
Jacen.He 发表于 2017-11-3 16:04
即然用其他语言都已经会用内存映射文件了,
应该比其他人更快掌握这个东西才对,怎么反而迷糊了呢?! ...

1,我说迷糊是因为对有概念不太完全理解,但是多多少少写,还是能写点出来的。主要还是想听Jacen用自己的语言说一下你的理解,因为你对编程的理解是非常深刻的,表达出来的东西,是不一样的。世界上肯定有的文档我能看懂的,只不过我没有发现,但是换句话说,百度一下内存映射文件,基本说法都是一样的,没有人用自己的语言来表达的,并且Jacen是我的偶像,所以更想听你表达一下。
2,我说改成文本方式,是因为程序运行完之后,打开txt文件,显示的是文本,方便查看阅读,而不是二进制,不方便查看,当然了他底层还是二进制了
3,我加\r\n,是想在txt文件中回车换行,方便查看文件内容,因为是windows系统所以加了\r\n

4,你给出的实例,是把数据写到文件,并且也读出来了,但是你查看文件时,会发现有64M

5,比如我现在要读取一个大文件,怎么办
fsys.mmap("/testgo.txt")  如果这样写,那么testgo.txt文件会被清空。

6,如果我读取一个大文件,如果直接传文件映射句柄,那我怎么能得到呢?
回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
发表于 2017-11-3 18:34:59 | 显示全部楼层
comeon123 发表于 2017-11-3 17:05
1,我说迷糊是因为对有概念不太完全理解,但是多多少少写,还是能写点出来的。主要还是想听Jacen用自己的 ...

终于听明白你想干啥了,
fsys.mmap 目前并没有提供你需要的功能(用来读取一个已经存在内容的文件),初始化时是创建一个新文件。
至于64M这个问题,打开的时候可以指定大小的。

回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
发表于 2017-11-4 10:07:03 | 显示全部楼层
改进了一下fsys.mmap,
可以"r+b"模式打开有内容的文件了,也可以自定义fsys.file对象。

不过 fsys.mmap 是用于进程间通信共享内存的( 例如实现 process.command 等 )
并不适合用来读写文件,读写文件用普通的文件流对象就可以了,读写大文件没太大问题。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

手机版|未经许可严禁引用或转载本站文章|站长邮箱|aardio.com|aardio官方社区 ( 皖ICP备09012014号 )

GMT+8, 2018-10-20 03:34 , Processed in 0.078125 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表