对于实验室,我们需要使用低级别的io(open / lseek / close而不是fopen / fseek / fclose)从二进制文件读入并操作数据。我的问题是如何使用这些方法读取或编写结构。
结构如下
typedef struct Entry {
char title[33];
char artist[17];
int val;
int cost;
} Entry_T;
我最初计划创建一个sizeof(Entry_T)
的缓冲区并简单地读取结构,但我不认为使用低级I / O是可能的。我应该创建4个缓冲区并按顺序填充它们,使用一个缓冲区并重新分配它以获得正确的大小,或者它是完全不同的东西。写作的一个例子也很有帮助,但我想在看到一个阅读例子之后我可以弄明白。
答案 0 :(得分:5)
因为您的结构不包含指针且所有元素都是固定大小,所以您可以简单地编写和读取结构。为简洁起见,省略了错误检查:
const char *filename = "...";
int fd = open(filename, O_RDWR|O_CREAT, 0644);
Entry_t ent1 = { "Spanish Train", "Chris De Burgh", 100, 30 };
ssize_t w_bytes = write(fd, &ent1, sizeof(ent1));
lseek(fd, 0L, SEEK_SET);
Entry_t ent2;
ssize_t r_bytes = read(fd, &ent2, sizeof(ent2));
assert(w_bytes == r_bytes);
assert(w_bytes == sizeof(ent1));
assert(strcmp(ent1.title, ent2.title) == 0);
assert(strcmp(ent1.artist, ent2.artist) == 0);
assert(ent1.val == ent2.val && ent1.cost == ent2.cost);
close(fd);
如果你的结构包含指针或可变长度成员(灵活的数组成员),你必须更加努力。
除非所有数据都是字符串,否则这样写的数据不可移植。如果您在big-endian和little-endian机器之间迁移数据,那么一方会误解对方认为它写的内容。同样,在单机架构上在32位和64位版本之间移动数据时可能会出现问题(例如,如果您有long
数据,那么32位系统可能会使用sizeof(long) == 4)
但64位系统可能会使用sizeof(long) == 8
- 除非你在Windows上。
答案 1 :(得分:1)
低级功能可能是特定于操作系统的。然而,它们通常是这些:
fopen() -> open()
fread() -> read()
fwrite() -> write()
fclose() -> close()
请注意,虽然'fopen()'函数集使用'FILE *'作为表示文件的标记,但'open()'函数集使用整数(int)。
使用read()和write(),您可以编写整个结构。所以,对于:
typedef struct Entry {
char title[33];
char artist[17];
int val;
int cost;
} Entry_T;
您可以选择阅读或写作如下:
{
int fd = (-1);
Entry_T entry;
...
fd=open(...);
...
read(fd, &entry, sizeof(entry));
...
write(fd, &entry, sizeof(entry));
...
if((-1) != fd)
close(fd);
}
答案 2 :(得分:0)
你走了:
Entry_T t;
int fd = open("file_name", _O_RDONLY, _S_IREAD);
if (fd == -1) //error
{
}
read(fd, &t, sizeof(t));
close(fd);