fseek文件定位和open 、read、 write函数

在 C 语言中,fseekftell 和 rewind 是用于文件操作的标准库函数,它们帮助管理文件流的位置。下面是对这些函数的详细介绍和示例。

1. fseek 函数

函数原型:

int fseek(FILE *stream, long offset, int whence);

参数:

  • stream:指向 FILE 结构体的指针,表示文件流。
  • offset:要移动的字节数。
  • whence:位置标志,指定从哪里开始移动,常用的值有:
    • SEEK_SET:从文件开头开始移动。
    • SEEK_CUR:从当前位置开始移动。
    • SEEK_END:从文件末尾开始移动。

返回值:

  • 成功时,返回 0。
  • 失败时,返回 -1,并设置 errno。

功能: 用于设置文件流的位置指针,使其指向指定的位置。

示例:

#include <stdio.h>

int main() {
    FILE *file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("fopen");
        return 1;
    }

    // 将文件位置指针移动到文件开头
    if (fseek(file, 0, SEEK_SET) != 0) {
        perror("fseek");
        fclose(file);
        return 1;
    }

    // 将文件位置指针移动到文件的第 10 个字节处
    if (fseek(file, 10, SEEK_SET) != 0) {
        perror("fseek");
        fclose(file);
        return 1;
    }

    fclose(file);
    return 0;
}

2. ftell 函数

函数原型:

long ftell(FILE *stream);

参数:

  • stream:指向 FILE 结构体的指针,表示文件流。

返回值:

  • 成功时,返回当前位置的字节偏移量。
  • 失败时,返回 -1L,并设置 errno。

功能: 返回文件流当前位置的偏移量,即从文件开头到当前位置的字节数。

示例:

#include <stdio.h>

int main() {
    FILE *file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("fopen");
        return 1;
    }

    // 将文件位置指针移动到文件的第 10 个字节处
    if (fseek(file, 10, SEEK_SET) != 0) {
        perror("fseek");
        fclose(file);
        return 1;
    }

    // 获取当前位置
    long position = ftell(file);
    if (position == -1L) {
        perror("ftell");
        fclose(file);
        return 1;
    }

    printf("Current position: %ld\n", position);

    fclose(file);
    return 0;
}

3. rewind 函数

函数原型:

void rewind(FILE *stream);

参数:

  • stream:指向 FILE 结构体的指针,表示文件流。

功能: 将文件流的位置指针重置到文件的开头,相当于执行 fseek(stream, 0, SEEK_SET)

示例:

#include <stdio.h>

int main() {
    FILE *file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("fopen");
        return 1;
    }

    // 将文件位置指针移动到文件的第 10 个字节处
    if (fseek(file, 10, SEEK_SET) != 0) {
        perror("fseek");
        fclose(file);
        return 1;
    }

    // 重置文件位置指针到文件开头
    rewind(file);

    // 获取当前位置
    long position = ftell(file);
    if (position == -1L) {
        perror("ftell");
        fclose(file);
        return 1;
    }

    printf("Current position after rewind: %ld\n", position);

    fclose(file);
    return 0;
}

总结

  • fseek:用于设置文件流的当前位置指针,可以移动到文件的任意位置。
  • ftell:用于获取当前文件流的位置指针,相对于文件开头的字节偏移量。
  • rewind:将文件流的位置指针重置到文件开头,相当于 fseek(stream, 0, SEEK_SET)

这些函数使得文件操作更加灵活,允许在文件中随机访问数据并进行位置管理。

 在文件 I/O 中,openclosewrite 和 read 是用于文件操作的基本函数。它们通常在 POSIX 标准下使用,特别是在 Unix 和 Linux 系统中。下面是对这几个函数的详细介绍及使用方法。

1. open 函数

函数原型:

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

参数:

  • pathname:要打开的文件的路径名。
  • flags:打开文件的标志,决定文件的打开模式(如只读、只写等)。
  • mode:指定文件的权限(在创建新文件时使用)。

返回值:

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

常见的 flags

  • O_RDONLY:以只读方式打开。
  • O_WRONLY:以只写方式打开。
  • O_RDWR:以读写方式打开。
  • O_CREAT:如果文件不存在,则创建文件。
  • O_TRUNC:如果文件存在且以写入方式打开,则清空文件。

