Linux 文件 系统编程(一)

打开 /创建文件

man 2 open

open的系统调用

系统调用open的作用是打开一个文件,并返回这个文件的描述符。

简单地说,open建立了一条到文件或设备的访问路径。如果操作成功,它将返回一个文件描述符,read和write等系统调用使用该文件描述符对文件或

设备进行操作。这个文件描述符是唯一的,他不会和任何其他运行中的进程共享。如果两个程序同时打开一个文件,会得到两个不同的问价描述符。如果

同时对两个文件进行操作,他们各自操作,互补影响,彼此相互覆盖(后写入的覆盖先写入的)为了防止文件按读写冲突,可以使用文件锁的功能。

Linux中open的函数原型有两个:

int open(const char *path, int oflags);

int open(const char *path, int flags, mode_t mode );

参数说明。

path:准备打开的文件或设备名字。

flags:指出要打开文件的访问模式。

open调用必须指定如下所示的文件访问模式之一:

open调用哈可以在flags参数中包括下列可选模式的组合(用”按位或“操作):

  • O_APPEND: 每次把写入数据追加在文件的末尾。
  • O_TRUNC: 属性去打开文件时,如果这个文件中本来是有内容的,而且为只读或只写成功打开,则将其长度截断为0.
  • O_CREAT: 如果需要,就按参数mode中给出的访问模式创建文件。
  • O_EXCL: 与O_CREAT一起调用,确保调用者创建出文件。使用这个模式可防止两个程序同时创建一个文件,如果文件已经存在,open调用将失败。

 关于其他可能出现的flags值,请看考open的调用手册。

mode:当使用O_CREAT标志的open来创建文件时,我们必须使用三个参数格式的open调用。第三个参数mode 是几个标志按位OR后得到的。他们是:

  • S_IRUSR: 读权限,文件属主。
  • S_IWUSR:写权限,文件属主。
  • S_ IXUSR:执行权限,文件属主。
  • S_IRGRP:读权限,文件所属组。
  • S_IWGRP:写权限,文件所属组。
opentest2.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main()
{
        int fd;

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

        if(fd == -1)
        {
                printf("open file1 failed\n");

                fd = open("./file1",O_RDWR|O_CREAT,0600);
                if(fd > 0)
                {
                        printf("create file1 success\n");
                }
        }

        printf("fd = %d\n",fd);
        return 0;

}

     
 

-rw-r--r--  1.可读   r    4        int open(const char *path, int flags, mode_t mode );

            2.可写  w   2          fd = open("./file1",O_RDWR|O_CREAT,0600);

            3.执行  x    1         0600   6指4+2 可读可写    而后面的 0 0 分别为 同组 和其他组         
opennew7.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main()
{
        int fd;



        fd = open("./file1",O_RDWR|O_CREAT|O_EXCL,0600);
        if(fd == -1){

                printf("file exit\n");

                }

        return 0;

}

主要是针对 添加 O_EXCL 的使用,O_EXCL: 与O_CREAT一起调用,确保调用者创建出文件。使用这个模式可防止两个程序同时创建一个文件,如果文件已经存在,open调用将失败。

O_APPENDtest8.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>


int main()
{
        int fd;

        char *buf = "ganboss is very handsome!";

        fd = open("./file1",O_RDWR|O_APPEND);


        printf("open success : fd = %d\n",fd);


//       ssize_t write(int fd, const void *buf, size_t count);
        int n_write = write(fd,buf,strlen(buf));
        if(n_write != -1){
                printf("write %d byte to file\n",n_write);
        }

//      int close(int fd);
        close(fd);



        return 0;

}

 O_APPEND: 每次把写入数据追加在文件的末尾。   意思就是在原有的内容file1 (132123132123123132) 增加内容你要的内容(ganboss is very handsome)

O_TRUNCtest9.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>


int main()
{
        int fd;

        char *buf = "test!";

        fd = open("./file1",O_RDWR|O_TRUNC);


        printf("open success : fd = %d\n",fd);


//       ssize_t write(int fd, const void *buf, size_t count);
        int n_write = write(fd,buf,strlen(buf));
        if(n_write != -1){
                printf("write %d byte to file\n",n_write);
        }

//      int close(int fd);
        close(fd);



        return 0;

}

 O_TRUNC: 属性去打开文件时,如果这个文件中本来是有内容的,而且为只读或只写成功打开,则将其长度截断为0.    全部内容清理掉  变成 test!

文件写入操作 

man 2 write

   

write的系统调用

write,就是把缓冲区的数据写入文件中。注意,这里的文件时广泛意义的文件,比如写入磁盘、写入打印机等等。

Linux 中write()的函数原型:

size_t write(int fildes, const void *buf, size_t nbytes);

参数说明:

fildes:文件描述符,标识了要写入的目标文件。例如:fildes的值为1,就像标准输出写数据,也就是在显示屏上显示数据;如果为 2 ,则想标注错误写数据。

*buf:待写入的文件,是一个字符串指针。

nbytes:要写入的字符数。

函数返回值:size_t  返回成功写入文件的字符数。需要指出的是,write可能会报告说他写入的字节比你所要求的少。这并不一定是个错误。在程序中,你需要检查error已发现错误,然后再次调用write写入剩余的数据。
writetest3.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>


int main()
{
        int fd;

        char *buf = "ganboss is very handsome!";

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

        if(fd == -1)
        {
                printf("open file1 failed\n");

                fd = open("./file1",O_RDWR|O_CREAT,0600);
                if(fd > 0)
                {
                        printf("create file1 success\n");
                }
        }

        printf("open success : fd = %d\n",fd);

//       ssize_t write(int fd, const void *buf, size_t count);
        write(fd,buf,strlen(buf));

//      int close(int fd);
        close(fd);



        return 0;

}
//       ssize_t write(int fd, const void *buf, size_t count);

