美文网首页
POSIX文件操作(一)

POSIX文件操作(一)

作者: oceanLong | 来源:发表于2018-04-06 17:57 被阅读203次

    前言

    在移动开发中,难免要做一些跨平台的事情。iOS和Android各执一套,平台很难跨。但其底层Linux和Unix则早早做了一套不错的兼容标准。这套标准就是POSIX

    不论是Android还是iOS都没有在native层,给我们提供完整的关于界面和手机相关功能的API。因此,从设计思路上,我们在native层,应该完成的工作应该是纯数据的,不挑系统的,无需界面的工作。

    这些工作中,就包括,数据的处理与转换。文件的操作,线程和进程的调度及网络操作。今天,主要记录文件操作的方法。

    基础读写操作

    以下示例需要头文件

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

    打开文件

        #define FILE_NAME "./test.txt"
    
        if((fd_open_create=open(FILE_NAME,O_CREAT|O_RDWR,0644))==-1)
        {
            perror("open");
        }
        printf("the %s file descriptor is:%d\n",FILE_NAME,fd_open_create);
    

    open方法,我们输入了三个参数,分别是:

    • 文件的相对路径
    • 文件的打开方式
    • 文件的权限

    这里有一些值得注意的点。

    文件路径

    笔者是在xcode下开发的c++,运行程序后的可执行文件,并不在工程目录下。因此,使用
    相对路径时也要注意。相对路径的基点在运行后的可执行文件处。xcode中有一种简单的找到此目录的办法,即是在右边的工程目录栏中的Products下,找到可执行文件,右键'Show in Finder'。

    文件打开方式

    fcntl.h中,我们可以看到如下宏定义:

    /* open-only flags */
    #define O_RDONLY    0x0000      /* open for reading only */
    #define O_WRONLY    0x0001      /* open for writing only */
    #define O_RDWR      0x0002      /* open for reading and writing */
    #define O_ACCMODE   0x0003      /* mask for above modes */
    
    /*
     * Kernel encoding of open mode; separate read and write bits that are
     * independently testable: 1 greater than the above.
     *
     * XXX
     * FREAD and FWRITE are excluded from the #ifdef KERNEL so that TIOCFLUSH,
     * which was documented to use FREAD/FWRITE, continues to work.
     */
    #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
    #define FREAD       0x0001
    #define FWRITE      0x0002
    #endif
    #define O_NONBLOCK  0x0004      /* no delay */
    #define O_APPEND    0x0008      /* set append mode */
    
    #include <sys/_types/_o_sync.h>
    
    #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
    #define O_SHLOCK    0x0010      /* open with shared file lock */
    #define O_EXLOCK    0x0020      /* open with exclusive file lock */
    #define O_ASYNC     0x0040      /* signal pgrp when data ready */
    #define O_FSYNC     O_SYNC      /* source compatibility: do not use */
    #define O_NOFOLLOW  0x0100      /* don't follow symlinks */
    #endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */
    #define O_CREAT     0x0200      /* create if nonexistant */
    #define O_TRUNC     0x0400      /* truncate to zero length */
    #define O_EXCL      0x0800      /* error if already exists */
    

    通过标志位运算的方式,定义了各种打开行为。在此不一一赘述,读者可以通过后面的注释大致了解这些标志位所控制的行为。

    文件权限

    这里对文件的权限进行了设置,0644的逻辑与chmod类似。第一位决定了是文件还是目录,后面三位则决定了,不同用户组,对此文件rwe(read,write,execute)权限。

    这一段可以参考File Permissons

    文件写入

        const char buf1[] = "1234567890abc\n";   // 临时需要写入的信息
        // write chars to file at head
        if( write(fd_open_create, buf1, 10) != 10 )
        {
            perror("write");
        }
        printf("the %s file write\n",FILE_NAME);
    

    这一段比较简单,就是将buf1中的前10个字符写入文件中。值得注意的是,这样的写入是复写的方式。如果想要在已有内容后面添加,文件需要使用O_APPEND方式打开。

    光标移动

    我们在写入过程中,可能会有些特殊需求,在文字中,直接改写某些地方(注意:这里只能改写,不能插入)。在这样的情景下,我们需要移动光标。

        const char buf2[] = "ABCDEFGHIJ\n";
        // move cursor in file
        if(lseek(fd_open_create, 5, SEEK_SET) == -1)         // 从5位置写
        {
            perror("lseek");
            exit(EXIT_FAILURE);
        }
        printf("the %s file lseek\n",FILE_NAME);
        
        // write chars to file at seek position
        if( write(fd_open_create, buf2, 10) != 10 )
        {
            perror("write");
        }
        printf("the %s file write\n",FILE_NAME);
        
    

    在上面的例子中,我们将光标移动至第5位,然后再开始写入。

    文件读取

    与上面的操作类似,文件的读取,也是从光标处开始的。

        // move cursor in file
        if(lseek(fd_open_create, 3, SEEK_SET) == -1)         // 从3位置读取
        {
            perror("lseek");
            exit(EXIT_FAILURE);
        }
        // read chars from file
        if( read(fd_open_create, bufr, 15) == 0)
        {
            perror("read");
        }
        
        printf("the %s file read content : %s\n",FILE_NAME , bufr);
    

    关闭文件

        close(fd_open_create);
    

    锁定/解锁文件

    flock()函数和fcntl()都可以对文件进行锁定和解锁.但是前者只能锁定整个文件,而后者可以提供任意位置的文件锁定.

        fcntl(fd_open_create, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));  
        fcntl(fd_open_create, F_SETLKW, file_lock(F_UNLCK, SEEK_SET)); 
    

    相关文章

      网友评论

          本文标题:POSIX文件操作(一)

          本文链接:https://www.haomeiwen.com/subject/dwqshftx.html