文件IO函数

文件IO函数

open 打开 / close 关闭
write 写 / read 读
lseek

1. open函数

功能:打开一个文件
原型:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

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

参数:

  • char *pathname: 指定要打开的文件路径以及名字;

  • int flags:打开方式

    int flag解释
    O_RDONLY只读
    O_WRONLY只写
    O_RDWR读写
    ----以上三种,必须且只能包含一个----
    O_APPEND追加的方式
    O_CREAT如果文件不存在,则创建一个普通文件;
    O_TRUNC如果文件存在,则清空文件;

    如果需要多个选项,则可以用按位或(‘|’)连接

    fopen() modeopen() flags
    rO_RDONLY
    r+O_RDWR
    wO_WRONLY
    w+O_RDWR
    aO_WRONLY
    a+O_RDWR
  • mode_t mode:在文件创建时候,指定文件权限使用。

例如:
- 0664 :110 110 100 rw- -rw- -r–
- 0777 : 111 111 111 rwx-rwx-rwx
当flags中指定了 O_CREAT (创建)或者 O_TMPFILE(清空) 的时候,mode参数必须填写
当flags没有指定上述两种选项,则mode参数会被忽略

返回值:

  • 成功,返回新的文件描述符;
  • 失败,返回-1,更新errno;
int fd = open("./open.txt", O_WRONLY|O_CREAT|O_TRUNC, 0664);
if(fd < 0)
{
    perror("open");
    return -1;
}

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

2.umask

所创建文件的模式为(mode & ~umask)

mode 0777 —> 111 111 111 & ~umask 111 111 101 —> umask 000 000 010 ===> 0002 111 111 111

2.1什么是umask

文件权限掩码,会影响文件创建时候的权限。从而保证某个用户没有指定的某种权限

2.2 umask获取

终端输入 umask

2.3 修改umask

  1. 终端输入 umask 0 umask 0022 只在设置终端有效
  2. 用umask函数设置
#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mask);
umask(0);     将umask设置为0

3.close

功能: 关闭文件,释放文件描述符对应的该空间

原型:

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

参数:

  • int fd:指定要关闭的文件;

返回值:

  • 成功返回0;
  • 失败,返回-1,更新errno;

4. write

功能:将数据写入到文件中

原型:

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

参数:

  • int fd:指定要写入到哪个文件中,填对应的文件描述符;

  • void *buf:指定要输出的数据首地址,可以输出任意类型数据;

  • size_t count:指定要输出的数据大小,以字节为单位;

返回值:

  • 成功,返回成功输出的字节数;
  • 失败,返回-1,更新errno.

5.read

功能:从指定的文件中读取数据;
原型:

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

参数:

  • int fd:指定要读取哪个文件,填对应的文件描述符;

  • void *buf:存储读取到的数据;

  • size_t count:指定要读取多少个字节;

返回值:

  • 0 成功,返回成功读取到的字节数;
  • =0 读取到文件结尾;
  • =-1 失败,返回-1,更新errno.

注意:

  1. read不会自动补充\0字符

  2. read函数遇到\n不会停止读取

练习:

用read和write拷贝一个图片,图片可以从widows拖入。

或者在ubuntu环境中按下prt sc按键截图,截图在~/Picture文件夹下。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
    int fp = open("1.png", O_RDONLY);
    int fp1 = open("2.png", O_WRONLY | O_CREAT | O_TRUNC, 0777); // 写,创建,清空,0777权限
    if (fp < 0)
    {
        perror("1.png  open:");
        system("pause");
        return -1;
    }
    if (fp1 < 0)
    {
        perror("2.png open:");
        system("pause");
        return -1;
    }

    char buf[10] = "";
    while (1)
    {

        ssize_t re = read(fp, buf, sizeof(buf)); // read遇到\0\n都不结束
        // printf("%s", buf);
        write(fp1, buf, re); // 只写入读取到的字节个数

        if (re == 0)
        {
            break;
        }
    }

    close(fp);
    close(fp1);
}

6. lseek

功能:修改文件偏移量;
原型:

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

参数:

  • int fd:指定要修改哪个文件偏移量,填上对应的文件描述符;

  • off_t offset:偏移量,新的位置位whence加上offset参数,

    • 若想往结尾偏移,则填正数

    • 若想往开头偏移,则填负数;

  • int whence:

    • SEEK_SET, 文件开头
    • SEEK_CUR, 文件当前位置
    • SEEK_END 文件结尾位置

返回值:

  • 成功,返回文件偏移后的当前位置,距离文件开头的偏移量;
  • 失败,返回(off_t)-1; 更新errno;

注:lseek(fd, 0, SEEK_END); 返回值为文件的大小;

练习:用read和write拷贝一个图片,

图片可以从widows拖入。或者在ubuntu环境中按下prt sc按键截图,截图在-/Picture文件夹下。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/*
   程序要求:
   用read和write拷贝一个图片,
   图片可以从widows拖入。或者在ubuntu环境中按下prt sc按键截图,截图在-/Picture文件夹下。
   */
