二、linux应用编程之二文件I/O
Linux中一切皆文件,无论是应用编程还是驱动开发,文件IO编程都是必须的。文件I/O编程要掌握几个函数,分别是creat(),open(),write(),read(),lseek(),close(),ioctl(),fsync()。
creat();
1) 函数原型 : int creat(const char *pathname, mode_t mode);
2) 函数输入 : *pathname,文件全名(可带路径);
mode,用户读写模式,可以与chmod所用参数一样;
3) 返 回 值 : int,成功返回文件描述符fd,失败返回-1;
4) 示 例 : fd = create(“hello.txt”, 0x644);
open();
1) 函数原型 : int open(const char *pathname, int flags, ... /* mode_t mode */);
2) 函数输入 : *pathname,文件全名(可带路径);
flags,打开选项,包括读写方式,是否创建等等;
mode,用户读写模式,可以与chmod所用参数一样;
3) 返 回 值 : int,成功返回文件描述符,失败返回-1;
4) 示 例 : fd = open(“hello.txt”, O_RDWR|O_CREAT, 0X644);
注意:只有在flags参数中输出了O_CREAT,mode参数才有效,否则就算没有hello.txt也不会创建,0x644也就失去了作用。flags主要取值如下:
参数名 |
打开文件标志 |
描述 |
flags |
O_RDONLY |
以只读方式打开文件,与 O_WRONLY 和 O_RDWR 互斥 |
O_WRONLY |
以只写方式打开文件,与 O_RDONLY 和 O_RDWR 互斥 |
|
O_RDWR |
以可读写方式打开文件,与 O_WRONLY 和 O_RDONLY 互斥 |
|
O_CREAT |
如果要打开的文件不存在,则创建该文件 |
|
O_EXCL |
该标志与 O_CREAT 共同使用时,会去检查文件是否存在,若文件不存在则创建该文件,否则将导致打开文件失败。此外,打开文件链接时,使用该标志将导致失败 |
|
O_NOCTTY |
如果要打开的文件为终端设备,则不把该终端设备当成控制终端 |
|
O_TRUNC |
若文件存在且以可写方式打开,此标志会清除文件内容,并将其长度置为 0 |
|
O_APPEND |
读写文件都从文件的尾部开始,所写入的数据会以追加的方式插入到文件末尾 |
|
O_NONBLOCK |
以不可阻塞方式打开文件,也就是不管有无数据需要读写或者等待,都会立即返回 |
|
O_NDELAY |
以不可阻塞方式打开文件,也就是不管有无数据需要读写或者等待,都会立即返回(已过时,由 O_NONBLOCK 替代) |
|
O_SYNC |
以同步方式打开文件 |
|
O_NOFOLLOW |
如果文件名所指向的文件本身为符号链接,则会导致打开文件失败 |
|
O_DIRECTORY |
如果文件名所指向的文件本身并非目录,则会导致打开文件失败 |
write();
1) 函数原型 : ssize_t write(int fd, const void *buf, size_t count);
2) 输入参数 : fd,文件描述符;
*buf,要写入的数据缓冲区指针;
count,要写入数据的大小(字节);
3) 返 回 值 : ssize,实际成功写入多少个字节的数据,写入失败返回-1;
4) 示 例 : char write_buf [] = “hello linux”; res = write(fd, write_buf, sizeof(write_buf));
read();
1) 函数原型 : ssize_t read(int fd, void *buf, size_t count);
2) 输入参数 : fd,文件描述符;
*buf,存储读取数据的数据缓冲器指针;
count,要读取多少个字节的数据;
3) 返 回 值 : ssize,实际读取到数据的字节数,读取失败返回-1;
4) 示 例 : char read_buf[100] = {0}; res = read(fd, read_buf, data_size);
lseek();
1) 函数原型 : off_t lseek(int fd, off_t offset, int whence);
2) 输入参数 : fd,文件描述符;
offset,以whence为基准的偏移值;
whence,基准,取值为SEEK_SET、SEEK_CUR、SEEK_END;
3) 返 回 值 : 返回新的读写位置(相对于文件开头)。
4) 示 例 : new_offset = lseek(fd, offset, SEEK_END);
5) 说 明 : 这个函数只能在支持随机读取的文件中使用,使用了该函数后再进行 读写操作就会从新的读写位置开始读写。也可以用lseek(fd, 0, SEEK_END); 获取文件大小;
close();
1) 函数原型 : int close(int fd);
2) 输入参数 : fd,文件描述符;
3) 返 回 值 : int,成功关闭返回0,失败则返回-1;
4) 示 例 : close(fd);
ioctl();
1) 函数原型 : int ioctl(int fd, int cmd, …);
2) 输入参数 : fd,文件描述符;
cmd,操作命令,一般不同的文件cmd也不同;
3) 返 回 值 : int,操作成功返回0,失败返回-1;
4) 示 例 : cmd = 0; ioctl(fd, cmd);
5) 说 明 : ioctl是一个杂项函数,一些文件操作不适用write和read进行操作, 就用ioctl完成操作,例如打开开发板的某个IO设备文件,进行IO 控制的时候,write和read显得不是很合适。
fsync();
1) 函数原型 : int fsync(int fd);
2) 输入参数 : fd,文件描述符;
3) 返 回 值 : int,成功返回0,失败返回-1;
4) 示 例 : fsync(fd);
5) 说 明 : 运行完write()函数的时候,实际上数据是写到了系统缓存区,还没有 写到文件中,需要运行fsync()函数进行同步,将系统缓存区的数据写 入到文件中。
综合实例:
交叉编译后,通过NFS将可执行文件传送到开发板上运行,输出结果为: