前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Linux】Linux文件

【Linux】Linux文件

作者头像
半生瓜的blog
发布2023-05-13 14:07:17
39.7K0
发布2023-05-13 14:07:17
举报
文章被收录于专栏:半生瓜のblog半生瓜のblog

Linux文件操作

Linux中,一切皆文件(网络设备除外)。 硬件设备也“是”文件,通过文件来使用设备。 目录(文件夹)也是一种文件。

Linux文件的结构

image-20220528174041390
image-20220528174041390

  • root:该目录为系统管理员(也称作超级管理员)的用户主目录。
  • bin:bin是Binary的缩写,这个目录存放着最经常使用的命令
  • boot:这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件和镜像文件。
  • deb:deb是Device(设备)的缩写,该目录下存放的是Linux的外部设备,在Linux中访问设备的方式和访问文件的方式是相同的。
  • etc:所有的配置文件,所有的系统管理所需要配置文件和子目录都存放在这里。
  • home:用户的主目录,在Linux系统中,每个用户都有一个自己目录,一般该目录名是以用户的账号命名的。
  • var:存放着不断变化的文件数据,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。
  • lib:这个目录里存放着系统最基本的动态链接共享库,其作用类似于Windows里的DLL文件。几乎所有的应用程序都要使用到这个共享库。
  • usr:系统用户工具和程序
  • bin:用户命令
  • sbin:超级用户使用的比较高级的管理程序和系统守护程序
  • include:标准头文件
  • lib:库文件
  • src:内核源代码
  • tmp:用来存放一些临时文件
  • media:Linux系统会自动识别一些设备,例如U盘、光驱等,当识别后,Linux会把识别的设备挂载到这个目录下。
  • mnt:临时挂载其他文件。
  • proc:包含了进程的相关信息。

Linux文件的操作方式

  • 文件描述符fd

fd是一个大于等于0的整数。 每打开一个文件,就创建一个文件描述符,通过文件描述符来操作文件。

预定义的文件描述符: 0: 标准输入,对应于已打开的标准输入设备(键盘) 1: 标准输出,对应于已打开的标准输出设备(控制台) 2: 标准错误,对应于已打开的标准错误输出设备(控制台) (运行程序在proc文件夹中的对应进程文件夹下查看fd文件夹) 多次打开同一个文件,可以得到多个不同的文件描述符。

  • 使用底层文件操作(系统调用)

例如:read

  • 使用I/O库函数

例如: fread


Linux底层文件操作

(关于文件的系统调用)


write

往一个文件描述符中写数据。

返回值:

  • 成功:返回实际写入的字节数
  • 失败:返回-1,设置错误号errno,用strerror(errno)查看

注意:

  • 从文件当前指针位置开始写入。文件刚打开时从文件指针指向文件头。

示例:

代码语言:javascript
复制
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

int main(void) {

	char buff[] = "hello world\n";
	//1 2 都是输出到控制台
	int len = 0;
	len = write(1, buff, sizeof(buff));//标准输出
	if (len < 0) {
		printf("write failed.reason:%s\n",strerror(errno));
	}
	len = write(2, buff, sizeof(buff));//标准出错输出
	if (len < 0) {
		printf("write failed.reason:%s\n", strerror(errno));
	}
	return 0;
}
image-20220528230403044
image-20220528230403044

read

从一个文件描述符中读取count个字节到buff中。

返回值:

  • 大于0——实际读取的字节数
  • 0——已读到文件尾
  • -1——出错

注意:

  • 参数3表示最多能接受的字节数,而不是指一定要输入的字节数。

示例:

代码语言:javascript
复制
char buffer[1024];
int cnt = read(0,buffer,sizeof(buffer));//从标准输入读

open

代码语言:javascript
复制
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

打开文件

返回值:

  • 成功:文件描述符
  • 失败:-1

打开方式:

  • O_RDONLY 只读
  • O_WRONLY 只写
  • O_RDWR 读写
  • O_CREAT 如果文件不存在,则创建该文件,并使用第3个参数设置权限,如果文件存在 ,则只打开文件。
  • O_EXCL 如果同时使用O_CREAT而且该文件又已经存在

时,则返回错误, 用途:以防止多个进程同时创建 同一个文件

  • O_APPEND 尾部追加方式(打开后,文件指针指向文件的末尾)
  • O_TRUNC 若文件存在,则长度被截为0,属性不变

参数3:设置权限

注意:

  • 返回的文件描述符是该进程未打开 的最小的文件描述符。

示例:

代码语言:javascript
复制
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

#define  FILE_RW_LEN 1024

int main(void) {
	
   //第二个参数-文件存在则无法打开
   //O_AOOEND —— 追加
	int fd = open("./test_open.txt", O_CREAT | O_EXCL | O_RDWR,S_IRWXU | S_IRGRP |S_IXGRP | S_IROTH);
	int count = 0;
	char buffer[FILE_RW_LEN] = "hello i am test";

	if (fd < 0) {
		printf("open failed!,reason :%s\n",strerror(errno));
		exit(-1);
	}

	count = write(fd, buffer, strlen(buffer));

	printf("written: %d bytes\n",count);

	close(fd);

	return 0;
}
image-20220607235540558
image-20220607235540558

提示:!gcc——重新执行gcc上次编译的命令


close

代码语言:javascript
复制
int close(int fd);

关闭文件

终止指定文件描述符与对应文件之间的关联。 并释放该文件描述符,即该文件描述符可被重新使用。

返回值:

  • 成功:0
  • 失败:-1

示例:

代码语言:javascript
复制
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

#define FILE1_NAME "file1.txt"
#define FILE2_NAME "file2.txt"

int main(void) {
	
	int file1, file2;
	char buffer[4096];
	int len = 0;

	file1 = open(FILE1_NAME, O_RDONLY);
	if (file1 < 0) {
		printf("open file failed! reason:%s\n",strerror(errno));
		exit(-1);
	}

	file2 = open(FILE2_NAME, O_CREAT | O_WRONLY ,S_IRUSR | S_IWUSR);
	if (file2 < 0) {
		printf("open file failed! reason:%s\n", strerror(errno));
		exit(-2);
	}

	while (len = read(file1, buffer, sizeof(buffer) > 0)) {
		write(file2,buffer,len);
	}

	close(file2);//实战记得判断是否关闭成功
	close(file1);


	return 0;
}

提示:

  • 观察耗时:time xxx
  • 程序总的执行时间
  • 程序本身所消耗的时间
  • 系统调用所消耗的时间
image-20220608161755521
image-20220608161755521

lseek

代码语言:javascript
复制
off_t lseek(int fd, off_t offset, int whence);

重新定义读写文件的偏移。

返回值:

  • 成功:返回新的文件位置与文件头之间的偏移。
  • 失败:-1

**示例:**从一个文件偏移100处,拷贝100字节到另一个文件。

代码语言:javascript
复制
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

#define  FILE1_NAME "lseek_test.c"
#define  FILE2_NAME "lseek_test2.txt"

#define  SIZE 100

int main(void) {
	int file1, file2;
	char buffer[1024];
	int ret;

	file1 = open(FILE1_NAME, O_RDONLY);
	if (file1 < 0) {
		printf("open file failed! reason:%s\n", strerror(errno));
		exit(-1);
	}

	file2 = open(FILE2_NAME, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
	if (file2 < 0) {
		printf("open file failed! reason:%s\n", strerror(errno));
		exit(-2);
	}

	//文件句柄,偏移量,从哪偏移

	ret = lseek(file1, 0, SEEK_END);
	printf("file size: %d\n", ret);

	ret = lseek(file1, 100, SEEK_SET);
	printf("lseek ret:%d\n", ret);

	ret = read(file1, buffer, SIZE);
	if (ret > 0) {
		buffer[ret] = '\0';
		write(file2,buffer,SIZE);
	}

	close(file1);
	close(file2);


	return 0;
}

ioctl

嵌入式相关

ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性接口进行控制,例如串口的传输波特率、马达的转速等等。是设备驱动程序中设备控制接口函数,用来控制设备。

代码语言:javascript
复制
int ioctl(int fd, int cmd,[int *argdx, int argcx]);

  • fd是用户程序打开设备时使用open函数返回的文件标示符,
  • cmd是用户程序对设备的控制命令,后面是一些补充参数,一般最多一个,这个参数的有无和cmd的意义相关。

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-06-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Linux文件操作
    • Linux文件的结构
      • Linux文件的操作方式
        • Linux底层文件操作
          • write
          • read
          • open
          • close
          • lseek
          • ioctl
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
      http://www.vxiaotou.com