Linux中设备与文件IO-学习笔记(二)

1、设备或文件操作两种方式:
   1)用户编程接口 API
   2)系统调用
2、文件描述符fd
1)每个进程PCB结构中有文件描述符指针,指向files_struct的文件描述符表,记录每个进程打开的文件列表
2)系统内核不允许应用程序访问进程的文件描述符表,只返回这些结构的索引即文件描述符ID(File Description)给应用程序
3)Linux系统中,应用程序通过这些文件描述符来实现让内核对文件的访问
3、特殊文件描述符号
   标准输入STDIN_FILENO
   标准输出STDOUT_FILENO
   标准错误STDERR_FILENO
   每个进程被加载后,默认打开0,1,2这三个文件描述符
4、open、close、read、write、lseek函数用法实例
//程序1
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
    int fd;//定义文件描述符
    char buf[1024] = "hello world!";
    char buf1[1024];
    int len;
    if (argc < 2)
    {
        printf("filname\n");
        exit(1);
    }
    //创建或打开一个文件
    fd=open(argv[1],O_CREAT | O_RDWR,0644);
    //写数据到文件
    write(fd,buf,strlen(buf));
    //写完数据后应关闭文件再打开读取,否则可能无法读取到数据。
    close(fd);
    fd=open(argv[1],O_RDWR);
    //阻塞读
    printf("fd=%d\n",fd);//输出文件描述符
    printf("lensizeof(buf1)=%d\n",sizeof(buf1));//计算字符数组大小
    memset(buf1,0,sizeof(buf1));//清空缓存区
    len=read(fd,buf1,sizeof(buf1));//从fd复制到缓冲区中的字节数
    printf("len=%d\n",len);
    //将数据显示在终端
    write(STDOUT_FILENO,buf1,len);
    printf("\nfd=%d\n",fd);
    close(fd);
    return 0;
}
//程序2
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void)
{
    //以可读可写方式打开程序1创建的文件
    int fd=open("first.h",O_RDWR);
    if(fd<0)
    {
        perror("open first.h");
        exit(1);
    }         //0x1000=4096k
    lseek(fd,0x1000,SEEK_SET);//文件重定位,偏移文件开头0x1000
    write(fd,"a",1);//并写入数据a
    close(fd);//关闭文件
}
程序1和程序2配套使用,终端命令具体执行如下图示:

无

 

对打开文件,关闭文件,读取文件,设置文件锁,解文件锁的封装函数设计
//程序3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

struct flock lock;//定义结构体类型变量

