当我们使用文件描述符进行操作时,需要操作标准输入、标准输出、标准错误,可以包含如下头文件:
#include <unistd.h>
这个头文件中定义了标准设备:
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
任意一个进程在启动时都会初始化对应的标准设备,他们对应的文件描述符就是0,1,2。
标准输出可以使用重定向符号>进行重定向,标准错误也可以重定向到标准输出中。
ls > log.txt 2>&1
示例:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
char buf[10];
int n;
while((n = read(STDIN_FILENO, buf, 10)) > 0) {
if (write(STDOUT_FILENO, buf, n) != n) {
perror("Write Failed");
exit(1);
}
}
if (n < 0) {
perror("Read Failed");
exit(2);
}
return 0;
}
标准IO库中的文件操作,涉及到FILE文件流格式的标准输入,标准输出和标准错误:
#include <stdio.h>
这个头文件定义了如下的标准设备:
typedef struct _IO_FILE FILE;
/* Standard streams. */
extern struct _IO_FILE *stdin; /* Standard input stream. */
extern struct _IO_FILE *stdout; /* Standard output stream. */
extern struct _IO_FILE *stderr; /* Standard error output stream. */
因此只要包含了该文件,我们可以直接使用stdin、stdout,stderr来使用。
示例:
#include <stdio.h>
int main(int argc, char *argv[])
{
char buf[10];
int n;
while((n = fread(buf, 1, 10, stdin)) > 0) {
printf("fread return n:%d\n", n);
if (fwrite(buf, 1, n, stdout) != n) {
perror("fwrite failed");
exit(1);
}
}
if (n < 0) {
perror("fread failed");
exit(2);
}
return 0;
}
我们需要清楚的一点就是,使用标准IO库的读写操作,内部实现是包含缓冲区的,所以这里我们读10个字节,如果仅仅输入8个是不会写入到标准输出的,只有当达到10个字节才会写入。
$ ./iostream
123456789
fread return n:10
123456789
123456
789
fread return n:10
123456
789