POSIX文件I/O编程

简介: POSIX文件I/O编程

POSIX是可移植操作系统接口的简写,英文全程是Portable Operating System Interface。最初由IEEE(Institute of Electrical and Electronics Engineers,IEEE)开发,目的是为了提高UNIX环境下的应用程序可移植性。实际上POSIX并不局限于UNIX,只要符合此标准的操作系统的系统调用是一致的,例如Linux和Microsoft Windows NT。POSIX是一组操作系统调用的规范,本节介绍其中的文件I/O编程规范。

1 底层的文件I/O操作

ANSI文件操作函数不同的是,POSIX文件操作的函数基本上和计算机设备驱动的底层操作(例如read,write等)是一一对应的。读者可以把POSIX文件操作理解为对设备驱动操作的封装。由此也可以看出,POSIX文件操作是不带数据缓冲的。

2 文件描述符

POSIX文件操作也使用文件描述符来标识一个文件。与ANSI文件描述符不同的是,POSIX文件描述符是int类型的一个整数值。POSIX文件描述符仅是一个索引值,代表内核打开文件记录表的记录索引。在一个系统中,文件打开关闭比较频繁,因此同一个POSIX文件描述符的值在不同时间可能代表不同的文件。

任何打开的文件都将被分配一个唯一标识该打开文件的文件描述符,为一个大于等于0的整数。需要注意的是,对于一个进程来说,打开文件的数量不是任意大小的。POISX没有规定一个进程可以打开文件的最大数目,不同的系统有不同的规定,例如Linux系统默认一个进程最多可以打开1024个文件,用户可以在console模式下通过ulimit –n命令查看系统允许进程打开文件的数量。

3 创建/打开/关闭文件

POSIX使用open()函数打开一个文件,使用creat()函数创建一个新文件,这两个函数在手册里常常放在一起介绍,因为open()函数在指定一定参数的情况下会隐含调用creat()函数创建文件。

1.open()函数

2.creat()函数

3.close()函数

clos()函数定义形式如下:

#include <unistd.h>
int close(int fd);

4 读写文件内容

POSIX文件操作使用read()函数和write()函数对文件读写,和ANSI文件操作的fread()函数和fwrite()函数不同的是read()函数和write()函数是不带缓冲的,并且不支持记录方式。write()函数的定义如下:

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

mode参数说明

  • r或rb为
    读打开文件
  • w或wb
    为写打开文件,并把文件长度置为0(清空文件)
  • a或ab
    在文件结尾添加打开
  • r+或r+b或rb+
    为读和写打开
  • w+或w+b或wb+
    为写打开文件,并把文件长度置0(清空文件)
  • a+或a+b或ab+
    在文件结尾读写打开

5 文件内容定位

每当打开一个文件的时候,都会有一个与文件相关联的读写位置偏移量,相当于一个文件指针。文件偏移量是一个非负整数,表示相对于文件开头的偏移。通常情况下,文件的读写操作都是从当前文件偏移量开始,读写之后使文件偏移量增加读写的字节数。打开文件时,如果不指定O_APPEND方式,文件偏移量默认是从0开始。

POSIX文件操作提供了lseek()函数用于设置文件偏移量,函数定义如下:

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fildes, off_t offset, int whence);

参数值解释SEEK_SET从文件开始处设置文件偏移量SEEK_CUR从当前文件偏移量设置SEEK_END从文件结尾处设置文件偏移量

6 修改已打开文件属性

fcntl()函数提供了获取或者改变已打开文件性质的功能,函数定义如下:

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);

7 POSIX文件编程实例

最后给出一个POSIX操作文件的例子,完成文件的创建,读写等操作。

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include stdio.h>
#include <errno.h>
extern int errno;
int main(){
    int fd;,file_mode;                        // 注意,文件描述符是整型值
    char buf[64] = "this is a posix file!(line1)\n";
    off_t curr_pos;    
    fd = open("./posix.data", O_CREAT|O_RDWR|O_EXCL, S_IRWXU);
    //打开一个不存在的文件,并创建文件,权限是用户可读写执行
    if (-1==fd) {  // 检查文件打开是否成功
        switch (errno) {
            case EEXIST:                // 文件已存在
            printf("File exist!\n");
            break;
            default:                    // 其他错误
            printf("open file fail!\n");
            break;
        }
    return 0;
    }
    write(fd, buf, strlen(buf));                // 把字符串写入文件
    curr_pos = lseek(fd, 0, SEEK_CUR);        // 取得当前文件偏移量位置
    printf("File Point at: %d\n", curr_pos);
    lseek(fd, 0, SEEK_SET);                // 把文件偏移量移动到文件开头
    strcpy(buf, "File Pointer Moved!\n");
    write(fd, buf, strlen(buf));                // 把新的数据写入文件
    file_mode = fcntl(fd, F_GETFL);        // 获取文件状态标记
    if (-1!=file_mode) {
        switch (file_mode&O_ACCMODE) {    // 检查文件状态
            case O_RDONLY:
                printf("file mode is READ ONLY\n");
                break;
            case O_WRONLY:
                printf("file mode is WRITE ONLY\n");
                break;
            case O_RDWR:
                printf("file mode is READ & WRITE\n");
                break;
               }
       }
       close(fd);
       return 0;
}


目录
相关文章
|
5月前
|
Unix C语言
用C语言打造自己的Unix风格ls命令
用C语言打造自己的Unix风格ls命令
|
6月前
|
消息中间件 Linux
Linux进程间通信(IPC)教程 Linux共享内存介绍:介绍POSIX共享内存的基本概念、用途和编程实践
Linux进程间通信(IPC)教程 Linux共享内存介绍:介绍POSIX共享内存的基本概念、用途和编程实践
135 2
|
6月前
|
Linux 测试技术 C语言
【Linux】应用编程之C语言文件操作
【Linux】应用编程之C语言文件操作
|
6月前
|
消息中间件 Kubernetes NoSQL
posix_memalign函数详解
posix_memalign函数详解
|
Unix Linux
Linux和Unix的区别?什么是Posix标准?
Linux和Unix的区别?什么是Posix标准?
174 0
|
Linux API
Linux下文件操作的主要系统调用,注意要点及说明!
基本上所有的操作系统都会有对文件的操作,也叫文件I/O。除开可以C函数库中基本操作外,所有操作系统都会针对各自的特点重新提供一些操作文件的API,下面描述一下linux下的主要文件操作API。 一、函数名称及格式。 creat   函数(相信很多的初学者都会在这个名字上吃点小亏)- 创建文件 int creat(const char* pathname,mode_t mode
1384 0