Linux系统编程_2_文件I/O(系统调用&库函数)

这里说的的文件I/O指的是不带缓存的;

1.关于带缓存的IO操作和不带缓存的IO操作,参见另一篇文章:

带缓存IO和不带缓存IO详解


Linux中的文件IO(不带缓存的IO)通常用的有以下几个:

open    read    write    lseek   close


2.open的参数

int open(filename, mode);

mode 通常可以是O_RDONLY(只读)  O_WRONLY(只写)  O_RDWR(读写)必须指定且只能指定一个!

其他的可供选择,可通过或运算添加:O_APPEND  O_CREAT  O_EXCL   O_TRUNC


3.read与write在读取网络数据时,可能由于网络的缓冲机制等造成实际读到的数据小于应读数据。

所以,应该做相应的数据完整性判断操作;


4.内核其实也是一个软件,内核的接口叫做系统调用(system call),系统调用是内核提供给应用层使用的,除了应用程序可以调用系统调用外(如shell),库函数也可以调用系统调用。

一个Linux操作系统的体系结构图


下面是一些简单的系统调用实例:

A. 使用read,write实现简单的复制功能

#include <stdio.h>
#include <unistd.h>

#define SIZE 1024

int main()
{
    int fd;
    int n;
    char buf[SIZE];

    while( (n = read(STDIN_FILENO, buf, SIZE)) > 0 )
    {
        if( write(STDOUT_FILENO, buf, n) != n )
        {
            perror("Write error!");
            return -1;
        }
    }
    if(n < 0)
    {
        perror("Read error!");
        return -1;
    }

    return 0;
}

Linux系统中每当运行一个程序时,所有的shell都为其打开3个文件描述符,标准输入STDIN_FILENO、标准输出STDOUT_FILENO、标准错误STDERR_FILENO;

上面的程序,直接运行时,./a.out,在标准输入中输入什么,程序就会显示什么;

运行./a.out < a.c > b.c,则程序会把a.c中的内容拷到b.c中去,为什么?

因为现在的标准输入已经重定向了,变成了a.c文件而不是标准输入in;


B. 用lseek实现获取文件大小的功能:

1 #include <stdio.h>
2 #include <unistd.h>
3 #include <fcntl.h>
4 #include <stdlib.h>
5
6 int main(int argc, char ** argv)
7 {
8     off_t size;
9     int nFd;
10
11     if(argc < 2)
12     {
13         printf("Usage: ./size xxx\n");
14         exit(-1);
15     }
16
17     nFd = open(argv[1], O_RDONLY);
 18     if(-1 == nFd)
19     {
20         perror("Open file error");
21         exit(-1);
22     }
23     size = lseek(nFd, 0, SEEK_END);
24     printf("The file size is : %d\n", size);
25
26     return 0;
27 }

5.dup与dup2函数,都用来复制一个现存的文件描述符

    int dup(int fd);

    int dup2(int fd1,int fd2);//若 fd2已经打开,则先关闭


6.sync  fsync  fdatasync函数都可以用来将缓冲区中的数据刷新到物理磁盘

    void sync(void);

    int fsync(int filedes);

    sync函数并不等待实际的写磁盘操作结束后返回。通常称为update的守护进程会周期性的调用sync函数,保证了定期冲洗内核的块缓冲区;

    fsync指定了文件描述符,操作单一的文件,函数等待写磁盘操作结束后返回,可以用于数据库这样的应用程序。


7.fcntl函数——可以改变已经打开的某个文件的性质

#include <fcntl.h>

int fcntl(int fd, int cmd, int arg);

fcntl函数有五种功能:

1.复制一个现有的文件描述符 ( cmd=F_DUPFD )

2.获取/设置文件描述符 ( cmd=F_GETFD / cmd=F_SETFD )

3.获取/设置文件状态 ( cmd=F_GETFL / cmd =F_SETFL )

4.获取/设置异步IO所有权 ( cmd=F_GETOWN / cmd=F_SETOWN) 

5.获取/设置文件记录锁 ( cmd=F_GETLK / cmd=F_SETLK/F_SETLKW )

具体的使用方法后面会做记录。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值