已解决:C和Python:通过mmap填充一个文件为空
Resolved: C and Python: fill a file empty through mmap
我想在 C(创建映射文件并且只从中读取)和 python(写入和填充映射文件)之间创建一个共享映射文件。我有这个 C 代码:
#include <sys/types.h>
#include <sys/mman.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
char *shared;
int fd = -1;
fd = open("hello.txt", O_RDWR, 0);
if (fd == -1) {
printf("unable to open");
return 0;
}
shared = (char *)mmap(NULL, 1, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
system("python /home/giuseppe/Documents/test_mmap/mappalo.py");
printf("C CODE: %c\n",shared[0]);
}
这是一个 python 代码:
import sys
import os
import mmap
with open( "hello.txt", "wb" ) as fd:
fd.write("1")
with open( "hello.txt", "r+b" ) as fd:
mm = mmap.mmap(fd.fileno(), 0, flags=mmap.MAP_SHARED, access=mmap.ACCESS_WRITE, offset=0)
print("content read from file")
print(mm.readline())
mm[0] = "01"
mm.close()
fd.close()
当我执行 C 代码时,出现此错误:
content read from file
1
Traceback (most recent call last):
File "/home/giuseppe/Documents/test_mmap/mappalo.py", line 11, in <module>
mm[0] = "01"
IndexError: mmap assignment must be single-character string
C CODE: 1
如何从 python 代码中写入映射文件中的长字符串,然后从 C 代码中读取它?
非常感谢您的宝贵时间
更新
我想写两个字符串,所以我写了这段代码:
arr = bytes("Hello123;", 'utf-8')
arr1 = bytes("Hello412;", 'utf-8')
size = sys.getsizeof(arr) + sys.getsizeof(arr1)
with buf:
buf[:size] = struct.pack('ss', arr1, arr)
但是我有以下错误:
IndexError: mmap slice assignment is wrong size
更新 2
感谢 Sam Mason 让我解决问题。这是代码:
C代码:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int fd = open("hello.txt", O_RDWR | O_CREAT, 0666);
if (fd == -1) {
perror("unable to open");
return 1;
}
if (ftruncate(fd, 4096) < 0) {
perror("unable to set length");
return 1;
}
int *shared = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
//system("python3.7 mappalo.py");
printf("C CODE: %s\n", shared);
return 0;
}
Python代码:
import mmap
import struct
with open('hello.txt', 'r+b') as fd:
buf = mmap.mmap(fd.fileno(), 4096, access=mmap.ACCESS_DEFAULT)
arr = bytes("Hello123;", 'utf-8')
arr1 = bytes("Hello412;", 'utf-8')
size = len(arr) + len(arr1)
types = str(len(arr))+'s' + str(len(arr1))+'s'
with buf:
buf[:size] = struct.pack(types, arr1, arr)
您在 C 代码和 Python 代码中都做了各种奇怪的事情。我将从 "works":
的一些代码开始
首先,C代码:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int fd = open("hello.txt", O_RDWR | O_CREAT, 0666);
if (fd == -1) {
perror("unable to open");
return 1;
}
if (ftruncate(fd, 1024) < 0) {
perror("unable to set length");
return 1;
}
int *shared = mmap(NULL, 1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
system("python mmap-test.py");
printf("C CODE: %i %i\n", shared[0], shared[1]);
return 0;
}
我对 headers 进行了一些修改,并确保文件中包含一些数据(在这种情况下,内核将用零延迟填充)。我也将其视为 int
的数组,因为单个字节传输毫无意义。此外,通常建议您不要从 void*
转换为另一种类型。我还将权限掩码设置为合理的值,零会在以后破坏。
下一个Python代码:
import mmap
import struct
with open('hello.txt', 'r+b') as fd:
buf = mmap.mmap(fd.fileno(), 1024, access=mmap.ACCESS_DEFAULT)
with buf:
buf[:8] = struct.pack('ii', 123, 7901)
我就打开一次,把数据映射进去,把两个Pythonint
编码成两个C-int
的字节数组。 with
语句的 non-nesting 是为了表明 mmap
使文件自行打开,但您可能希望将它们嵌套在您自己的代码中。 Python 中的两个 open
还创建了第二个文件(同名,替换了 C 文件),这可能令人困惑。此外,您没有将正确的 sized/typed 数据写入 mmap
ed space
我想在 C(创建映射文件并且只从中读取)和 python(写入和填充映射文件)之间创建一个共享映射文件。我有这个 C 代码:
#include <sys/types.h>
#include <sys/mman.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
char *shared;
int fd = -1;
fd = open("hello.txt", O_RDWR, 0);
if (fd == -1) {
printf("unable to open");
return 0;
}
shared = (char *)mmap(NULL, 1, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
system("python /home/giuseppe/Documents/test_mmap/mappalo.py");
printf("C CODE: %c\n",shared[0]);
}
这是一个 python 代码:
import sys
import os
import mmap
with open( "hello.txt", "wb" ) as fd:
fd.write("1")
with open( "hello.txt", "r+b" ) as fd:
mm = mmap.mmap(fd.fileno(), 0, flags=mmap.MAP_SHARED, access=mmap.ACCESS_WRITE, offset=0)
print("content read from file")
print(mm.readline())
mm[0] = "01"
mm.close()
fd.close()
当我执行 C 代码时,出现此错误:
content read from file
1
Traceback (most recent call last):
File "/home/giuseppe/Documents/test_mmap/mappalo.py", line 11, in <module>
mm[0] = "01"
IndexError: mmap assignment must be single-character string
C CODE: 1
如何从 python 代码中写入映射文件中的长字符串,然后从 C 代码中读取它?
非常感谢您的宝贵时间
更新 我想写两个字符串,所以我写了这段代码:
arr = bytes("Hello123;", 'utf-8')
arr1 = bytes("Hello412;", 'utf-8')
size = sys.getsizeof(arr) + sys.getsizeof(arr1)
with buf:
buf[:size] = struct.pack('ss', arr1, arr)
但是我有以下错误:
IndexError: mmap slice assignment is wrong size
更新 2 感谢 Sam Mason 让我解决问题。这是代码:
C代码:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int fd = open("hello.txt", O_RDWR | O_CREAT, 0666);
if (fd == -1) {
perror("unable to open");
return 1;
}
if (ftruncate(fd, 4096) < 0) {
perror("unable to set length");
return 1;
}
int *shared = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
//system("python3.7 mappalo.py");
printf("C CODE: %s\n", shared);
return 0;
}
Python代码:
import mmap
import struct
with open('hello.txt', 'r+b') as fd:
buf = mmap.mmap(fd.fileno(), 4096, access=mmap.ACCESS_DEFAULT)
arr = bytes("Hello123;", 'utf-8')
arr1 = bytes("Hello412;", 'utf-8')
size = len(arr) + len(arr1)
types = str(len(arr))+'s' + str(len(arr1))+'s'
with buf:
buf[:size] = struct.pack(types, arr1, arr)
您在 C 代码和 Python 代码中都做了各种奇怪的事情。我将从 "works":
的一些代码开始首先,C代码:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int fd = open("hello.txt", O_RDWR | O_CREAT, 0666);
if (fd == -1) {
perror("unable to open");
return 1;
}
if (ftruncate(fd, 1024) < 0) {
perror("unable to set length");
return 1;
}
int *shared = mmap(NULL, 1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
system("python mmap-test.py");
printf("C CODE: %i %i\n", shared[0], shared[1]);
return 0;
}
我对 headers 进行了一些修改,并确保文件中包含一些数据(在这种情况下,内核将用零延迟填充)。我也将其视为 int
的数组,因为单个字节传输毫无意义。此外,通常建议您不要从 void*
转换为另一种类型。我还将权限掩码设置为合理的值,零会在以后破坏。
下一个Python代码:
import mmap
import struct
with open('hello.txt', 'r+b') as fd:
buf = mmap.mmap(fd.fileno(), 1024, access=mmap.ACCESS_DEFAULT)
with buf:
buf[:8] = struct.pack('ii', 123, 7901)
我就打开一次,把数据映射进去,把两个Pythonint
编码成两个C-int
的字节数组。 with
语句的 non-nesting 是为了表明 mmap
使文件自行打开,但您可能希望将它们嵌套在您自己的代码中。 Python 中的两个 open
还创建了第二个文件(同名,替换了 C 文件),这可能令人困惑。此外,您没有将正确的 sized/typed 数据写入 mmap
ed space