Linux系统编程学习笔记(1)-文件的I/O操作

概述

在Linux系统下,通常以一个非负整数来代指一个打开的文件,这些文件可以包括终端,socket,设备,普通文件等等。规定的三个标准的文件描述符为0,1,2下面分别介绍(在交互式shell中,这些文件描述符通常指向shell运行所在的终端):

  • 文件描述符0:
    用途:标准输入
    POSIX名称: STDIN_FILENO

  • 文件描述符1:
    用途:标准输出
    POSIX名称STDOUT_FILENO

  • 文件描述符2
    用途:标准错误
    POSIX名称:STDERR_FILENO
    注:推荐使用

常用的标准函数

fd = open(pathname,flags,mode)

fd即为文件描述符, flags参数指定了文件的打开方式,mode指定了创建文件的访问权限,若open函数没有创建文件,则此参数可以忽略。

numread = read(fd, buffer,count)

从文件描述符fd所指代的文件中读取count个数据到buffer中,返回值即为读取到的字节数。

numwritten = write(fd,buffer,count)

与read函数类似

status = close(fd)

输入与输出操作完成之后,调用次函数以释放资源。

一个简单的I/O操作如下,实现了对文件内容的复制:

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

#ifndef BUF_SIZE
#define BUF_SIZE 1024
#endif

using namespace std;

int main(int argc, char *argv[])
{
  int inputFd, outputFd, openFlags;
  mode_t filePerms;
  ssize_t numRead;
  char buf[BUF_SIZE];
  /*确保在终端输入了正确的文件路径*/
  if (argc != 3 || strcmp(argv[1], "--help") == 0)
    cout<<"param error??"<<endl;
  /*打开输入文件*/
  inputFd = open(argv[1], O_RDWR);
  if (inputFd == -1)
    cout<<"open file"<<argv[1]<<"failed!!"<<endl;
  openFlags = O_CREAT | O_WRONLY | O_TRUNC;
  filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
  /*打开输出文件*/
  outputFd = open(argv[2], openFlags, filePerms);
  if(outputFd == -1)
    cout<<"open file"<<argv[2]<<"failed!!"<<endl;
  /*复制文件内容*/
  while ((numRead = read(inputFd, buf, BUF_SIZE)) > 0)
    if (write(outputFd, buf, numRead) != numRead)
      cout<<"couldnot wrire whole buffer"<<endl;
  if (numRead == -1)
    cout<<"read wrong!!"<<endl;
  /*关闭两个文件*/
  if (close(inputFd) == -1)
    cout<<"can not close input file!!"<<endl;
  if (close(outputFd) == -1)
    cout<<"can not close output file!!"<<endl;
  return 0;
}
g++ main.cpp -o io_test

好玩的是,例如下面的命令:

./io_test /dev/tty a.txt 

会接受开启程序之后用户在终端的输入,知道使用Ctrl+c结束程序之前,用户的输入会一直记录到a.txt当中。反之亦然。

open函数

fd = open(pathname,flags,mode)

mode参数只在创建新文件时有用,主要有以下几个参数可供选择:

  • O_RDONLY:只读方式打开文件
  • O_WRONLY:只写方式打开文件
  • O_RDWR: 读写方式打开文件

flags参数较多且经常使用,下面介绍各种参数的用途:

  1. O_RDONLY:只读方式打开
  2. O_WRONLY:只写方式打开
  3. O_RDWR:读写方式打开
  4. O_CREAT:若文件不存在则创建,注意要加入mode参数
  5. O_DIRECT:无缓冲的输入输出
  6. O_DIRECTORY:若pathname不是文件目录则失败
  7. O_EXCL:结合O_CREAT参数使用,用于创建文件,若文件已经存在,则不会打开文件且报错
  8. O_NOATIME:读取文件时,不修改最近访问时间
  9. O_NOCTTY:不让pathname所指向的文件成为控制终端
  10. O_NOFOLLOW:对符号链接不予解引用
  11. O_TRUNC:截断已有文件,使其长度为0
  12. O_APPEND:总在文件末尾追加数据
  13. O_NONBLOCK:以非阻塞方式打开
  14. O_SYNC:以同步方式打开文件

read()函数

read函数从文件描述符代指的文件中读取数据。buffer参数通过用来存放输入数据的内存缓冲区地址。read成功将返回读取的字节数。当然也可以使用上述提到的标准文件描述符,直接从终端读取数据

numread = read(STDIN_FILENO, buffer, MAX_READ)

注意,由于直接从终端读取,读取的数据类型不确定,read函数无法在读取的数据末尾加上结尾字符’\0’,因此需要人为添加

buffer[numread] = '\0'

才能正确显示输入的数据。

改变文件偏移量

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

off_t数据类型为有符号整数型,whence参数表明依照哪个基点来结束offset参数

  • SEET_SET:文件头部
  • SEET_CUR:当前文件偏移量
  • SEET_END:文件尾部,offset参数从文件最后一个字节的下一个字节开始

打印错误信息

采用linux系统读写函数时,经常出现文件不存在或者访问权限的问题,要知道出现的是什么错误,可以使用perror函数

perror(string)

这个函数可以打印上一次函数的错误信息,string主要为了显示错误的同时显示一些描述性的信息

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值