Linux C应用编程-1-文件IO

2019-04-23  本文已影响0人  Mr_Michael

1.open与close

#include <stdio.h>
//IO操作需要包含的头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

char filename[] = "text.txt";

int main(void)
{
    int fd;

    fd = open(filename, O_RDWR | O_CREAT, 0777);
    if (fd != -1) {
        printf("open %s ok\r\n",filename);
        if (close(fd) != -1) {
            printf("close %s ok\r\n",filename);
            
        } else {
            printf("close %s fail\r\n",filename);
        }
    } else {
        printf("open %s fail\r\n",filename);
    }

    return 0;
}

常用flags有:

以下三个常数中必须指定一个,且仅允许指定一个。

以下可选项可以同时指定0个或多个,和必选项按位或起来作为flags参数。可选项有很多,这里只介绍一部分,其它选项可参考open(2)的Man Page:

2.read与write

#include <stdio.h>
#include <stdlib.h>
//IO操作需要包含的头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

char filename[] = "./text.txt";

int main(void)
{
    int fd;
    char buf[10];
    int n;
    int i = 0;
    int len;
    
    //如果文件不存在就创建文件
    fd = open(filename, O_RDWR | O_CREAT, 0777);
    //fd = open(filename, O_RDONLY | O_WRONLY);
    if(fd == -1) {
        printf("open %s fail\r\n",filename);
        exit(1);
    } else {
        printf("open %s ok\r\n", filename);
    }
    
    n = write(fd, "1234567890", 10);
    if(n == -1) {
        printf("write %s fail\r\n",filename);
    } else {
        printf("write %s %d buff\r\n",filename, n);
    }
    
    //由于write操作会使读写位置处于内容末尾,需要指向到当前位置的前10偏移位置
    lseek(fd, -10, SEEK_CUR);
    
    n = read(fd, buf, 10);
    if(n == -1) {
        printf("read %s fail\r\n",filename);
    } else {
        printf("read %s %d buff\r\n",filename, n);
    }

    printf("read buf len:%d\r\n", n);
    //write(STDOUT_FILENO, buf, 10);
    for (i = 0; i < 10; i++)
    {
        printf("%c",buf[i]);
    }
    
    if(close(fd) == -1) {
        printf("close %s fail\r\n",filename);
        exit(1);
    } else {
        printf("close %s ok\r\n", filename);
    }

    return 0;
}

3.mmap

mmap可以把磁盘文件的一部分直接映射到内存,这样文件中的位置直接就有对应的内存地址,对文件的读写可以直接用指针来做而不需要read/write函数。

image
#include <stdio.h>
#include <stdlib.h>
//内存映射需要的头文件
#include <sys/mman.h>
//文件操作需要的头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(void)
{
    int *p;
    int fd;
    
    //判断文件是否存在
    if (access("text.txt",F_OK) == -1) {
        perror("access text.txt");
        exit(1);
    }

    fd  = open("text.txt", O_RDWR);
    if (fd == -1) {
        perror("open text.txt");
        exit(1);
    }
    
    //映射之前文件内容不能为空,否则映射出错
    //mmap没法增加文件长度,通过内存对文件操作的数据长度不会超过文件本身包含的数据长度的
    //length==6,代表将文件中6word的数据映射到内存,但如果length小于一个内存页的长度,
    //测试发现实际设置共享内存的大小是一页。
    p = mmap(NULL, 6, PROT_WRITE, MAP_SHARED, fd, 0);
    if (p == MAP_FAILED) {
        perror("mmap");
        exit(1);
    }
    
    if (close(fd) == -1)
    {
        perror("close text.txt");
        exit(1);
    }
    
    p[0] = 0x31303030;  //低位在前,高位在后 X86架构下
    p[1] = 0x32303030;
    p[2] = 0x33303030;
    p[3] = 0x34303030;
    p[4] = 0x35303030;
    p[5] = 0x36303030;

    //取消映射
    if (munmap(p, 6) == -1) {
        perror("munmap");
        exit(1);
    }
    
    return 0;
}

prot参数有四种取值:

flag参数有很多种取值,这里只讲两种,其它取值可查看mmap(2)

4.实用工具

1)access

用于判断该文件是否存在或者是否可以读/写某一已存在的文件。

#include<unistd.h>
int access(const char * pathname,int mode);
/*
pathname:文件路径
mode: 文件访问的权限
R_OK,W_OK与X_OK:检查文件是否具有读取、写入和执行的权限。
F_OK:判断该文件是否存在。

返回0值,表示成功,只要有一权限被禁止则返回-1。
*/

2)lseek

改变文件当前读写位置。打开文件时读写位置是0,表示文件开头,通常读写多少个字节就会将读写位置往后移多少个字节。

#include <sys/types.h>
#include <unistd.h>

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

/*
fd 表示要操作的文件描述符
offset是相对于whence(基准)的偏移量
whence 可以是SEEK_SET(文件指针开始),SEEK_CUR(文件指针当前位置) ,SEEK_END为文件指针尾

返回值:文件读写指针距文件开头的字节大小,出错,返回-1
*/
上一篇下一篇

猜你喜欢

热点阅读