我对使用Python非常陌生,并且对C非常生疏,所以我提前道歉我的声音是多么愚蠢和/或丢失.
我在C中有函数创建一个包含数据的.dat文件.我使用Python打开文件来读取文件.我需要阅读的一件事是在C函数中创建并以二进制打印的结构.在我的Python代码中,我在文件的相应行中读取结构.我已经尝试了逐项解开stuct项目并且整体没有成功.结构中的大多数项目在C代码中被声明为"真实".我正在与其他人一起研究这个代码,主要的源代码是他的,并且已经将变量声明为"真实".我需要把它放在一个循环中,因为我想读取目录中以'.dat'结尾的所有文件.要开始循环,我有:
for files in os.listdir(path):
if files.endswith(".dat"):
part = open(path + files, "rb")
for line in part:
Run Code Online (Sandbox Code Playgroud)
然后我读取包含结构的那一行之前的所有行.然后我到达那条线并且:
part_struct = part.readline()
r = struct.unpack('<d8', part_struct[0])
Run Code Online (Sandbox Code Playgroud)
我试图只读取存储在结构中的第一件事.我在这里看到了一个这样的例子.当我尝试这个时,我收到的错误是:
struct.error: repeat count given without format specifier
Run Code Online (Sandbox Code Playgroud)
我会接受别人可以给我的任何和所有提示.我已经坚持了几天,并尝试了许多不同的东西.老实说,我认为我不理解struct模块,但我已尽可能多地阅读它.
谢谢!
jfs*_*jfs 15
您可以使用ctypes.Structure或struct.Struct指定文件的格式.要从@ perreal的答案中读取C代码生成的文件中的结构:
"""
struct { double v; int t; char c;};
"""
from ctypes import *
class YourStruct(Structure):
_fields_ = [('v', c_double),
('t', c_int),
('c', c_char)]
with open('c_structs.bin', 'rb') as file:
result = []
x = YourStruct()
while file.readinto(x) == sizeof(x):
result.append((x.v, x.t, x.c))
print(result)
# -> [(12.100000381469727, 17, 's'), (12.100000381469727, 17, 's'), ...]
Run Code Online (Sandbox Code Playgroud)
见io.BufferedIOBase.readinto().它在Python 3中受支持,但在Python 2.7中没有记录默认文件对象.
struct.Struct需要明确指定填充字节(x):
"""
struct { double v; int t; char c;};
"""
from struct import Struct
x = Struct('dicxxx')
with open('c_structs.bin', 'rb') as file:
result = []
while True:
buf = file.read(x.size)
if len(buf) != x.size:
break
result.append(x.unpack_from(buf))
print(result)
Run Code Online (Sandbox Code Playgroud)
它产生相同的输出.
为避免不必要的复制Array.from_buffer(mmap_file),可以使用从文件中获取结构数组:
import mmap # Unix, Windows
from contextlib import closing
with open('c_structs.bin', 'rb') as file:
with closing(mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_COPY)) as mm:
result = (YourStruct * 3).from_buffer(mm) # without copying
print("\n".join(map("{0.v} {0.t} {0.c}".format, result)))
Run Code Online (Sandbox Code Playgroud)
一些C代码:
#include <stdio.h>
typedef struct { double v; int t; char c;} save_type;
int main() {
save_type s = { 12.1f, 17, 's'};
FILE *f = fopen("output", "w");
fwrite(&s, sizeof(save_type), 1, f);
fwrite(&s, sizeof(save_type), 1, f);
fwrite(&s, sizeof(save_type), 1, f);
fclose(f);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
一些Python代码:
import struct
with open('output', 'rb') as f:
chunk = f.read(16)
while chunk != "":
print len(chunk)
print struct.unpack('dicccc', chunk)
chunk = f.read(16)
Run Code Online (Sandbox Code Playgroud)
输出:
(12.100000381469727, 17, 's', '\x00', '\x00', '\x00')
(12.100000381469727, 17, 's', '\x00', '\x00', '\x00')
(12.100000381469727, 17, 's', '\x00', '\x00', '\x00')
Run Code Online (Sandbox Code Playgroud)
但也存在填充问题.填充大小save_type为16,所以我们再读3个字符并忽略它们.