这是我的代码段:
int fd;
bufsize = 30;
char buf[bufsize];
char cmd[100] = "file.txt";
int newfd = 1;
if (fd = open(cmd,O_RDONLY) >=0){
puts("wanna read");
while (read(fd,&bin_buf,bufsize)==1){
puts("reading");
write(newfd,&bin_buf,bufsize);
}
close(fd);
}
所以这里程序打印"wanna read"
但从不打印"reading"
。我也尝试使用nonblock标志打开,但没有用。有谁能够帮我?我必须仅使用open()
和read()
系统调用。谢谢。
编辑:我在代码中做了一些澄清。实际上我写的newfd是套接字描述符,但我不认为这对于这个问题很重要,因为它坚持read
之前的write
。
答案 0 :(得分:2)
第一个问题是你的if
声明。您忘记使用足够的括号,因此如果open()
有效,则读取尝试从文件描述符1(即标准输出)读取。如果这是你的终端(它可能是)在Unix机器上,那么它可行 - 虽然可能是令人惊讶的;该程序正在等待您输入内容。
修复:使用括号!
if ((fd = open(cmd, O_RDONLY)) >= 0)
分配是在比较之前而不是之后完成的。
我顺便观察到你没有展示你如何设置cmd
,但如果你看到'想要阅读'的消息,那一定是好的。您没有显示newfd
的初始化方式;也许那是1
。
您还遇到了“read()
调用返回的内容”的问题。你可能需要:
int fd;
char buf[bufsize];
int newfd = 1;
if ((fd = open(cmd, O_RDONLY)) >= 0)
{
puts("wanna read");
int nbytes; // ssize_t if you prefer
while ((nbytes = read(fd, buf, sizeof(buf))) > 0)
{
puts("reading");
write(newfd, buf, nbytes);
}
close(fd);
}
您可以通过原始if
键入某些内容('Surprise'或'终端文件描述符通常是可读写的'或其他内容)来演示我的主要观察结果,但我的循环体然后将其写入某处。< / p>
答案 1 :(得分:1)
read
返回从文件读取的字节数,如果必须读取的文件的剩余部分短于bufsize
,则可以是bufsize
或更少。
在你的情况下,很可能bufsize
大于1且文件大于1个字节,因此while循环的条件被评估为false,代码被跳过到文件关闭的位置。
您应该检查是否有更多要读取的字节:
while( read(fd,&bin_buf,bufsize) > 0 ) {
答案 2 :(得分:1)
您的read()
调用尝试读取bufsize
个字节并返回实际读取的字节数。除非bufsize ==
,否则read()
将不会返回1
,因此几乎总是会跳过该块,并且不会写入任何内容。
另请注意if (fd = open(cmd, O_RDONLY) >= 0)
不正确,并将fd
设置为1
,标准输出的句柄(如果文件存在),导致read
失败作为标准输入很可能无法阅读。
请注意,在某些环境中使用read
系统调用进行阅读非常棘手,因为-1
的返回值可以重新启动。
以下是改进版本:
int catenate_file(const char *cmd, int newfd, size_t bufsize) {
int fd;
char buf[bufsize];
if ((fd = open(cmd, O_RDONLY)) >= 0) {
puts("wanna read");
ssize_t nc;
while ((nc = read(fd, buf, bufsize)) != 0) {
if (nc < 0) {
if (errno == EINTR)
continue;
else
break;
}
printf("read %zd bytes\n", nc);
write(newfd, buf, nc);
}
close(fd);
return 0;
}
return -1;
}