//打开一个文件,参数(文件名称,打开方式)
int File_open(char *pcName, int flag)
{
    int fd;//定义文件描述符
    //创建或打开一个文件
    fd = open(pcName, flag);
    if (fd == -1)//打开失败
    {
        perror("open file\n");
        exit(-1);
    }
    else//打开成功
    {
        printf("success to open file\n");
    }
    return fd;//返回文件描述符
}
//关闭一个文件,参数(文件描述符)
int File_close(int fd)
{
    int filefd;//定义文件描述符
    //关闭文件
    filefd = close(fd);
    if (filefd == -1)//关闭失败
    {
        perror("close file\n");
        exit(-1);
    }
    else//关闭成功
    {
        printf("success to close file\n");
    }
    return filefd;//返回文件描述符
}
//从文件读取数据(文件描述符,缓冲区,缓冲区大小)
int File_read(int fd,char *buf,int bufferlen)
{
    int len;//从文件中读取的字节数
    int file_fd=fd;//文件描述符
    printf("bufferlen=%d\n",bufferlen);
    //读取数据后返回读取到的字节数
    len=read(file_fd,buf,bufferlen);
    if(len==-1)
    {
        perror("read file\n");
    }
    else
    {
        printf("已读取的字节数len=%d\n",len);
        //终端显示读取到的数据
        write(STDOUT_FILENO,buf,len);
        printf("\n");
    }
    return len;//返回读取到的字节数
}
//设置文件锁(文件描述符)
int File_lock(int fd)
{
    int state;//文件锁状态返回值
    //获得锁信息
    state=fcntl(fd,F_GETLK,&lock);
    if(state<0)
    {
        perror("get file lock state\n");
        return -1;
    }
    else//获得锁调用成功
    {
        printf("设置之前文件锁类型:%d\n",lock.l_type);
        if (lock.l_type != F_UNLCK)//文件锁已设置
        {
            printf("文件锁不能被设置! \n");
            return -1;
        }
        if(lock.l_type == F_UNLCK)//文件锁为空
        {
            printf("文件锁可以设置! \n");
            lock.l_type = F_WRLCK;//设置排他锁
            //设置文件锁
            state=fcntl(fd,F_SETLK,&lock);
            if (state == -1)
            {
                printf("设置失败!\n");
                return -1;
            }
            else//设置排他锁成功
            {
                printf("设置之后文件锁类型:%d\n",lock.l_type);
                printf("设置成功!\n");
                return 0;
            }
        }
    }
}
//解文件锁(文件描述符)
int File_unlock(int fd)
{
    int state;//文件锁状态返回值
    printf("获取状态之前设置之前文件锁类型:%d\n",lock.l_type);
    //获得锁信息
    state=fcntl(fd,F_GETLK,&lock);
    if(state==-1)
    {
        perror("get file lock state\n");
        return -1;
    }
    else//获得锁调用成功
    {
        printf("设置之前文件锁类型:%d\n",lock.l_type);
        if (lock.l_type != F_UNLCK)//文件锁为解锁状态
        {
            printf("文件锁不能被解锁\n");
            return -1;
        }
        else//文件锁已设置
        {
            printf("文件锁可以设置\n");
            lock.l_type = F_UNLCK;//定义锁类型为解锁
            //解锁
            state=fcntl(fd,F_SETLK,&lock);
            if (state == -1)
            {
                printf("设置失败!\n");
                return -1;
            }
            else//解锁调用成功
            {
                printf("设置之后文件锁类型:%d\n",lock.l_type);
                printf("设置成功!\n");
                return 0;
            }
        }
    }
}
//主函数
int main(void)
{
    int file_fd;//定义文件描述符
    int i;//关闭文件标志位
    int j=0;//文件中读取的字节数
    int k=2;//文件锁状态返回值
    char buf[50];//读取数据缓存数组
    int buf_len;//缓存数组大小

    memset(&lock, 0, sizeof(struct flock));//结构体清零
    //l_whence有SEEK_SET、SEEK_CUR和SEEK_END。
    lock.l_whence = 0;//偏移量的起始位置:文件开始处
    lock.l_start = SEEK_SET;//l_whence的偏移量:从文件开始处计算偏移
    lock.l_len = 0;//表示从起点开始直至最大可能位置为止。

    //打开文件
    file_fd = File_open("hello.c", O_CREAT | O_RDWR);
    if (file_fd == -1)//打开失败
    {
        perror("open file\n");
    }
    else//打开成功,输出文件描述符
    {
        printf("文件打开成功fd=%d\n", file_fd);
        printf("\n");
    }

    //读文件
    memset(buf,0,sizeof(buf));//清空字符数组数据
    buf_len=sizeof(buf);//计算字符数组大小
    j=File_read(file_fd,buf,buf_len);
    if(j==-1)
    {
        printf("读取文件失败!\n");
    }
    else
    {
        printf("读取文件成功!\n");
        printf("从文件中读取的字节数=%d\n",j);
        printf("\n");
    }

    //设置文件锁
    k=File_lock(file_fd);
    if(k==-1)
    {
        printf("设置文件锁失败!\n");
    }
    else
    {
        printf("文件锁状态返回值k=%d\n",k);
        printf("文件锁设置成功!\n");
        printf("\n");
    }

    //解文件锁
    k=File_unlock(file_fd);
    if(k==-1)
    {
        printf("解锁失败!\n");
        printf("\n");
    }
    else
    {
        printf("文件锁状态返回值k=%d\n",k);
        printf("解锁成功!\n");
        printf("\n");
    }

    //关闭文件
    i = File_close(file_fd);
    if (i == -1)//关闭失败
    {
        printf("关闭文件失败!\n");
    }
    else//关闭成功
    {
        printf("关闭文件 %d 成功\n", i);
        printf("\n");
    }
    return 0;
}
注:
当文件加锁后,状态位由1--变为0,其他程序需要检测到该文件状态位为0时,无法访问该文件,直到状态位为1时。
文件解锁,状态位由0++变为1。
程序执行效果:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值