基于Linux的文件操作(socket操作)

在linux中,socket也被认为是文件的一种,因此在网络数据传输过程中自然可以使用文件I/O的相关函数。

而在Windows中,是要区分socket和文件的,所以在Windows中需要特殊的数据传输相关的函数。

1. 文件描述符

文件描述符(File Descriptor,简称 FD)是操作系统内核用来管理和访问文件的抽象概念。它是一个非负整数,标识每个进程中已打开的文件、套接字等资源。以下是对文件描述符相关知识的总结:

基本概念

文件描述符的定义:

  • 文件描述符是一个整数,代表一个已经打开的文件或其他输入/输出资源(如套接字、管道等)。
  • 每个进程都有自己独立的文件描述符表。

标准文件描述符:

  • 标准输入(stdin):文件描述符 0,通常关联到键盘输入。
  • 标准输出(stdout):文件描述符 1,通常关联到屏幕输出。
  • 标准错误(stderr):文件描述符 2,通常关联到错误信息输出。

文件描述符的分配:

  • 当进程打开一个新的文件时,系统分配下一个未使用的最小整数作为文件描述符,从 3 开始递增。
  • 例如,标准输入、输出和错误分别占用了文件描述符 012,第一个打开的文件会被分配文件描述符 3

2. 文件描述符操作

打开文件

使用 open 系统调用打开文件并返回文件描述符

#include <fcntl.h>

int open(const char *pathname, int flags);
  • pathname:指向要打开的文件路径的字符串。
  • flags:一个整数值,用于指定文件的打开模式和访问模式。常用的标志有:

O_RDONLY:以只读模式打开文件。
O_WRONLY:以只写模式打开文件。
O_RDWR:以读写模式打开文件。
O_CREAT:如果文件不存在,则创建它。
O_EXCL:与 O_CREAT 一起使用,如果文件已存在,则返回错误。
O_TRUNC:如果文件存在,并且以写模式打开,则将文件长度截断为 0。
O_APPEND:以追加模式打开文件,写操作将追加到文件的末尾。

返回值:

  • 成功时,open 返回文件描述符(一个非负整数)。
  • 失败时,open 返回 -1,并设置 errno 以指示错误类型。

示例:(代码来自TCP/IP网络编程 尹圣雨(韩)p10)

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

void error_handling(char *message);

int main(void)
{
    int fd;
    char buf[] = "Let's go!\n";

    fd = open("data.txt", O_CREAT | O_WRONLY | O_TRUNC);
    if (fd == -1)
        error_handling("open() error!");

    printf("file descriptor: %d \n", fd);

    if (write(fd, buf, sizeof(buf)) == -1)
        error_handling("write() error!");

    close(fd);
    return 0;
}

void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

代码解析:

  • int fd;:定义一个文件描述符变量 fd。

  • char buf[100];:定义一个字符数组 buf,用于存储从文件中读取的数据。

  • fd = open(“data.txt”, O_RDONLY);:打开 data.txt 文件,以只读模式(O_RDONLY)打开。

  • 如果 open 函数返回 -1,表示打开文件失败,调用 error_handling 函数输出错误信息并终止程序。

  • printf(“file descriptor: %d \n”, fd);:输出文件描述符 fd。

  • if (read(fd, buf, sizeof(buf)) == -1):从文件中读取数据到 buf 中。

  • read 函数返回读取的字节数,如果返回 -1,表示读取失败,调用 error_handling 函数输出错误信息并终止程序。

  • printf(“file data: %s”, buf);:输出读取到的数据。

  • close(fd);:关闭文件描述符 fd。

fd = open("data.txt", O_CREAT | O_WRONLY | O_TRUNC);

代表文件打开模式,目录下无data.txt,所以将创建空文件,并只能写

if (write(fd, buf, sizeof(buf)) == -1)

向对应的fd中保存的文件描述符的文件传输buf中保存的数据

  • 在linux下运行结果:
    在这里插入图片描述

读取文件中的数据

#include <unistd.h>

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

此函数定义中,size_t 是通过 typedef 声明的 unsigned int 类型,对于 ssize_t 来说,size_t 前面多加的 s 代表 signed,即 ssize_t 是通过 typedef 声明的 signed int 类型

参数解释:

  • fd:文件描述符,表示要读取的打开文件。它是通过之前的 open 函数或其他函数(如 pipe)获得的。
  • buf:指向一个缓冲区的指针,读取的数据将被存储在这个缓冲区中。
  • count:要读取的字节数,指定从文件中最多读取多少字节的数据到缓冲区 buf 中。

返回值:

  • 成功时,返回读取的字节数(类型为 ssize_t),这可能小于 count,如果遇到文件结尾(EOF)。
  • 如果返回值是 0,表示已到达文件结尾。
  • 失败时,返回 -1,并设置 errno 以指示具体的错误类型。

代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

void error_handling(char *message);

int main(void)
{
    int fd;
    char buf[100];

    fd = open("data.txt", O_RDONLY);
    if (fd == -1)
        error_handling("open() error!");

    printf("file descriptor: %d \n", fd);

    if (read(fd, buf, sizeof(buf)) == -1)
        error_handling("read() error!");

    printf("file data: %s", buf);
    close(fd);
    return 0;
}

void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

代码解释:

  • int fd;:定义一个文件描述符变量 fd。

  • char buf[100];:定义一个字符数组 buf,用于存储从文件中读取的数据。

  • fd = open(“data.txt”, O_RDONLY);:打开 data.txt 文件,以只读模式(O_RDONLY)打开。

  • 如果 open 函数返回 -1,表示打开文件失败,调用 error_handling 函数输出错误信息并终止程序。

  • printf(“file descriptor: %d \n”, fd);:输出文件描述符 fd。

  • if (read(fd, buf, sizeof(buf)) == -1):从文件中读取数据到 buf 中。

  • read 函数返回读取的字节数,如果返回 -1,表示读取失败,调用 error_handling 函数输出错误信息并终止程序。

  • printf(“file data: %s”, buf);:输出读取到的数据。

  • close(fd);:关闭文件描述符 fd。

以上为文件描述符的I/O操作相关的介绍,该内容同样适用于套接字

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值