linux文件读取程序,Linux系统编程:文件的读取写入

本文详细介绍了Linux系统中的read、write、ioctl和lseek四个关键系统调用。read用于从文件中读取数据,write用于写入数据,ioctl用于发送控制命令和配置设备,lseek用于实现文件的随机访问。通过这些调用,开发者可以灵活地对文件进行读写操作,并实现对设备的控制和文件定位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、read系统调用

一旦有了与一个打开文件描述相关连的文件描述符,只要该文件是用O_RDONLY或O_RDWR标志打开的,就可以用read()系统调用从该文件中读取字节

函数原型:

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

参数:

fd :想要读的文件的文件描述符

buf : 指向内存块的指针,从文件中读取来的字节放到这个内存块中

count : 从该文件复制到buf中的字节个数

返回值:

如果出现错误,返回-1;读文件结束,返回0;否则返回从该文件复制到规定的缓冲区中的字节数

二、write系统调用

用write()系统调用将数据写到一个文件中

函数原型:

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

函数参数:

fd:要写入的文件的文件描述符

buf: 指向内存块的指针,从这个内存块中读取数据写入 到文件中

count: 要写入文件的字节个数

返回值:如果出现错误,返回-1;如果写入成功,则返回写入到文件中的字节个数

三、ioctl 函数

ioctl用于向设备发控制和配置命令,有些命令也需要读写一些数据,但这些数据是不能用read/write读写的,称为Out-of-band数据。也就是说,read/write读写的数据是in-band数据,是I/O操作的主体,而ioctl命令传送的是控制信息,其中的数据是辅助的数据。例如,在串口线上收发数据通过read/write操作,而串口的波特率、校验位、停止位通过ioctl设置,A/D转换的结果通过read读取,而A/D转换的精度和工作频率通过ioctl设置。

#include

int ioctl(int d, int request, ...);

d是某个设备的文件描述符。request是ioctl的命令,可变参数取决于request,通常是一个指向变量或结构体的指针。若出错则返回-1,若成功则返回其他值,返回值也是取决于request。

以下程序使用TIOCGWINSZ命令获得终端设备的窗口大小。

#include

#include

#include

#include

int main(void)

{

struct winsize size;

if (isatty(STDOUT_FILENO) == 0)

exit(1);

if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &size) < 0)

{

perror("ioctl TIOCGWINSZ error");

exit(1);

}

printf("%d rows, %d columns\n", size.ws_row, size.ws_col);

return 0;

}

四、文件的随机读写

到目前为止的所有文件访问都是顺序访问。这是因为所有的读和写都从当前文件的偏移位置开始,然后文件偏移值自动地增加到刚好超出读或写结束时的位置,使它为下一次访问作好准备。

有个文件偏移这样的机制,在Linux系统中,随机访问就变得很简单,你所需做的只是将当前文件偏移值改变到有关的位置,它将迫使下一次read()或write()发生在这一位置。(除非文件打开时标志有 O_APPEND,在这种情况下,任何write调用仍将发生在文件结束处)

lseek系统调用:

功能说明:通过指定相对于开始位置、当前位置或末尾位置的字节数来重定位,这取决于 lseek() 函数中指定的位置

函数原型:off_t lseek (int  fd,    off_t offset,   int base);

函数参数:

fd:需要设置的文件描述符

offset:偏移量

base:偏移基位置

返回值:返回新的文件偏移值

base 表示搜索的起始位置,有以下几个值:(这些值定义在)

base文件位置

SEEK_SET 从文件开始处计算偏移

SEEK_CUR 从当前文件的偏移值计算偏移

SEEK_END 从文件的结束处计算偏移

注意:管道和socket是不能lseek的,否则返回ESPIPE错误(Invalid seek)。

示例程序如下:

#include

#include

#include

#include

#include

#include

#include

#include

#define ERR_EXIT(m) \

do { \

perror(m); \

exit(EXIT_FAILURE); \

} while(0)

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

{

int infd;

int outfd;

if (argc != 3)

{

fprintf(stderr, "Usage %s src dest\n", argv[0]);

exit(EXIT_FAILURE);

}

infd = open(argv[1], O_RDONLY);

if (infd == -1)

ERR_EXIT("open src error");

if ((outfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0664)) == -1)

ERR_EXIT("open dest error");

char buf[1024];

ssize_t nread;

while ((nread = read(infd, buf, 1024)) > 0)

write(outfd, buf, nread); // 可以调用fsync同步内核缓冲区的数据到磁盘文件

// 或者打开文件时标志为O_SYNC

close(infd);

close(outfd);

/********************************************************************************************/

infd = open("test.txt", O_RDONLY);

if (infd == -1)

ERR_EXIT("open error");

char buf2[1024] = {0};

int num = read(infd, buf2, 5);

if (num == -1)

ERR_EXIT("read error");

num = lseek(infd, 0, SEEK_CUR); // 从当前位置偏移0个字节

if (num == -1)

ERR_EXIT("lseek");

printf("current offset=%d\n", num);

outfd = open("dest.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);

if (outfd == -1)

ERR_EXIT("open error");

write(outfd,buf2, 5);

close(infd);

close(outfd);

return 0;

}

struct stat

结构体中的

文件长度对应st_size字段,而文件使用的块大小对应st_blksize字段,占用块数对应st_blocks字段。 大部分情况下面,st_size和st_blksize*st_blocks应该是很接近的,除非一种情况就是文件空洞。 一般对应于空洞文件来说,st_size可能很大,而实际占用磁盘空间却很少。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值