Linux学习笔记(一)----文件

一、文件的一些基础知识:

        Linux里面一切都是文件,那从哪里看出是什么文件并具有哪些属性呢?

Linux学习笔记(一)----文件_第1张图片

 

通过指令:ls -l的结果的第一位标识位看出来:

(1)-表示普通文件;

(2)d表示文件夹;

(3)c表示字符设备文件;

(4)b表示块设备文件;

(5)s表示套接字socket文件;

  (6)  l表示符号链接,即软链接  通过名字指向另外一个文件

(7)p表示该文件为命令管道文件。与shell编程有关的文件。

关于软连接的相关概念:

链接文件的概念类似于windows里的快捷方式。多个链接文件同时指向一个“源文件”。链接文件分为硬链接或符号链接两种。

在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号inode 。软连接,其实就是新建立一个文件,这个文件就是专门用来指向别的文件的(那就和windows 下的快捷方式的那个文件有很接近的意味)。软连接产生的是一个新的文件,但这个文件的作用就是专门指向某个文件的,删了这个软连接文件,那就等于不需要这个连接,和原来的存在的实体原文件没有任何关系,但删除原来的文件,则相应的软连接不可用(cat那个软链接文件,则提示“没有该文件或目录“)

软链接可以跨文件系统,硬链接不可以;软链接可以对一个不存在的文件名(filename)进行链接(当然此时如果你vi这个软链接文件,linux会自动新建一个文件名为filename的文件),硬链接不可以(其文件必须存在,inode必须存在);软链接可以对目录进行连接,硬链接不可以。两种链接都可以通过命令 ln 来创建。ln 默认创建的是硬链接。使用 -s 开关可以创建软链接

第一位标识位后面9个字母表示该文件或目录的权限位。

r表是读 (Read) 、w表示写 (Write) 、x表示执行 (eXecute)

其中前三个表示文件拥有者的权限,中间三个表示文件所属组拥有的权限,最后三个表示其他用户拥有的权限。

比如:

-rw-r--r-- 1 root root 762 07-29 18:19 exit

表示文件的拥有者root对文件有读写权限,其他人(同组用户和其他用户只有读的权限)  

其中:rwx也可以用数字来代替 
  r ------------4 
  w -----------2 
  x ------------1 
  - ------------0 

可以通过chmod指令来为文件增加权限

        -rw------- (600) 只有所有者才有读和写的权限 
  -rw-r--r-- (644) 只有所有者才有读和写的权限,组群和其他人只有读的权限 
  -rwx------ (700) 只有所有者才有读,写,执行的权限 
  -rwxr-xr-x (755) 只有所有者才有读,写,执行的权限,组群和其他人只有读和执行的权限 
  -rwx--x--x (711) 只有所有者才有读,写,执行的权限,组群和其他人只有执行的权限 
  -rw-rw-rw- (666) 每个人都有读写的权限 
  -rwxrwxrwx (777) 每个人都有读写和执行的权限

如: chmod 777 filename        表示为文件添加每个人都有读写和执行的权限。

第二字段表示文件硬链接数

        

-rw-r--r-- 1 root root 762 07-29 18:19 exit

如果一个文件不是目录,此时这一字段表示这个文件所具有的硬链接数,

第二字段的值为1,说明这个文件只有exit这一个文件名。即只有一个指向该链接的硬链接。。

如果使用ln,做一个指向该文件的硬链接再查看该文件,该文件的第二字段就会变成二。

第三点字段:文件(目录)拥有者3字段:文件(目录)拥有者

lrwxrwxrwx 1 root root 4 08-03 08:27 bexit -> exit

该字段表示此文件是属于哪个用户。linux类系统都是多用户系统,每个文件都有它的拥有者。只有文件的拥有者才具有改动文件属性的权利。当然, root用户具有改动任何文件属性的权利。对于一个目录来说,只有拥有该目录的用户,或者具有写权限的用户才有在目录下创建文件的权利

如果某一个用户因为某种原因,被删除,而该用户的文件还存在,那么用ls -l 查看该文件将显示一个代表用户存在前ID号的数字。

第4字段:文件(目录)拥有者所在的组

一个用户可以加入很多个组,但是其中有一个是主组,就是显示在第4字段的名称。

可以在useradd的时候用-g指定该用户所在的主组,用-G指定其他组

后面字段就不介绍了,就记一点如果是一个符号链接,那么会有一个 “->" 箭头符号,后面根一个它指向的文件名,如

lrwxrwxrwx 1 root root 4 08-03 08:27 bexit -> exit

 二、文件的打开/创建。

        API:  

#include 
int open(const char *pathname, int flag,...);

当使用系统调用open打开一个文件时,操作系统会创建一些数据结构来表示这个被打开的文件。为了能够找到这些数据结构,在进程中,代码会为这个打开的文件分配一个文件描述符fd(File Descriptor)。文件描述符就是用来区分一个进程打开的多个文件的。它的作用域就是当前进程,出了当前进程这个文件描述符就没有意义了。

