#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
unsigned char count = 0;
char *s_gets(void);
struct TEST {
char *p; // 字符串指针
int b; // 整数
struct TEST *next; // 指向下一个结构体的指针
};
// 在链表末尾插入节点
struct TEST *back_insert(struct TEST *head, struct TEST *new) {
struct TEST *tmp = head;
if (tmp == NULL) {
head = new;
return head;
}
while (tmp->next != NULL) {
tmp = tmp->next;
}
tmp->next = new;
return head;
}
// 创建节点
struct TEST *creat_node(struct TEST *head) {
struct TEST *new;
while (1) {
new = (struct TEST *)malloc(sizeof(struct TEST));
new->next = NULL;
puts("enter string");
new->p = s_gets(); // 获取用户输入的字符串
if (strcmp(new->p, "end") == 0) { // 如果用户输入 "end" 则结束节点创建过程
printf("over \n");
free(new);
return head;
}
puts("enter data");
scanf("%d", &(new->b)); // 获取用户输入的整数
getchar();
count++;
head = back_insert(head, new); // 将新节点插入链表末尾
}
}
// 打印链表节点内容
void printlist(struct TEST *L) {
while (L != NULL) {
printf("%s \n", L->p); // 打印字符串
printf("%d\n", L->b); // 打印整数
L = L->next; // 指向下一个节点
}
putchar('\n');
}
int main(int argc, char** argv) {
int fdsrc;
fdsrc = open(argv[1], O_RDWR); // 以读写方式打开文件
printf("file_fdsrc=%d\n", fdsrc);
struct TEST *head = NULL;
head = creat_node(head); // 创建链表节点
printlist(head); // 打印链表节点内容
// 写入文件内容
struct TEST *current = head;
printf("count=%d\n", count);
while (current != NULL) {
struct TEST temp;
temp.p = current->p;
temp.b = current->b;
int write_size = write(fdsrc, &temp, sizeof(struct TEST)); // 将结构体写入文件
printf("write struct\n");
current = current->next;
}
// 读取文件内容
lseek(fdsrc, 0, SEEK_SET); // 设置文件偏移量
for (int i = 0; i < count; i++) {
struct TEST ARRAY;
int read_size = read(fdsrc, &ARRAY, sizeof(struct TEST)); // 从文件中读取结构体
printf("string: %s data = %d\n", ARRAY.p, ARRAY.b);
printf("***********************************************************\n");
free(ARRAY.p);
}
count = 0;
close(fdsrc); // 关闭文件
return 0;
}
// 自定义函数,用于获取用户输入的字符串
char *s_gets(void) {
char *ret_vel = malloc(1 * sizeof(char)); // 初始分配1个字节的内存
if (ret_vel != NULL) {
int ch;
size_t len = 0;
while ((ch = getchar()) != '\n' && ch != EOF) {
ret_vel = realloc(ret_vel, (len + 1) * sizeof(char)); // 扩展内存大小
ret_vel[len++] = ch; // 将输入的字符存储到字符串中
}
ret_vel = realloc(ret_vel, (len + 1) * sizeof(char)); // 扩展内存大小
ret_vel[len] = '\0'; // 在字符串的末尾添加空字符,表示字符串的结束
}
return ret_vel; // 返回输入的字符串
}
-
数据完整性:使用二进制方式可以确保数据在存储和读取过程中的完整性。二进制方式将数据以字节流的形式存储,不会对数据进行任何格式转换或解析,能够准确地保留数据的原始状态。
-
结构体写入和读取:该代码中,通过直接将结构体的内存内容写入文件,在读取时同样直接读取特定大小的字节,这样可以确保结构体的完整性。如果使用文本方式进行写入和读取,很可能会导致数据的丢失或错误,因为文本方式会对数据进行编码和解码,从而可能改变数据的内容。
-
通用性:二进制方式在处理各种类型的数据时更加通用。无论是整型、浮点型还是自定义结构体,都可以以二进制方式进行读写。而文本方式则需要将数据转换为字符串表示,可能需要考虑编码和解码的问题,对于某些特殊数据类型可能会存在限制。
综上所述,使用二进制方式进行文件的写入和读取,能够确保数据的完整性,并且具有更高的通用性。但需要注意的是,在读取二进制文件时,需要确保读取的数据按照正确的格式进行解析,以免出现数据错误的情况。
20230811