示例:

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

int main() {
    int fd = open("example.txt", O_CREAT | O_WRONLY, 0644);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    // 进行文件操作

    close(fd);  // 关闭文件
    return 0;
}

2. close 函数

函数原型:

int close(int fd);

参数:

  • fd:要关闭的文件描述符。

返回值:

  • 成功时,返回 0。
  • 失败时,返回 -1,并设置 errno。

示例:

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

int main() {
    int fd = open("example.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    // 进行文件操作

    if (close(fd) == -1) {
        perror("close");
        return 1;
    }

    return 0;
}

3. write 函数

函数原型:

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

参数:

  • fd:要写入的文件描述符。
  • buf:指向要写入数据的缓冲区。
  • count:要写入的字节数。

返回值:

  • 成功时,返回实际写入的字节数。
  • 失败时,返回 -1,并设置 errno。

示例:

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

int main() {
    int fd = open("example.txt", O_CREAT | O_WRONLY, 0644);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    const char *text = "Hello, World!\n";
    ssize_t bytes_written = write(fd, text, 14);
    if (bytes_written == -1) {
        perror("write");
        close(fd);
        return 1;
    }

    close(fd);
    return 0;
}

4. read 函数

函数原型:

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

参数:

  • fd:要读取的文件描述符。
  • buf:指向存储读取数据的缓冲区。
  • count:要读取的字节数。

返回值:

  • 成功时,返回实际读取的字节数(可能小于 count,如果到达文件末尾)。(这个值一般都需要用到,记住它的含义,时读时写,和write函数配合使用,读多少,我就写多少)
  • 读完时,返回 0。
  • 失败时,返回 -1,并设置 errno。

示例:

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

int main() {
    int fd = open("example.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    char buffer[100];//
    ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
    if (bytes_read == -1) {
        perror("read");
        close(fd);
        return 1;
    }

    buffer[bytes_read] = '\0';  // 添加字符串结束符
    printf("Read: %s", buffer);

    close(fd);
    return 0;
}

注意事项

  1. 错误处理: 始终检查 openclosewrite 和 read 的返回值,以处理可能出现的错误。
  2. 文件权限: 使用 mode 参数时,要确保设置正确的文件权限,以允许合适的读/写操作。
  3. 缓冲区: 在 read 和 write 操作时,确保缓冲区足够大,以存储所需的数据。
  4. 文件描述符: 每次打开文件时,系统会分配一个新的文件描述符。确保在使用后关闭文件描述符,以避免资源泄漏。

通过使用这些函数,可以在 C 语言中进行文件的读写操作,确保能够正确管理和操作文件。

练习:复制功能(重要)

使用open、close、read、write函数完成复制函数。

#include <stdio.h> 
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, const char *argv[])
{
	if(argc<3)
	{
		fprintf(stderr, "input ./a.out 1 2\n");//注意输入的规范  类似于 cp 1.txt 2.txt
		return 1;
	}
	int fd = open(argv[1],O_RDONLY);
	int dest = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0666);

	if(-1==fd||-1==dest)//这里有个小细节,常数写左边,如果你少输入一个=,则会报错,常数在右边就是正常赋值,不会报错,但会使结果异常,左值必须是变量,不可以是常数。
	{
		fprintf(stderr, "open error\n");
		return 1;
	}

	while(1)
	{
		char buf[1024] = {0};//每次循环都要清空,不可以在while外面,要不然传了一次下一次还是会传上一次buf内的内容
		int ret = read(fd,buf,sizeof(buf));
		if(ret<=0)//文件读完ret=0;读取出错ret=-1;反正都是结束程序,一块处理  
		{
			break;
		}
		int ch = write(dest,buf,ret);//一定要read函数读完返回值判断完,读取成功,才可以写入,而且每次写入的内容都是read返回值大小(返回值为读到有效字节数),时读时传,这样就可以传二进制文件和文本文件都能传。
		if(ch==-1)
		{
			fprintf(stderr, "write error\n");
			return 1;
		}
	}
	close(fd);
	close(dest);//打开使用完别忘记关闭
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值