fsync系统调用及示例

fsync - 文件同步

函数介绍

fsync系统调用用于将文件的所有修改强制写入磁盘,确保数据的持久性。它会同步文件的数据和元数据(如修改时间、访问时间等),是保证数据安全的重要函数。掌握fsync系统调用,确保数据安全写入磁盘。了解其功能、用法及示例代码,提升文件操作效率与可靠性。关键词:fsync…

data-ad-format="fluid" data-ad-layout-key="-7k+ex-4a-9w+4a">

fsync系统调用, 文件同步fsync, Linux fsync使用示例, 如何使用fsync确保数据持久性, fsync函数详解, fsync与数据安全, 理解fsync及其重要性, 使用fsync提高文件操作安全性, fsync在编程中的应用, fsync系统调用实战案例

函数原型

1
2
3
4
#include <unistd.h>

int fsync(int fd);

功能

将文件描述符对应的文件所有修改(包括数据和元数据)强制写入磁盘。

参数

  • int fd: 文件描述符

返回值

  • 成功时返回0

失败时返回-1,并设置errno:

  • EBADF: 文件描述符无效

  • EIO: I/O错误

  • EINVAL: 文件描述符不支持同步

  • EROFS: 文件在只读文件系统上

相似函数

  • fdatasync(): 只同步文件数据,不同步所有元数据

  • sync(): 同步所有文件系统缓冲区

  • msync(): 同步内存映射文件

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>

int main() {
int fd;
struct stat stat_buf;
time_t write_time, sync_time;

printf("=== Fsync函数示例 ===\n");

// 示例1: 基本的文件同步操作
printf("\n示例1: 基本的文件同步操作\n");

// 创建测试文件
fd = open("test_fsync.txt", O_CREAT | O_RDWR | O_TRUNC, 0644);
if (fd == -1) {
perror("创建测试文件失败");
exit(EXIT_FAILURE);
}
printf("成功创建测试文件,文件描述符: %d\n", fd);

// 写入数据
const char *data1 = "First line of data\n";
if (write(fd, data1, strlen(data1)) == -1) {
perror("写入第一行数据失败");
close(fd);
exit(EXIT_FAILURE);
}
printf("写入第一行数据: %s", data1);

// 获取写入时间
time(&write_time);
printf("写入时间: %s", ctime(&write_time));

// 同步文件到磁盘
printf("开始同步文件到磁盘...\n");
time(&sync_time);
if (fsync(fd) == -1) {
perror("文件同步失败");
} else {
printf("文件同步成功\n");
printf("同步完成时间: %s", ctime(&sync_time));
}

// 再写入更多数据
const char *data2 = "Second line of data\nThird line of data\n";
if (write(fd, data2, strlen(data2)) == -1) {
perror("写入更多数据失败");
} else {
printf("写入更多数据成功\n");
}

// 再次同步
if (fsync(fd) == -1) {
perror("第二次文件同步失败");
} else {
printf("第二次文件同步成功\n");
}

// 示例2: 同步前后文件状态对比
printf("\n示例2: 同步前后文件状态对比\n");

// 获取同步前的文件状态
if (fstat(fd, &stat_buf) == -1) {
perror("获取文件状态失败");
} else {
printf("同步前文件状态:\n");
printf(" 文件大小: %ld 字节\n", stat_buf.st_size);
printf(" 最后修改时间: %s", ctime(&stat_buf.st_mtime));
printf(" 最后访问时间: %s", ctime(&stat_buf.st_atime));
}

// 写入数据但不同步
const char *unsynced_data = "Unsynced data\n";
if (write(fd, unsynced_data, strlen(unsynced_data)) == -1) {
perror("写入未同步数据失败");
}

// 再次获取文件状态(可能还未写入磁盘)
if (fstat(fd, &stat_buf) == -1) {
perror("再次获取文件状态失败");
} else {
printf("写入未同步数据后的文件状态:\n");
printf(" 文件大小: %ld 字节\n", stat_buf.st_size);
}

// 同步文件
if (fsync(fd) == -1) {
perror("同步文件失败");
} else {
printf("文件同步完成\n");
}

// 同步后再次获取文件状态
if (fstat(fd, &stat_buf) == -1) {
perror("同步后获取文件状态失败");
} else {
printf("同步后文件状态:\n");
printf(" 文件大小: %ld 字节\n", stat_buf.st_size);
printf(" 最后修改时间: %s", ctime(&stat_buf.st_mtime));
}

// 示例3: 性能对比演示
printf("\n示例3: 性能对比演示\n");

// 测试不使用fsync的写入性能
clock_t start_time = clock();
for (int i = 0; i < 1000; i++) {
char buffer&#91;50];
sprintf(buffer, "Line %d: Performance test data\n", i);
if (write(fd, buffer, strlen(buffer)) == -1) {
perror("性能测试写入失败");
break;
}
}
clock_t without_sync_time = clock() - start_time;
printf("不使用fsync写入1000行数据耗时: %f 秒\n",
((double)without_sync_time) / CLOCKS_PER_SEC);

// 测试使用fsync的写入性能
start_time = clock();
for (int i = 1000; i < 2000; i++) {
char buffer&#91;50];
sprintf(buffer, "Line %d: Performance test data with sync\n", i);
if (write(fd, buffer, strlen(buffer)) == -1) {
perror("性能测试写入失败");
break;
}
if (fsync(fd) == -1) {
perror("同步失败");
break;
}
}
clock_t with_sync_time = clock() - start_time;
printf("使用fsync写入1000行数据耗时: %f 秒\n",
((double)with_sync_time) / CLOCKS_PER_SEC);

printf("注意: fsync会显著降低写入性能,但保证数据安全\n");

// 示例4: 错误处理演示
printf("\n示例4: 错误处理演示\n");

// 尝试对无效文件描述符同步
if (fsync(999) == -1) {
printf("对无效文件描述符同步: %s\n", strerror(errno));
}

// 尝试对只读文件同步(应该成功)
int readonly_fd = open("test_fsync.txt", O_RDONLY);
if (readonly_fd != -1) {
if (fsync(readonly_fd) == -1) {
printf("对只读文件同步: %s\n", strerror(errno));
} else {
printf("对只读文件同步成功\n");
}
close(readonly_fd);
}

// 示例5: 数据安全重要性演示
printf("\n示例5: 数据安全重要性演示\n");

// 创建重要的数据文件
int important_fd = open("important_data.txt", O_CREAT | O_RDWR | O_TRUNC, 0644);
if (important_fd != -1) {
printf("创建重要数据文件\n");

// 写入重要数据
const char *important_data = "Very important data that must not be lost\n";
if (write(important_fd, important_data, strlen(important_data)) != -1) {
printf("写入重要数据\n");

// 对于重要数据,必须同步到磁盘
if (fsync(important_fd) == -1) {
perror("重要数据同步失败");
} else {
printf("重要数据已安全同步到磁盘\n");
}
}

close(important_fd);
unlink("important_data.txt");
}

// 清理资源
printf("\n清理资源...\n");
if (close(fd) == -1) {
perror("关闭文件失败");
} else {
printf("成功关闭文件描述符 %d\n", fd);
}

if (unlink("test_fsync.txt") == -1) {
perror("删除测试文件失败");
} else {
printf("成功删除测试文件\n");
}

return 0;
}

fsync系统调用及示例-CSDN博客

https://www.calcguide.tech/2025/09/08/fsync系统调用及示例/

data-ad-format="auto" data-full-width-responsive="true">