通过低级I/O读取结构

Cry*_*orm 0 c io struct

对于实验室,我们需要使用低级别的io(open/lseek/close而不是fopen/fseek/fclose)从二进制文件读入并操作数据.我的问题是如何使用这些方法读取或编写结构.

结构如下

typedef struct Entry {
    char title[33];
    char artist[17];
    int  val;
    int  cost;
} Entry_T;
Run Code Online (Sandbox Code Playgroud)

我最初计划sizeof(Entry_T)简单地创建一个缓冲区并读取结构,但我不认为使用低级I/O是可能的.我应该创建4个缓冲区并按顺序填充它们,使用一个缓冲区并重新分配它以获得正确的大小,或者它是完全不同的东西.写作的一个例子也很有用,但我想在看到一个阅读例子之后我可以弄明白.

Jon*_*ler 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);
Run Code Online (Sandbox Code Playgroud)

如果您的结构包含指针或可变长度成员(灵活的数组成员),则必须更加努力.

除非所有数据都是字符串,否则这样写的数据不可移植.如果您在big-endian和little-endian机器之间迁移数据,那么一方会误解对方认为它写的内容.类似地,在单个机器架构上的32位和64位构建之间移动数据时可能会出现问题(long例如,如果您有数据,那么32位系统可能会使用,sizeof(long) == 4)但64位系统可能会使用sizeof(long) == 8- 除非你在Windows上.

  • +1,我希望我可以再次勾选这个可移植性细化.像往常一样,写得很好.@CrypticStorm如果你是dyna-为返回结果分配这个,你可以(a)让*caller*hand*you*一个有效的地址给其中一个并把它们放在*他们*来找出内存的位置来自,或者(b)首先执行此操作,并且仅在*之后*知道它成功(从`read`调用好的retval),使用`malloc()`分配并将本地结构复制到动态的结构,然后返回它是他们`free()`的结果,否则为NULL.就个人而言,我更喜欢这些选项的前者. (2认同)