Unix C (四)

13 篇文章 0 订阅
11 篇文章 1 订阅
文件:
    1、在Linux系统中,几乎一切都是文件。目录(使用vi目录名验证),内存(查看/proc/进程号/maps文件验证),硬盘(查看/dev文件可验证)以及其他的各种硬件设备都可以看成文件。比如:文件/dev/tty可以看成键盘和显示器。
    2、在标准C中的文件操作:用FILE*代表fopen打开的一个文件;而在UC中用文件描述符(一个非负整数)代表打开一个文件。
    3、文件描述符自身不存储任何文件信息,信息都存在文件表(本身比较庞大)中。文件描述符对应文件表。就像用UID代表进程一样。
    4、在Linux来说,一个进程最多同时打开256个文件,描述符从3开始,0~2的描述符系统占用,他们分别表示标准输入,标准输出和标准错误。
    5、文件函数:open(),close(),read(),write(),ioctl()。
        open()    打开一个文件,返回一个文件描述符
        read()    读一个文件
        write()    写一个文件
        close()    关闭一个文件
        ioctl()    控制文件的读写
    6、函数原型int open(const char *pathname, int flags);和int open(const char *pathname, int flags, mode_t mode);创建成功返回文件描述符,失败返回-1。
            第一个参数:文件路径包括文件名
            第二个参数:文件描述符权限标记
                flags取值:
                    O_RDONLY        只读方式打开         \
                    O_WRONLY        只写方式打开             --> 三种权限必选其一
                    O_RDWR        以可读可写方式打开    /
                    O_APPEND        从文件尾以追加方式打开。
                    创建标识:
                        O_CREAT        如果文件存在则打开,文件不存在就创建。
                        O_EXCL        如果文件文件不存在,创建文件;如果文件存在,返回-1,代表出错。
                        O_TRUNC        清空文件内容后打开
                多个描述符一起使用要用按位或"|"连接。
            第三个参数:只有在创建文件时指定文件权限。该权限是指文件在硬盘上的操作权限(某些权限由于系统出于安全考虑会屏蔽某些权限)。
    7、函数原型:ssize_t read(int fd, void *buf, size_t count);也可以为int read(int fd, void* buf, size_t size);
        参数:
            fd文件描述符,就是open的返回值
            buf是读文件的首地址,任意类型都可
            size是buf的大小(有可能读不满)
        返回值:正数        真实读到文件的字节数
              0        什么都没读取
              -1        出现错误
    8、函数原型:ssize_t write(int fd, const void *buf, size_t count);也可以为int write(int fd, void* buf, size_t lenght)
        参数:
            参数:
            fd文件描述符,就是open的返回值
            buf是写文件的首地址,任意类型都可
            lenght是真实想要写入的字节数
        返回值:正数        真实写入文件的字节数
              0        什么都没写

              -1        出现错误

实例:

(1)文件写入比较:

C语言版:

#include <stdio.h>
#include <stdlib.h>

int main(){
    FILE * p_file = fopen("a.txt","wb");
    if(!p_file){
        perror("fopen"),exit(-1);
    }

    int i = 0;
    for(i = 0; i < 100000; i++){
        fwrite(&i,sizeof(int),1,p_file);
    }

    close(p_file);

    return 0;
}

UC普通版:

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

int main(){
    int fd = open("b.txt",O_WRONLY | O_CREAT | O_TRUNC,0664);
    if(fd == -1){
        perror("open"),exit(-1);
    }

    int i = 0;
    for(i = 0; i < 100000; i++){
        write(fd,&i,4);
    }

    close(fd);

    return 0;
}

UC优化版:

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

int main(){
    char buf[100000] = {};   //自定义缓冲区
    
    int fd = open("c.txt",O_WRONLY | O_CREAT | O_TRUNC,0664);
    if(fd == -1){
        perror("open"),exit(-1);
    }

    int i = 0;
    for(i = 0; i < 100000; i++){
        buf[i%100000] = i;
        if(i%100000 == 99999){
            write(fd,buf,sizeof(buf));  //将缓冲区的内容写入到文件
        }
    }

    close(fd);

    return 0;
}

执行时间对比:

原因:所有的标C函数都在用户层定义了输入/输出缓冲区,作用就是累计到了一定数量以后再进入内核读/写一次。
            所有的UC函数都没有定义缓冲区,但是可以由程序员自定义缓冲区提升效率,更加灵活。


(2)文件拷贝:

/*
   文件拷贝练习
 */

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

int main(void){
    //打开第一个文件,用于读取里面的内容
    int fdr  = open("1.png",O_RDONLY);
    if(-1 == fdr){     //检测文件打开是否失败
        perror("open1"),exit(-1);
    }

    //打开第二个文件,用于存储复制第一个文件的内容
    int fdw = open("2.png",O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if(-1 == fdw){    //检测文件打开是否失败
        perror("open2"),exit(-1);
    }

    char buf[4096] = {};

    while(1){
        //读取文件内容
        int res = read(fdr,buf,sizeof(buf));        //读取第一个文件的内容
        if(-1 == res){       //判断是否读取有误
            perror("read");
            break;
        }
        if(!res){            //判断是否读到了文件末尾
            break;
        }
        //写入文件中
        write(fdw,buf,res);  //将第一个文件的内容写到第二个文件中
    }
    
    //关闭文件
    close(fdr);
    close(fdw);

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值