c++笔记--linux编程-linux文件和输入输出文件和目录操作(代码片段)

xiangjai xiangjai     2022-12-15     201

关键词:

目录

Linux文件概念

Linux系统上的文件部分类型说明

文件描述符

使用文件描述符

打开和关闭文件描述符

示例

读写文件描述符

read函数例子

write函数例子

使用fstat获取文件信息

文件和目录操作

库函数和系统调用

打开和关闭文件

mode说明

读写文件

fread函数例子

fwrite函数例子

格式化输入和输出调用

fprintf函数例子

fscanf函数例子

行输入和输出调用

fgets函数例子

fputs函数例子

文件删除和改名

writelog函数

remove函数例子

rename函数例子

找到当前目录

获得目录列表

获取目录列表例子


Linux文件概念

Linux系统上的文件部分类型说明

普通文件。

        就是储存到磁盘上大家所操作的各种数据文件;

管道文件。

        是一个从一端发送数据,从另一端接收数据的通道;

目录

        也叫目录文件,是包含了保存在目录中文件的列表;

设备文件

        是一种特殊文件,提供了大多数物理设备的接口;

符号链接

        包含了到另一个人文件的连接,类似于windows的快捷方式;

套接口

        套接口更像管道文件,但可以让处于不同机器上的进程通讯

文件描述符

        文件描述符是个很小的正整数,它是一个索引值,指向内核为每个进程所维护的该进程打开文件的记录表。

        例如:每个进程启动时都打开3个文件:

                标准输入文件(stdin)

                标准输出(stdout)

                标准出错(stderr)

        这三个文件分别对应文件描述符0、1、2,实际上,你可能已经用过基于描述的I/O操作,但却没有意识到。编程中应该使用<unistd.h>中定义的STDIN_FILENO、 STDOUT_FILENO、 STDERR_FILENO代替数字0、1、2

        说明:

        基于文件描述符的I/O操作兼容POSIX标准,所以移植性比较好。 许多Linux、Unix系统都依赖于文件描述符。 尤其是TCP/IP操作只能通过文件描述符执行输入输出。 在Linux上几乎每样东西都是一个文件。 这样大量资源,比如内存,磁盘空间,进程间通讯,声卡,鼠标都有了一个统一的编程接口。

使用文件描述符

打开和关闭文件描述符

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int open(const char *pathname, int flags);
int close(int fd);

