我在努力做两件事:从一个文件描述符读入一个结构体,然后我需要读入一个内存位置。对于第一个,我使用fread。对于第二个,我使用read from unistd. h。 有没有什么方法可以做到这两点,而不需要像这样使用fopen,fclose,open,close和repeating?我可以使用“read”来读入一个结构体吗?
/**
* @brief Opens the file whose name is the string pointed to
* by file_name and associates a stream with it.
* @return A file descriptor corresponding to the stream on success,
* -1 elsewise.
*/
static int open_sesame (FILE *stream, const char *file_name)
{
stream = fopen (file_name, "r");
if (!stream) {
perror ("fopen()");
/* Handle error here */
return -1;
}
/* On failure, -1 is returned and errno is set to indicate
* the error.
*/
int fd = fileno (stream);
if (fd == -1) {
perror ("fileno()");
/* Handle error here */
return -1;
}
return fd;
}
这也可以做到:
/* read() will return -1 and set errno to EBADF¹
* if fileno() fails.
*/
if (read (fileno (fp), ..., ..., ...) == -1) {
perror ("read()");
/* Handle error here */
}
/* Upon successful completion, fdopen() shall return
* a pointer to a stream; otherwise, a null pointer
* shall be returned and errno set to indicate the
* error.
*/
FILE *stream = fdopen (fd, "r");
if (!stream) {
perror ("fdopen()");
/* Handle error here */
}
3条答案
按热度按时间doinxwow1#
调用
fopen()
后,可以通过fileno()
获取文件指针的文件描述符,如下所示:然后你可以直接使用
read
。事实上,fopen()
和open()
都为进程打开一个文件,前者返回一个指向文件的指针,而后者返回文件描述符。FILE
类型只是一个struct
,它有一个字段记录底层文件描述符。换句话说,在类Unix系统上,
fopen()
是使用open()
实现的,因此必须有一种方法同时使用这两个调用。注意,在我的系统(wsl2)上,
FILE
的定义可以在路径/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h
下找到,如下所示:cpjpxq1n2#
是的,当然你可以把数据(这里是字符串)读入一个结构体:
b1uwtaje3#
回复:有没有什么方法可以做到这两点,而不需要像这样重复fopen、fclose、open、close?
可以。您可以使用
fileno()
获取与FILE *
对应的文件描述符。从手册页中可以看到:函数fileno()检查参数流,并返回用于实现该流的整数文件描述符,该文件描述符仍然归stream所有,并将在fclose(3)被调用时关闭。
例如:
这也可以做到:
另一方面,如果您想打开对应文件描述符的流,则可以使用
fdopen()
。fdopen()函数应将流与文件描述符关联。
电话示例:
或者,正如@Fe203所建议的,如果需要两份数据,可以使用标准的
memcpy()
,而不是两次读取文件;或者,如果已经在使用POSIX系统调用,则使用mmap()
将文件Map到内存并使用它可能会更高效。[1]-
EBADF
:fd
不是有效的文件描述符或未打开以供读取。