char *buf = "ganboss is very handsome!";

用到了strlen去计算write要写入字符串的多少
所以要加头文件#include <string.h>

close系统调用

close系统调用用于“关闭”一个文件,close调用终止一个文件描述符fildes以其文件之间的关联。文件描述符被释放,并能够重新使用。

close成功返回1,出错返回-1.

#Include<unistd.h>

int close(int fildes);

read的系统调用

系统调用read是从文件中读出数据。要读取的文件用文件描述符标识,数据读入一个事先定义好的缓冲区。他返回实际读入的字节数。

Linux中read的函数原型:

size_t read(int fildes, void *buf, size_t nbytes);

参数说明:

fildes:文件描述符,标识要读取的文件。如果为0,则从标准输入读数据。类似于scanf()的功能。

*buf:缓冲区,用来存储读入的数据。

nbytes:要读取的字符数。

返回值:size_t返回成功读取的字符数,它可能会小于请求的字节数。

readtest4.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>


int main()
{
        int fd;

        char *buf = "ganboss is very handsome!";

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

        if(fd == -1)
        {
                printf("open file1 failed\n");

                fd = open("./file1",O_RDWR|O_CREAT,0600);
                if(fd > 0)
                {
                        printf("create file1 success\n");
                }
        }

        printf("open success : fd = %d\n",fd);


//       ssize_t write(int fd, const void *buf, size_t count);
        int n_write = write(fd,buf,strlen(buf));
        if(n_write != -1){
                printf("write %d byte to file\n",n_write);
        }

        close(fd);

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

        char *readBuf;
        readBuf = (char *)malloc(sizeof(char)*n_write + 1);//强制转换指针 malloc 
//      ssize_t read(int fd, void *buf, size_t count);
        int n_read = read(fd,readBuf,n_write);

        printf("read : %d,contex : %s\n",n_read,readBuf);

//      int close(int fd);
        close(fd);



        return 0;

运行结果为:

重新打开的方法: 这个是打开open 文件夹 再写入write 字符串 然后关闭close文件夹 再打开open 让光标跑到前面去读取read前面的内容  若不这样可能光标在字符串后面 什么也读不到 可以通过对光标的闪烁位置进行改动

文件光标的移动操作

解决上面方法是:去重新定位光标 

将文件读写指针相对whence移动offset个字节  (offset对whence的偏移值)

 
 

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

 所需要头文件:
   #include <sys/types.h>
   #include <unistd.h>
参数:
fd 表示要操作的文件描述符

offset是相对于whence(基准)的偏移量

whence 可以是SEEK_SET(文件指针开始),SEEK_CUR(文件指针当前位置) ,SEEK_END为文件指针尾

返回值:文件读写指针距文件开头的字节大小,出错,返回-1

lseek 主要作用是移动文件读写指针,因此还有以下两个作用
1.拓展文件,不过一定要一次写的操作。迅雷等下载工具在下载文件时候先扩展一个空间,然后再下载的。

2.获取文件大小
lseektest5.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>


int main()
{
        int fd;

        char *buf = "ganboss is very handsome!";

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

        if(fd == -1)
        {
                printf("open file1 failed\n");

                fd = open("./file1",O_RDWR|O_CREAT,0600);
                if(fd > 0)
                {
                        printf("create file1 success\n");
                }
        }

        printf("open success : fd = %d\n",fd);
//       ssize_t write(int fd, const void *buf, size_t count);
        int n_write = write(fd,buf,strlen(buf));
        if(n_write != -1){
                printf("write %d byte to file\n",n_write);
        }

//      close(fd);
//      fd = open("./file1",O_RDWR);
//      off_t lseek(int fd, off_t offset, int whence);

        char *readBuf;
        readBuf = (char *)malloc(sizeof(char)*n_write + 1);//qiangzhi zhizhen
//      ssize_t read(int fd, void *buf, size_t count);

//      lseek(fd,0,SEEK_SET);
        lseek(fd,-25,SEEK_CUR);
        int n_read = read(fd,readBuf, n_write);

        printf("read : %d,contex : %s\n",n_read,readBuf);

//      int close(int fd);
        close(fd);



        return 0;

}

运行结果为: 

lseeknew6.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>


int main()
{
        int fd;

        char *buf = "ganboss is very handsome!";

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

        int filesize = lseek(fd,0,SEEK_END);

        printf("file's size is %d\n",filesize);

        close(fd);

        return 0;

}

 运行结果为:

creat的系统调用

int creat(const char *filename, mode_t mode)

filename:要创建的文件名(包含路径,缺省为当前路径)

mode:创建模式

creat的返回值为文件描述符,其本质为一个非负整数,是由系统分配。文件说明符的范围为0 - OPEN_MAX。早期的UNIX版本OPEN_MAX = 19,即允许每个进程同时打开20个文件,现在很多系统则将其增加到1024. 

 

常见的创建模式:

S_IRUSR            可读    4       (可以用数字来表示访问权限)

S_IWUSR            可写    2        (无任何权限->0)

S_IXUSR            可执行  1

S_IRWXU         可读、可写、可执行 7
createtest10.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>


int main()
{
        int fd;

        char *buf = "test!";

//       int creat(const char *pathname, mode_t mode);

        fd = creat("/home/ganboss/syslinux/11fileop/file1",S_IRWXU);

        return 0;

}

运行结果为:     让 a.out  变成  -rwxr-xr-x

                                                                             

猜你喜欢

转载自blog.csdn.net/weixin_46016743/article/details/114845884