如何使用Linux文件描述符(FD)管理文件? (linux fd)

在Linux系统中,文件描述符是一种非常重要的概念,因为它们是管理文件和I/O操作的基石。文件描述符是一个非负整数,它代表着一个正在被打开的文件句柄。在Linux中,所有的I/O操作都是通过文件描述符(FD)来完成的。本文将介绍如何使用Linux文件描述符(FD)来管理文件。

1. 打开文件

在Linux中,打开文件是通过系统调用open()函数来实现的。语法如下:

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

其中,pathname是指文件的路径名,flags是打开文件的模式。open()函数返回一个文件描述符,可以用来进行后续的I/O操作。例如,以下代码打开了一个名为test.txt的文件:

int fd = open(“test.txt”, O_CREAT | O_RDWR, 0644);

其中,O_CREAT和O_RDWR是文件打开的模式,0644是新建文件的权限。

2. 写入文件

在Linux中,写入文件可以通过系统调用write()函数来实现。语法如下:

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

其中,fd是文件描述符,buf是写入数据的指针,count是写入数据的字节数。以下是一个向test.txt写入字符串的例子:

char *str = “Hello, world!”;

write(fd, str, strlen(str));

3. 读取文件

在Linux中,读取文件可以通过系统调用read()函数来实现。语法如下:

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

其中,fd是文件描述符,buf是读取数据的指针,count是读取数据的字节数。以下是一个从test.txt读取字符串的例子:

char buf[1024];

read(fd, buf, 1024);

4. 关闭文件

在Linux中,关闭文件可以通过系统调用close()函数来实现。语法如下:

int close(int fd);

其中,fd是要关闭的文件描述符。以下是一个关闭test.txt文件的例子:

close(fd);

5. 使用dup()和dup2()函数

dup()和dup2()函数可以用来复制文件描述符。dup()函数会返回一个新的文件描述符,它会指向与原来的文件描述符相同的文件。dup2()函数也会返回一个新的文件描述符,但它会把新的文件描述符指定为第二个参数传递的文件描述符,如果该文件描述符已经存在,则会先关闭它。以下是一个使用dup()函数复制文件描述符的例子:

int newfd = dup(fd);

6. 使用fcntl()函数

fcntl()函数可以用来获取和设置文件描述符的属性。以下是一个设置文件描述符为非阻塞状态的例子:

int flags = fcntl(fd, F_GETFL);

flags |= O_NONBLOCK;

fcntl(fd, F_SETFL, flags);

7. 使用mmap()函数

mmap()函数可以在用户进程的内存地址空间中映射磁盘文件。这可以让用户进程直接和磁盘文件进行操作,而不必进行读取和写入操作。以下是一个将磁盘文件映射到用户进程内存中的例子:

struct stat st;

fstat(fd, &st);

void *addr = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);

在本文中,我们介绍了一些使用Linux文件描述符(FD)管理文件的方法。文件描述符是Linux中非常重要的概念,它是管理文件和I/O操作的基石。通过以上介绍,相信读者们对使用文件描述符来管理文件有了一定的了解。

相关问题拓展阅读:

Linux下,fclose(fd)后,为什么没有释放内存,直到把该文件从磁盘上删除,使用内存数才减去文件大小?

fclose会将缓冲区数据写入做枯者磁盘,但若磁盘已满,则fclose就会失败,导致内存没有释放。

判断下fclose返回值是纯薯不是EOF(-1),败谨并检查下是不是磁盘满了。

Linux上的物理网卡与虚拟网络设备

通过 ip link add 可以创建多种类型的虚拟网络设备,在 man ip link 中可以得知有以下类型的device:

Virtual Ethernet Port Aggregator。它是HP在虚拟化支持领域对抗Cisco的VN-Tag的技术。

解决了虚拟机之间网络通信的问题,特别是位于同一个宿主机内的虚拟机之间的网络通信问题。

VN-Tag在标准的协议头中增加了一个全新的字段,VEPA则是通过修改网卡驱动和交换机,通过发夹弯技术回注报文。

TUN是Linux系统里的虚拟网络设备,它的原理和使用在 Kernel Doc 和 Wiki 做了比较清楚的说明。

TUN设备模拟网络层设备(network layer),处理三层报文,IP报文等,用于将报文注入到网络协议栈。

应用程序(app)可以从物理网卡上读写报文,经过处理后通过TUN回送,或者从TUN读取报文处理后经物理网卡送出。

创建:

创建之后,使用 ip addr 就会看见一个名为”tun-default”的虚拟网卡

可以对tun-default设置IP:

使用open/write等文件操作函数从fd中进行读取操作,就是在收取报文,向fd中写入数据,就是在发送报文。

TAP是Linux系统里的虚拟网络设备,它的原理和使用在 Kernel Doc 和 Wiki 做了比较清楚的说明。

不同于TUN的是,TAP设备模拟链路层设备(link layer),处理二层报文,以太网帧等。

TAP设备的创建过程和TUN类似,在ioctl设置的时候,将类型设置为IFF_TAP即可。

TAP设备与TUN设备的区别在于:

有时我们可能需要一块物理网卡绑定多个 IP 以及多个 MAC 地址,虽然绑定多个 IP 很容易,但是这些 IP 会共享物理网卡的 MAC 地址,可能无迹蠢颂法满足我们的设计需求,所以有了 MACVLAN 设备,其工作方式如下:

MACVLAN 会根据收到包的目的 MAC 地址判断这个包需要交给哪个虚拟网卡。单独使用 MACVLAN 好像毫无意义,但是配合之前介绍的 network namespace 使用,我们可以构建这样的网络:

采摘

创建一个基于eth0的名为macv1的macvlan网卡:

macvlan支持三种模式,bridge、vepa、private,在创建的时候设置“mode XXX”:

bridge模式,macvlan网卡和物理网卡直接可以互通,类似于接入到同一个bridge。

vepa模式下,两个macvlan网卡直接不能直接通信,必须通过外部的支持“发夹弯”交换机才能通信。

private模式下,macvlan发出的广播包(arp等)被丢弃,即使接入了支持“发夹弯”的交换机也不能发现其它macvlan网卡,除非手动设置mac。

MACVTAP 是对 MACVLAN的改进,把 MACVLAN 与 TAP 设备的特点综合一下,使用 MACVLAN 的方式收发数据包,但是收到的包不交给 network stack 处理,而是生成一个 /姿郑dev/tapX 文件,交给这个文件:

由于 MACVLAN 是工作在 MAC 层的,所以 MACVTAP 也只能工档凳作在 MAC 层,不会有 MACVTUN 这样的设备。

ipvlan和macvlan的区别在于它在ip层进行流量分离而不是基于mac地址,同属于一块宿主以太网卡的所有ipvlan虚拟网卡的mac地址都是一样的。

veth设备是成对创建的:

创建之后,执行 ip link 就可以看到新创建的veth设备:

注意veth设备前面的ID, 58: 和 59: ,一对veth设备的ID是相差1的,并且系统内全局唯一。可以通过ID找到一个veth设备的对端。

veth设备理解

linux fd的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux fd,如何使用Linux文件描述符(FD)管理文件?,Linux下,fclose(fd)后,为什么没有释放内存,直到把该文件从磁盘上删除,使用内存数才减去文件大小?,Linux上的物理网卡与虚拟网络设备的信息别忘了在本站进行查找喔。


数据运维技术 » 如何使用Linux文件描述符(FD)管理文件? (linux fd)