这些函数在学习APUE(Unix环境高级编程)文件I/O时碰到,在这里做一个总结。
首先熟悉系统调用和库函数
系统调用是操作系统为用户态运行的进程与硬件设备(如CPU、
磁盘、 打印机等)进行交互提供的一组接口函数;
库函数: 顾名思义是把函数放到库里。 是把一些常用到的函数编完放到一个库文件里,供别人用, 别人用的时候把它所在的文件名用#include<>加到里面就可以了。 可分为两类, 一类是c语言标准规定的库函数, 一类是编译器特定的库函数。
想知道具体哪个函数如何使用,可以使用man命令
man
手册第一部分是命令
man 1 printf
man 手册第二部分是系统调用
man 2 write
man 手册第三部分是库函数
man 3 printf
open()函数
int open(const char *pathname, int flags,。。。);
The argument flags must include one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR. These
request opening the file read-only, write-only, or read/write,
打开的函数可以设置为,读O_RDONLY,写 O_WRONLY,读写O_RDWR。
。。。后面可以加些如权限等信息,不是必须的,但是*pathname, int flags是必须的。
path:
要打开的文件、 设备的路径名
oflag: 由多个选项进行“或”运算构造oflag参数
必选: O_RDONLY (只读)、
O_WRONLY(只写)、
O_RDWR(读写)
可选: O_APPEND
每次写时都追加到文件的尾端。
O_CREAT 文件不存在则创建它, 使用该选项需要第三个参数mode
O_NONBLOCK 如果path是一个FIFO、 块设备、 字符特殊文件则此选项为文件的本
次打开和后续的I/O操作设置非阻塞模式方式。
O_TRUNC 如果文件存在, 而且为只写或读写成功打开, 则将其长度截取为0;
O_EXEC、 O_SEARCH、
O_CLOEXEC、
O_NOCTTY....
mode: oflag带O_CREAT选项时, 必须带该参数用来指定打开文件的权限模式, 如066。
read()/write() 函数
ssize_t read(int fd, void *buf, size_t nbytes);
ssize_t write(int fd, const void *buf, size_t nbytes);
int fstat(int fd, struct stat *buf); //fd为文件描述符,对于内核而言, 所有打开的文件、 设备、 网络socket都是通过文件描述符引用,文件描述符是一个非负整数。
struct stat {
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小)
unsigned long st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //最后一次修改时间
time_t st_ctime; //最后一次改变时间(指属性)
};
int access(const char *path, int mode);
R_OK 测试读许可权
W_OK 测试写许可权
X_OK 测试执行许可权
F_OK 测试文件是否存在
下面用一个copy程序来熟悉上面的那些函数用法,该程序用来实现将“test.txt”文件中的内容拷贝到“test2.txt”中
1 /*********************************************************************************
2 * Copyright: (C) 2017 fanmaolin<fanmaolinn@gmail.com>
3 * All rights reserved.
4 *
5 * Filename: test-copy.c
6 * Description: This file
7 *
8 * Version: 1.0.0(04/22/2017)
9 * Author: fanmaolin <fanmaolinn@gmail.com>
10 * ChangeLog: 1, Release initial version on "04/22/2017 04:54:01 PM"
11 *
12 ********************************************************************************/
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17 #include <stdio.h>
18 #include <error.h>
19
20 #define BUF_SIZE 50
21 #define PATH_NAME "./test.txt"
22
23 int main(int argc, char **argv)
24 {
25 int fd;
26 int fd2;
27 char buf[BUF_SIZE];
28 int nbytes;
29 struct stat sbuf;
30 int filesize = 0;
31
32 if(access(PATH_NAME,F_OK))
33 {
34 printf("file %s not exit\n", "test.txt");
35 return -1;
36 }
37
38 fd = open(PATH_NAME, O_RDWR);
+ test-copy.c
39
40 if(fd < 0)
41 {
42 printf("open %s failure because:%s\n", PATH_NAME, strerror(error));
43 return -2;
44 }
45
46 fd2 = open("test2.txt" ,O_RDWR|O_CREAT|O_TRUNC, 0644);//创建文件test2.txt,如果文件存在就清零
47 if(fd2 < 0)
48 {
49 printf("open %s failure bacause:%s\n", "test2.txt", strerror(error));
50 return -2;
51 }
52
53 fstat(fd, &sbuf);
54 filesize = sbuf.st_size;
55
56 while(filesize > 0)
57 {
58 nbytes = read(fd, buf, sizeof(buf));
59 printf("read %d byte data\n", nbytes);
60 write(fd2, buf, nbytes);
61 filesize = filesize - nbytes;
62 }
63
64 close(fd);
65 close(fd2);
66
67 }
[fanmaolin@Centeros io]$ gcc test-copy.c
[fanmaolin@Centeros io]$ ./a.out
read 50 byte data
read 50 byte data
read 50 byte data
read 50 byte data
read 9 byte data
[fanmaolin@Centeros io]$ cat test2.txt
aaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaa
a
aaaaaaaaaaaaaaaaaaaaaaa
sssssssss
ssssssssssssss
sssssss
bbbbbbbbbbb
bbbbbbbbbbb
bbbbbbbb
bbbbbbbbbbb
qqq
问题总结:
Segmentation fault (core dumped)
可以编译通过,但是无法执行。
原因:
printf()打印类型弄错
58 printf("chucuo %s\n",strerror(error));
59 printf("read %d byte data\n", nbytes);
59行打印整数用%d 我用成了%s (打印字符串)
我在代码的每一行加一个打印信息,然后运行,就知道在哪里出现了错误
[fanmaolin@Centeros io]$ gcc test-copy.c
[fanmaolin@Centeros io]$ ./a.out
chucuo Unknown error 4195752
chucuo Unknown error 4195752
chucuo Unknown error 4195752
chucuo Unknown error 4195752
chucuo Unknown error 4195752
Segmentation fault (core dumped)