通过低级I / O读取结构

时间:2014-04-28 19:45:22

标签: c struct io

对于实验室,我们需要使用低级别的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个缓冲区并按顺序填充它们,使用一个缓冲区并重新分配它以获得正确的大小,或者它是完全不同的东西。写作的一个例子也很有帮助,但我想在看到一个阅读例子之后我可以弄明白。

3 个答案:

答案 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);