POSIX文件操作(一)

前言

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

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

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

基础读写操作

以下示例需要头文件

#include 
#include 
#include 

打开文件

    #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 

#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文件操作(一))