Linux下文件读写的操作

摘要:Linux系统管理与开发课程中对于文件的读写操作的认识并且运用C语言进行模拟读、写和复制操作。

文件开关以及读写说明

读操作read()

read(int fd, void *buf, size_t count);

len: 请求读取的字节数

返回值:

​ -1 :读取失败

​ 0:没有读取到数据

​ n:读取到的字节数(n:1~len)

实际情况下:

​ < 0 : 失败

​ = len: 正常读取

​ = 0~len-1: 读取完毕

写操作write()

write(int fd, const void *buf, size_t count);

返回值:

​ -1 :读取失败

​ n:写入字符个数(n:1~len)

打开文件open()/creat()

creat(文件名称,权限模式); = open(文件名称,O_CREAT,权限模式);

类型:

O_RDONLY O_WRONLY O_RDWR O_APPEND O_CREAT O_TRUNC
只读 只写 读写 末尾追加 若文件存在,此标志无用;若不存在,建新文件 若文件存在,则长度被截为0,属性不变

权限模式:

S_I <权限><对象>

​ 权限:R, W, X, RWX

​ 对象:USR, GRP, OTH, U, G, O

​ 举个栗子:

1
2
3
4
usr:rwx;	group:rw;	other:r;
creat("test", S_IRWXU | S_IRGRP |S_IROTH);
=
open("test",O_CREAT, S_IRWXU | S_IRGRP |S_IROTH)

tips:

权限位:3个八进制数

764

creat(“test”,010764);

关闭文件close()

close(句柄);

读操作

解释一下int main(int argc, char** argv)的意思:

例如一条指令:cp abc.txt xyz.log

argc = 3 (指令的三个部分) argv[0] = cp argv[1]=abc.txt argv[2]= xyz.log

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
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#define LEN 512
int bail(const char* str){
printf("Error(%d):",errno);
perror(str);
exit(-1);
}

int main(int argc, char** argv){
int fd = -1;
char buf[LEN] = {0};
int read_return = -1;
fd = open(argv[1],O_RDONLY);
if(fd < 0)
bail("open file error.");
printf("fd = %d \n",fd);

read_return = read(fd, buf, sizeof(buf));
while(read_return > 0)
{
printf("%s",buf);
memset(buf, 0, sizeof(buf));
read_return = read(fd, buf, sizeof(buf));
}
if (read_return < 0){
close(fd);
bail("read file error.");
}

close(fd);
return 0;
}

写操作

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
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#define LEN 512
int bail(const char* str)
{
printf("Error(%d):",errno);
perror(str);
exit(-1);
}

int main(int argc, char** argv)
{
int fd = -1;
char buf[LEN] = {0};
int write_return = -1;
int read_return = -1;
//fd = open(argv[1],O_WRONLY); //以只写的方式写入
//fd = open(argv[1],O_WRONLY | O_APPEND); //以只写+尾部追加的方式写入
fd = open(argv[1],O_CREAT | O_WRONLY | O_APPEND, S_IRUSR | S_IRGRP | S_IROTH);
if(fd < 0)
bail("open file error.");
printf("fd = %d \n",fd);
printf(">");
gets(buf);
while(strcmp(buf, "quit") != 0)
{
write_return = write(fd, buf, strlen(buf));
if(write_return <0)
{
close(fd);
bail("Write file error.");
}
memset(buf , 0, sizeof(buf));
printf(">");
gets(buf);
}


close(fd);
return 0;
}

复制功能的实现

  1. 打开源文件
  2. 创建目标文件
  3. 读取源文件
  4. 写入目标文件
  5. 关闭句柄退出
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
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#define LEN 512
int bail(const char* str)
{
printf("Error(%d):",errno);
perror(str);
exit(-1);
}

int main(int argc, char** argv)
{
int read_fd = -1;
int write_fd = -1;
char buf[LEN] = {0};
int write_return = -1;
int read_return = -1;

read_fd = open(argv[1],O_RDONLY);
write_fd = open(argv[2],O_CREAT | O_RDWR , 010755);
if(read_fd < 0)
bail("open file error.");
if(write_fd < 0)
{
close(read_fd);
bail("Create file error.");
}

read_return = read(read_fd, buf, sizeof(buf));
while( read_return > 0)
{
write_return = write(write_fd, buf , read_return);
if(write_return < read_return)
{
close(read_fd);
close(write_fd);
bail("Write file error.");
}
memset(buf, 0, sizeof(buf));
read_return = read(read_fd, buf, sizeof(buf));
}

if(read_fd < 0)
{
close(read_fd);
close(write_fd);
bail("Read file error.");
}

close(read_fd);
close(write_fd);
return 0;
}

tips:

复制操作中关于文件权限判断和使用的问题未能成功实现,留待下次更新。

—3.18更新—

访问文件(判断权限)

access函数使用方法:

access(“文件名称”,测试权限)

测试权限:

​ R_OK:读可以

​ W_OK:写可以

​ X_OK:执行可以

​ F_OK:文件存在

返回值:

​ 0:测试成功

​ -1:测试失败

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
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>

int bail(const char* str){
printf("Error(%d):",errno);
perror(str);
exit(-1);
}

int main(int argc, char** argv)
{
int ret = -1;
ret = access(argv[1],F_OK);
//ret = access(argv[1],F_OK | X_OK); //同时检测满足文件是否同时存在和可执行
if (ret < 0)
printf("File not exist.\n");
else
printf("File exist.\n");
close(ret);
return 0;
}

这就很好的解释了在读写前可以使用access函数判断权限。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
读操作:

ret = access(argv[1],F_OK | R_OK);

if (ret ==0)

fd = open();

写操作:

ret = access(argv[1],F_OK );

if(ret <0)

fd = creat();

else

printf("overwrite?");

获取状态信息

stat函数:

struct stat st;

stat(“文件名”,&st);

返回值:

​ -1:失败

st返回值:

​ st.st_size:文件大小

​ st.st_mode:文件类型、权限

​ st.st_xtim:时间相关参数(秒为单位,用ctime转换)

​ st.mode:

​ ①st.mode&S_IFMT

​ ②宏函数:S_ISDIR、S_ISREG、S_ISLNK、S_ISFIFO、S_ISCHR、S_ISSOCK

获取文件信息

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
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>

int bail(const char* str){
printf("Error(%d):",errno);
perror(str);
exit(-1);
}

int main(int argc, char** argv)
{
int ret = -1;
struct stat bs;

memset(&bs,0,sizeof(bs));
ret = stat(argv[1],&bs);
if (ret < 0)
bail("Stat error.\n");

if (S_ISDIR(bs.st_mode))
printf(" %s \t","D");
else if (S_ISREG(bs.st_mode))
printf(" %s \t","-");
else if (S_ISLNK(bs.st_mode))
printf(" %s \t","l");
else
printf(" %s \t","u");
printf("%lld\t",bs.st_size);
printf("%o\t",bs.st_mode);
printf("%s\t",ctime(&bs.st_atime));

return 0;
}

一下为运行截图

image-20200318144324692

获取权限信息并复制到另一文件

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
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>

int bail(const char* str){
printf("Error(%d):",errno);
perror(str);
exit(-1);
}

int main(int argc, char** argv)
{
int ret = -1;
int dfd = -1;
struct stat bs;
memset(&bs , 0, sizeof(bs));
ret = stat(argv[1],&bs);
dfd = creat(argv[2],bs.st_mode);

return 0;
}

如下图所示

image-20200318144820783

------- 本文结束  感谢您的阅读 -------