1. open试图打开参数pathname中的一个文件(引入#include <fcntl.h>)

2. 参数flags指定访问该文件的方式。

3. 必须把flags设置为O_RDONLY、O_WRONLY、O_RDWR、O_CREAT、O_APPEND分别表示只读、只写、读写、如果文件不存在就创建、追加。

4. open成功后会返回一个文件描述符。

5. open失败后会返回-1,并设置errno变量(需引入#include "errno.h")

示例

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int main()

	char s[] = "abc.txt";
	int fd = open(s, O_RDONLY);
	if (fd == -1)
	
		printf("error is %s\\n", strerror(errno));		
	
	else
	
		printf("success fd=%d\\n", fd);
	
	return 0;

open试图打开一个不存在的文件,返回-1。

如果想知道更加详细的错误描述,请使用errno和strerror函数

在一个文件描述符用完后一定要用close()函数关闭它,这样才能保证该进程对文件所有加的锁全部被释放

读写文件描述符

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, void *bug, size_t count);

read用于从文件描述符对应的文件读取数据,调用成功返回读出的字节数(引入#include<unistd.h>)

参数fd必须是用open调用返回的有效文件描述符。

参数buf为读出数据的缓冲区,count指定读出的字节数。

成功返回读取字节数,如果遇到EOF,返回0,出错返回-1

read函数例子

int main()

	char s[] = "abc.txt";
	int fd = open(s, O_RDONLY);
	if (fd == -1)
	
		printf("error is %s\\n", strerror(errno));
	 else
	
		printf("success fd=%d\\n", fd);
		char buf[100];
		memset(buf, 0, sizeof(buf));
		int i = read(fd, buf, sizeof(buf));
		printf("%s\\n", buf);
		close(fd);
	
	return 0;

write函数例子

int main()

	char s[] = "abc.txt";
	int fd = open(s, O_RDWR | O_APPEND);
	if (fd == -1)
	
		printf("error is %s\\n", strerror(errno));		
	
	else
	
		printf("success fd=%d\\n", fd);
		char buf[100];
		memset(buf, 0, sizeof(buf));
		strcpy(buf, “hello world\\n");
		int i = write(fd, buf, strlen(buf));
		close(fd);	
	
	return 0;

使用fstat获取文件信息

int fstat(int fd, struct stat *buf)

参数fd必须是用open调用返回的有效文件描述符。

使用stat获取文件信息。

int stat(const char *path, struct stat *buf);

参数path是路径加文件名的字符串(引入#include "sys/stat.h")

Struct stat定义如下:

struct stat 
              dev_t     st_dev;     /* ID of device containing file */
              ino_t     st_ino;     /* inode number */
              mode_t    st_mode;    /* protection */
              nlink_t   st_nlink;   /* number of hard links */
              uid_t     st_uid;     /* user ID of owner */
              gid_t     st_gid;     /* group ID of owner */
              dev_t     st_rdev;    /* device ID (if special file) */
              off_t     st_size;    /* total size, in bytes */
              blksize_t st_blksize; /* blocksize for filesystem I/O */
              blkcnt_t  st_blocks;  /* number of blocks allocated */
              time_t    st_atime;   /* time of last access */
              time_t    st_mtime;   /* time of last modification */
              time_t    st_ctime;   /* time of last status change */
          ;

 为了正确解释文件类型,有一套宏能够计算stat接口的st_mod成员。              


              S_ISREG(m)  is it a regular file?
              S_ISDIR(m)  directory?
              S_ISCHR(m)  character device?
              S_ISBLK(m)  block device?
              S_ISFIFO(m) FIFO (named pipe)?
              S_ISLNK(m)  symbolic link? (Not in POSIX.1-1996.)
              S_ISSOCK(m) socket? (Not in POSIX.1-1996.)

fstat函数例子

int main()

	char s[] = "abc.txt";
	int fd = open(s, O_RDONLY);
	if (fd == -1)
	
		printf("error is %s\\n", strerror(errno));
	
	else
	
		printf("success\\n");
		struct stat buf;
		fstat(fd, &buf);
		if (S_ISREG(buf.st_mode))
		
			printf("%s is charfile\\n", s);
		
		close(fd);
	
	return 0;

stat函数例子

int main()

        struct stat t;
        memset(&t, 0, sizeof(t));
        if (stat("a.txt", &t) == 0)
        
                printf("%d\\n", t.st_size);
        
        else
        
                printf("open failed %s\\n", strerror(errno));
        
        return 0;

文件和目录操作

库函数和系统调用

本内容介绍的函数是库函数,而不是系统调用

库函数和系统调用的区别在于系统调用能够让你直接访问linux内核提供的服务,比如上面的函数就是基于系统调用的函数

系统调用函数存在与内核空间,库函数都是用户模式,所以系统调用不当可能会破坏系统,但库函数调用风险就要小很多。

库函数对I/O操作进行缓冲,减少了系统调用开销,同时可移植性也更好。

打开和关闭文件

FILE *p fopen(const char *path, const char *mode);

int fclose(FILE *stream);

fopen以mode模式打开名为path的文件

fopen返回一个文件指针。

出现错误,fopen返回NULL,并把errno设置为恰当的值。

mode说明

         r      Open text file for reading.  The stream is positioned at the beginning of the file.        

         r+     Open for reading and writing.  The stream is positioned at the beginning of the file.                w      Truncate  file  to  zero  length or create text file for writing.  The stream is positioned at the  beginning of the file.        

         w+     Open for reading and writing.  The file is created if it does not exist,  otherwise  it  is  trun-cated.  The stream is positioned at the beginning of the file.        

          a      Open  for  appending  (writing  at  end  of file).  The file is created if it does not exist.  The  stream is positioned at the end of the file.        

           a+    Open for reading and appending (writing at end of file).  The file  is  created  if  it  does  not  exist.   The  initial  file  position  for  reading is at the beginning of the file, but output is               always appended to the end of the file.

读写文件

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);

参数说明:

        1.参数ptr指向缓冲区保存或读取的数据。

        2.参数size控制记录大小。

        3.参数nmemb为记录数。

        4.函数返回读取或回写的记录数

fread函数例子

int main()

	char s[] = "abc.txt";
	FILE *p = fopen(s, "r+");
	if (p == NULL)
	
		printf("error is %s\\n", strerror(errno));
	
	else
	
		printf("success\\n");
		char buf[100];
		memset(buf, 0, sizeof(buf));
		fread(buf,sizeof(buf),1, p);
		printf("%s\\n", buf);
		fclose(p);
	
	return 0;

fwrite函数例子

int main()

	char s[] = "abc.txt";
	FILE *p = fopen(s, "r+");
	if (p == NULL)
	
		printf("error is %s\\n", strerror(errno));
	
	else
	
		printf("success\\n");
		char buf[100];
		memset(buf, 0, sizeof(buf));
		sprintf(buf, "hello world\\n", "%s");
		fwrite(buf,strlen(buf),1, p);
		fclose(p);
	
	return 0;

格式化输入和输出调用

int fprintf(FILE *stream, const char *fromat,…);
int fscanf(FILE *stream, const char *fromat,…);

fprintf函数例子

int main()

	char s[] = "abc.txt";
	FILE *p = fopen(s, "r+");
	if (p == NULL)
	
		printf("error is %s\\n", strerror(errno));
	
	else
	
		printf("success\\n");
		char buf[100];
		memset(buf, 0, sizeof(buf));
		sprintf(buf, "hello world");
		fprintf(p, "%s\\n", buf);
		fclose(p);
	
	return 0;

fscanf函数例子

int main()

	char s[] = "abc.txt";
	FILE *p = fopen(s, "r+");
	if (p == NULL)
	
		printf("error is %s\\n", strerror(errno));
	
	else
	
		printf("success\\n");
		char buf[100];
		memset(buf, 0, sizeof(buf));
		while (fscanf(p, "%s", buf) != EOF)
		
			printf("%s\\n", buf);
		
		fclose(p);
	
	return 0;

行输入和输出调用

char fgets(char *s, int size, FILE *stream);
int fputs(const char *s, FILE *stream);

fgets从文件中读取一行,返回EOF代表文件结尾。

fputs向文件中写入一行

fgets函数例子

int main()

	char s[] = "abc.txt";
	FILE *p = fopen(s, "r+");
	if (p == NULL)
	
		printf("error is %s\\n", strerror(errno));
	
	else
	
		printf("success\\n");
		char buf[100];
		memset(buf, 0, sizeof(buf));
		while (fgets(buf, sizeof(buf),p) != NULL)
		
			printf("%s", buf);
		
		fclose(p);
	
	return 0;

fputs函数例子

int main()

	char s[] = "abc.txt";
	FILE *p = fopen(s, "a+");
	if (p == NULL)
	
		printf("error is %s\\n", strerror(errno));
	
	else
	
		printf("success\\n");
		char buf[100];
		memset(buf, 0, sizeof(buf));
		sprintf(buf, “hello world\\n");
		fputs(buf, p);
		fclose(p);
	
	return 0;

文件删除和改名

int remove(const char *pathname);
int rename(const char *oldpath, const char *newpath);

remove函数删除pathname指向的文件名。

Rename函数修改文件名称。

执行成功返回0,失败返回-1,错误码保存在变量errno中

writelog函数

程序在运行过程中有时需要记录log,writelog函数例子

void writelog(const char *log)

	time_t tDate;
	struct tm *eventTime;
	time(&tDate);
	eventTime = localtime(&tDate);
	int iYear = eventTime->tm_year + 1900;
	int iMon = eventTime->tm_mon + 1;
	int iDay = eventTime->tm_mday;
	int iHour = eventTime->tm_hour;
	int iMin = eventTime->tm_min;
	int iSec = eventTime->tm_sec;
	char sDate[16];
	sprintf(sDate, "%04d-%02d-%02d", iYear, iMon, iDay);
	char sTime[16];
	sprintf(sTime, "%02d:%02d:%02d", iHour, iMin, iSec);
	char s[1024];
	sprintf(s, "%s %s %s\\n", sDate, sTime, log);
	FILE *fd = fopen("my.log", "a+");
	fputs(s, fd);
	fclose(fd);

remove函数例子

int main()

	char s[] = "abc.txt";
	int i = remove(s);
	if (i == -1)
	
		printf("error is %s\\n", strerror(errno));
	
	else
	
		printf("success\\n");
	
	return 0;

rename函数例子

int main()

	char s[] = "abc.txt";
	int i = rename(s,"aaa.txt");
	if (i == -1)
	
		printf("error is %s\\n", strerror(errno));
	
	else
	
		printf("success\\n");
	
	return 0;

找到当前目录

char *getcwd(char *buf,size_t size);

getcwd函数把当前工作目录的绝对路径名复制到buf中,size指示buf的大小。

如果buf不够大,不能装下整个路径名,getcwd返回NULL

获得目录列表

用opendir函数打开目录文件

用readdir函数读出目录文件内容

 用closedir函数关闭目录文件

这些函数都在<dirent.h>中声明

DIR *opendir(const char *pathname);
struct dirent *readdir(DIR *dir);
int closedir(DIR *dir);

Opendir函数打开pathname指向的目录文件,如果错误返NULL

获取目录列表例子

int main(int argc, char *argv[])

	if (argc < 2)
		return 0;
	DIR *dp;
	struct dirent *dirp;
	dp = opendir(argv[1]);
	if (dp == NULL)
	
		printf("error is %s\\n", strerror(errno));
		return 0;
	
	while((dirp = readdir(dp)) != NULL)
	
		printf("%s\\n", dirp->d_name);
	
	closedir(dp);
	return 0;

c++笔记--linux编程(12)-信号

Linux编程(12)-信号 查看详情

c++笔记--linux编程(11)-进程通信(代码片段)

无名管道无名管道        无名管道是半双工的,就是对于一个管道来讲,只能读,或者写。        无名管道只能在相关的、有共同祖先的进程间使用。        一个fork或者exec调用创建的子进程继承了父... 查看详情

c++笔记--linux编程-gccgbbmake(代码片段)

gcc使用gcc,程序员可以对编译过程有更多的控制,编译过程分为3个阶段。-预处理-汇编-链接程序员可以再编译的任何阶段结束后停止整个编译过程以检查编译器在该阶段输出的信息示例#include<stdio.h>intmain(intarg,char*arg... 查看详情

c++笔记--linux编程(14)-线程同步(代码片段)

目录线程同步技术说明互斥锁 加锁和解锁函数 使用mutex线程同步示例读写锁读写锁状态读写锁特性读写锁示例线程同步技术说明        线程共享进程的内存空间,打开的文件描述符,全局变量。        当有多... 查看详情

c++笔记--linux编程(13)-守护进程-线程(代码片段)

目录进程组 概念和特性进程组操作函数(了解)会话创建会话getsid函数pid_tsetsid()会话和进程总结守护进程创建守护进程模型进程与线程线程标识线程调用线程创建pthread_create示例线程终止单个线程通过以下三种方式退出 线程退出... 查看详情

c++学习笔记:高级编程:文件和流,异常处理,动态内存,命名空间

C++文件和流到目前为止,我们已经使用了iostream标准库,它提供了cin和cout方法分别用于从标准输入读取流和向标准输出写入流。本教程介绍如何从文件读取流和向文件写入流。这就需要用到C++中另一个标准库fstream,它定义了三... 查看详情

c++笔记--linux编程(10)-进程控制fork系统调用(代码片段)

Linux进程模型传统的Linux模型里有三种创建或者修改进程的操作    1. system用于调用shell,执行一个指定的命令;    2.fork用于创建一个新的进程,该进程几乎是当前进程的一个完全拷贝;    3.exec可以在进程... 查看详情

linux上c++与cuda混合编程(代码片段)

...结果为了更好地说明如何在Linux实现C++与CUDA的混合编程,我接下来将以实现对一个矩阵的每一个元素的取模运算。1.头文件和文件形式要在C++中编写CUDA代码,需要引入头文件& 查看详情

linux操作系统编程

gcc和g++区别?两者都是编译器,一般用gcc来编译c文件,g++来编译cpp文件,其实gcc也可以来编译c++文件,只不过在链接的时候,gcc不会主动连接C++库。安装gcc和g++的方式有2种?一种是离线安装rpm,另外一种是yum(在线升级)本文出... 查看详情

linux学习-linux系统及编程基础笔记(代码片段)

useraddzhangsanpasswdzhangsanvisudo往/etc/sudoers文件中添加zhangsan#visudo找到如下的行rootALL=(ALL)ALL往该行下面添加zhangsanzhangsanALL=(ALL)ALL2.2Linux的基本结构一些根文件系统中较为重要的二级目录:①/boot:存放系统引导时所需的文件&#... 查看详情

c++笔记--linux网络编程(15-0)-socket(供自查,文档说明)

目录网络基础协议的概念什么是协议典型协议网络应用程序设计模式C/S模式B/S模式优缺点分层模型OSI七层模型TCP/IP四层模型通信过程协议格式数据包封装以太网帧格式ARP数据报格式IP段格式UDP数据报格式TCP数据报格式TCP协议TCP通... 查看详情

awk学习笔记

1.awk简介 awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具... 查看详情

linux下intel的mkl编程代码,怎么样编译。c++和c语言代码

...L/lib/-l库名当然前提该库是路径在/lib/的想要在linux下学习编程,建议把linux编程学好。以上实在linux终端下实现本回答被提问者和网友采纳 查看详情

linux学习-linux系统及编程基础笔记(代码片段)

useraddzhangsanpasswdzhangsanvisudo往/etc/sudoers文件中添加zhangsan#visudo找到如下的行rootALL=(ALL)ALL往该行下面添加zhangsanzhangsanALL=(ALL)ALL2.2Linux的基本结构一些根文件系统中较为重要的二级目录:①/boot:存放系统引导时所需的文件&#... 查看详情

linux编程22shell编程(输出和输入重定向,管道,数学运算命令,退出脚本状态码)(代码片段)

1.输出重定向  最基本的重定向是将命令的输出发送到一个文件中。在bashshell中用大于号(>),格式如下:command>inputfile。例如:将date命令的输出内容,保存到指定的输出文件中。      如果文件已存在,重定向操作符... 查看详情

读书笔记第八章

蜂鸣器是S3C410开发板上带的一个硬件设备。可以通过向寄存器写入特定的值来控制蜂鸣器发出尖叫声。本节介绍蜂鸣器的实现原理,并实现一个完整蜂鸣器驱动。PWM驱动由多个文件组成,这也是大多数Linux驱动的标准实现方式。... 查看详情

linux 中 C++ 中的 UDP Socket 编程

】linux中C++中的UDPSocket编程【英文标题】:UDPSocketprogramminginC++inlinux【发布时间】:2011-06-2120:10:53【问题描述】:我对套接字编程和c++中的初学者-中级完全陌生。我用c++编写了一个代码,还用java编写了另一个应用程序。java程序... 查看详情

使用 ubuntu linux 在 C++ 中进行文件重定向和编码的问题

】使用ubuntulinux在C++中进行文件重定向和编码的问题【英文标题】:Issuewithfileredirectionandcodinginc++usingubuntulinux【发布时间】:2019-02-0320:13:14【问题描述】:我正在尝试完成一项作业,我创建了一个numbers.txt文件,其中一行包含六... 查看详情