int main()
{
    int fp = open("1.png", O_RDONLY);
    int fp1 = open("2.png", O_WRONLY | O_CREAT | O_TRUNC, 0777); // 写,创建,清空,0777权限
    if (fp < 0)
    {
        perror("1.png  open:");
        system("pause");
        return -1;
    }
    if (fp1 < 0)
    {
        perror("2.png open:");
        system("pause");
        return -1;
    }

    char buf[10] = "";
    while (1)
    {

        ssize_t re = read(fp, buf, sizeof(buf)); // read遇到\0\n都不结束
        // printf("%s", buf);
        write(fp1, buf, re); // 只写入读取到的字节个数

        if (re == 0)
        {
            break;
        }
    }

    close(fp);
    close(fp1);
}

文件属性相关函数

-rw-rw-r-- 1 ubuntu ubuntu 380 三月 24 17:24 01_fileno.c

代码段解析
-rw-rw-r–分别对应用户权限,用户组权限,其他用户权限
1硬链接数
ubuntu文件所属用户名
ubuntu文件所属组用户名
380文件大小(字节byte)
三月 24 17:24修改日期
01_fileno.c文件名

1. stat

**功能: ** 获取文件所有属性;
原型:

//头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *pathname, struct stat *statbuf);
参数:

  • char *pathname:指定要获取哪个文件的属性,填上对应的文件路径以及文件名;
  • ​ struct stat statbuf:存储获取到的文件属性;

返回值:

  • 成功,返回0;
  • 失败,返回-1,更新errno;
struct stat
{
    dev_t st_dev;         // ID of device containing file
    ino_t st_ino;         // Inode number              inode号
    mode_t st_mode;       // File type and mode        文件类型以及文件权限
    nlink_t st_nlink;     // Number of hard links      硬链接数
    uid_t st_uid;         // User ID of owner          文件所属用户的id号      uid
    gid_t st_gid;         // Group ID of owner         文件所属组用户的id号    gid
    dev_t st_rdev;        // Device ID (if special file)
    off_t st_size;        // Total size, in bytes      文件大小
    blksize_t st_blksize; // Block size for filesystem I/O
    blkcnt_t st_blocks;   // Number of 512B blocks allocated
}
struct timespec st_atim;  /* Time of last access */         最后一次被访问的时间
struct timespec st_mtim;  /* Time of last modification */   最后一次被修改的时间
struct timespec st_ctim;  /* Time of last status change */  最后一次被改变状态的时间
#define st_atime st_atim.tv_sec      /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec

2. 提取文件权限

mode_t    st_mode;        /* File type and mode */           文件类型以及文件权限
int a = 0400;//代表八进制数据

mode_t 本质上是一个整型数,且mode_t 是 unsigned int类型。
变量的后9bit存储了文件的权限。

mode: 0100664
        0664--->  110 110 100
                & 100 000 000    ---> 0400 
                ---------------
                  100 000 000     --0400 不等于0,所以打印'r'

        0664--->  110 110 100
                & 010 000 000     ---> 0200
                ---------------
                  010 000 000     --0200 不等于0,所以打印'w'

        0664--->  110 110 100
                & 001 000 000     --->0100
                ---------------
                  000 000 000     --0 等于0,所以打印'-'

作业1:解析文件的权限,把秒数改为时间

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>

void get_mode(mode_t m, char *str); // 问价类型解析函数

int main(int argc, const char *argv[])
{
    struct stat buf;
    if (stat("1.png", &buf) < 0)
    {
        perror("stat:");
        system("pause");
        return -1;
    }
    printf("mode: %o\n", buf.st_mode); // 文件类型及文件权限
    char str[10] = "";
    get_mode(buf.st_mode, str); // 文件类型权限解析函数
    printf("%s\n", str);
    printf("link: %ld\n", buf.st_nlink); // 硬链接数
    printf("uid: %d\n", buf.st_uid);     // 文件所属用户的id号
    printf("gid: %d\n", buf.st_gid);     // 文件所属组的id号
    printf("size: %ld\n", buf.st_size);  // 文件大小
    printf("time: %ld\n", buf.st_ctime); // 文件修改时间
    struct tm *tt = localtime(&buf.st_ctime);
    printf("%d月 %d %d:%d", tt->tm_mon + 1, tt->tm_mday, tt->tm_hour, tt->tm_min);
    system("pause");
    return 0;
}
/*文件类型权限解析函数*/
void get_mode(mode_t m, char *str)
{
    // printf("%s\n",str);
    int t = 0400;
    char per[3] = "rwx";
    // printf("%o\n", m);
    for (int i = 0; i < 9; i++, t >>= 1)
    {
        if ((m & t) == 0)
        {
            *(str + i) = '-';
            // putchar('-');
            continue;
        }
        *(str + i) = per[i % 3];
        // putchar(per[i % 3]);
    }
    // printf("\n");
    // printf("%s\n", str);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值