补充说明:

文件平时是存放在块设备中的文件系统文件中的,我们把这种文件叫做静态文件,当我们取open打开一个文件时,linux内核做的操作包括:内核在进程中建立一个打开的数据结构,记录下我们打开的这个文件;内核在内存张申请一段内存,并将静态文件的内容从块设备读到内核中特定的地址管理存放(叫动态文件)。

        打开文件以后,对这个文件的读写操作,都是针对内存中的这一份动态文件的,而并不是对静态文件的。当然我们对动态文件进行读写以后,此时内存中动态文件和块设备文件中的静态文件就不同步了,当我们close关闭动态文件时,close内部将内存中的动态文件的内容取更新块设备中的静态文件。所以最后读写完成后,一定要关闭文件,否则会造成文件损坏。

文件描述符fd
文件描述符在形式上 是一个非负整数。它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕文件描述符展开。

习惯上,标准输入(standard input)的文件描述符是 0,标准输出(standard output)是 1,标准错误(standard error)是 2。
0,1,2对应的物理设备一一般是:键盘,显示器,显示器。
所以通常当我们成功打开文件时,返回的fd都是从3起。

若打开失败,文件描述符fd等于-1;


pathname:打开文件的路径可以是绝对路径,也可以是相对路径。

flag:

        O_RDONLY 只读打开        O_WRONLY 只写打开        O_RDWR 可读可写打开

这三个只能选择一个

下列常数是可选择的:     
        O_CREAT 若文件不存在则创建它。使用此选项时,需要同时说明第三个参数mode,用其说明该新文件的存取许可权限。
        O_EXCL 如果同时指定了OCREAT,而文件已经存在,则出错。 (可用来判断文件是否存在)
        O_APPEND 每次写时都加到文件的尾端。
        O_TRUNC 属性去打开文件时,如果这个文件中本来是有内容的,而且为只读或只写成功打开,则将其长度截短为0。(即将原文件的内容清除)

如:

fd = open("./filename", O_RDWR|O_CREAT, 0777);

表示打开当前文件下的filename,以可读可写的方式打开,如果没有filename这个文件就创建,文件权限为777(可参考上面基础知识部分)。0777的0表示可参考

http://chen498402552-163-com.iteye.com/blog/1164407

三、文件的写入。

       API:

#include 
ssize_t write(fd, const void *buf, size_t count);

        write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。

        返回值:如果顺利write()会返回实际写入的字节数(len)。当有错误发生时则返回-1,错误代码存入errno中。

附加说明:

write()函数返回值一般无0,只有当如下情况发生时才会返回0:write(fp, p1+len, (strlen(p1)-len))中第三参数为0,此时write()什么也不做,只返回0。

write()函数从buf写数据到fd中时,若buf中数据无法一次性读完,那么第二次读buf中数据时,其读位置指针(也就是第二个参数buf)不会自动移动,需要程序员来控制,而不是简单的将buf首地址填入第二参数即可。如可按如下格式实现读位置移动:write(fp, p1+len, (strlen(p1)-len))。 这样write第二次循环时便会从p1+len处写数据到fp, 之后的也一样。由此类推,直至(strlen(p1)-len)变为0。
附加说明:原文链接:https://blog.csdn.net/hhhlizhao/article/details/71552588

四、文件的读取。

        API:

ssize_t read(int fd, void * buf, size_t count);

 read()会把参数fd所指的文件传送count 个字节到buf 指针所指的内存中。

返回值:返回值为实际读取到的字节数, 如果返回0, 表示已到达文件尾或是无可读取的数据。

读取失败则返回-1。

附加说明:读常规文件时,在读到count个字节之前已到达文件末尾。例如,距文件末尾还有50个字节而请求读100个字节,则read返回50,下次read将返回0。(这是因为光标的原因)

五、文件光标的相关操作

        API:

#include 
#include 
off_t lseek(int fd, off_t offset, int whence);

 返回值:新的偏移量(成功),-1(失败)

 offset:光标的偏移值,相对于第三个参数。offset为正则向文件末尾移动(向前移),为负数则向文件头部(向后移)。

whence:有三个选项

SEEK_SET
  从文件头部开始偏移offset个字节。 
SEEK_CUR: 
  从文件当前读写的指针位置开始,增加offset个字节的偏移量。 
SEEK_END 
  文件偏移量设置为文件的大小加上偏移量字节。(即从文件内容的末尾开始偏移)

可以利用lseek函数的返回值来计算文件的大小:

int main()
{

    int fd;
    int filesize;

    fd = open("./filename", O_RDWR);

    if(fd == -1){
        printf("open failed!\n");
        perror("");
    }


    filesize = lseek(fd, 0 , SEEK_END);

    printf("filename's size: %d", filesize);

    close(fd);
    
    return 0;
}

六、文件的关闭

        close(fd); 就不记录了

你可能感兴趣的:(linux,vim)