系统编程(文件操作)---C语言学习(2)

小感慨
愉快的暑假留校学习开始啦,感慨一下,高考完了之后再次这样早起学习,一天过得格外快的日子好久没遇到了呢。。。
前述

暑假主要是学习LinuxC 还有系统的基本操作,今天主要看了文件操作,针对的都是一些系统调用函数。一天的学习快要结束了,趁着没忘赶紧总结一下吧。
首先说一下什么是系统调用,首先要纠正一个之前的错误观念,在做课设的时候有很多人都使用了system(“clear”)或者system(“cls”)
但是这并不是系统调用。
简单地说,system函数只是将传入的字符串交给shell去执行。而系统调用指的是操作系统提供给用户的一组接口,是用户程序和内核进行交互的一组接口,我自己对于底层,内核这些也不是很懂,希望在之后的学习中加深了解。
关系图

正文

1.文件权限控制
linux下一切皆文件,对于文件权限的控制自然是一大重点。可以通过chmod/fchmod函数对文件的访问权限进行修改,这这两者的区别在于chmod以文件名作为第一个参数,fchmod则是文件描述符,文件描述符我们后面再谈。
函数原型如下

int chmod(const char *path, mode_t mode);
int fchmod(int fildes, mode_t mode);
//成功返回0,否则返回-1

我认为首先一个重点是从这个函数我才分清 系统调用的函数和我们在shell下输入的命令并不相同,命令不等于系统调用函数
其次 mode_t 是unsigned int 类型的,不过按八进制进行解释,也就是说我们输入的777 要转换为八进制的511才能被函数正确的“理解”。

2.文件的创建,读写,关闭。
文件的创建可以通过open/creat函数来实现。函数原型如下

 int  open(const char *pathname, int flags);
 int  open(const char *pathname, int flags, mode_t mode);
 int  creat(const char *pathname, mode_t mode);
 //成功返回文件描述符 失败返回-1
为什么open有两种形式呢?我认为是变参函数,此处先略过

open函数的用法和fopen非常像,为什么呢?
pathname是含路径的文件名不多说,flags表示打开文件的方式,分别是只读,只写,和可读可写,3种打开方式是互斥的。但是可以与一些标志进行或运算从而实现很多其他的方式。当或上O_CREAT标志时,表示若文件不存在则创建,此时需要第三个参数来设置新文件的权限,这里同chmod的参数。通过这些标志,creat函数可以看成时open函数的一种使用方式。
文件的关闭通过close函数,函数原型如下

int  close(int fd);
//成功返回0,错误返回-1

close函数调用成功并不能保证全部数据写回磁盘。
3.文件读写
文件读写函数write/read,文件读写指针移动函数lseek。感觉还是lseek函数更有意思些。lseek允许文件指针的值设置到文件结束符之后,但这样做并不改变文件的大小(我感觉是由于linux的ext2/3/4文件系统将数据存放在data block,即使在文件结束符eof后面写入一些数据,如果当前的data block并未被写满所以显示的文件大小还是之前的data block 大小),如果使用write对eof之后的位置写入了数据,则在eof处和数据之间会存在一个间隔,用read读取的到的数据为0.

int main(void)
{
    int fd;
    char buf[4096];
    char buf2[] = "l";
    int i;
    for(i = 0; i < 4096; i++)
    buf[i] = 'a';
    if((fd = open("./test/test.c",O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) == -1)
    {
        perror("open");
        exit(1);
    }
    else{ 
    printf("success\n");
    write(fd, buf, 4096);
    //第一次将下面两行注释掉,将一个4096字符串写入文件,恰好占一个blcok
    //lseek(fd, 4096, SEEK_END); 
    //再次打开时将文件指针移动一个block大小,然后写入1字节
    //write(fd, buf2,1);
    close(fd);
    return 0;
    }
}

结果如下
第一次写入4096字节

第二次移动指针4096字节后写入一字节
由ls 可以看到 lseek移动的4096字节确实占了文件的空间,但并没有占用blcok,下图就可以看出
新建一个文件写入8193字节的内容占了3个block'
这种移动超出eof所形成的叫做文件空洞,这样的文件叫做稀疏文件。
这里写图片描述文件系统存储稀疏文件时,inode索引节点中,只给出实际占用磁盘空间的Block 号,
数据全零且不占用磁盘空间的文件Block并没有物理磁盘Block号。

小结

学习这些函数的时候不禁想起了之前学的fopen fwrite fread fseek fclose,这些我们之前用的是C标准库的函数,我认为它们是由系统调用封装成的(所以在用法上十分相似),具有良好的移植性,可以跨平台使用,但系统调用函数是由操作系统提供的,不同的操作系统自然不同。

额外的心得

书上的例子几乎每个函数都记录了错误代码,方便查询错误信息,感觉有点麻烦不知道以后写的时候用不用加上,不过可能调试的时候比较方便吧。还有系统调用函数有的函数名和宏名(好多宏)都看不出什么意思,感觉需要好好学习英语了。。。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值