read() 在读取来自标准输入的所有文本之前返回 0

问题描述 投票:0回答:1

我正在做一项作业,我必须接受来自标准输入的输入并将其写入文件。要求之一是在任何给定时间保持较低的内存使用量并使用 read() 来做到这一点。我正在使用大小为 4096 的缓冲区,其想法是,将调用 read() 直到缓冲区已满,然后调用 write() 直到缓冲区完全写入文件,然后该过程继续进行读取从它停止的地方开始覆盖缓冲区,直到 a) 用户设置的内容长度(以字节为单位)已被写入或 b) 已到达 stdin 内容的末尾。我遇到了一个问题,read 只能读取 4095 字节,此时它将返回 0,并且只能返回 0。我已经阅读了 read 的手册页,并了解到当达到 EOF 时会返回 0,所以我不知道为什么 read() 返回 0。

void executeSetCommand(const char *filename, int contentLength) {
   int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
   if (fd == -1) {
       fprintf(stderr, "Operation Failed fd -1 line 44 \n");
       exit(15);
   }

   char buffer[4096];
   ssize_t bytesRead = 0;
   ssize_t bytesWrote = 0;
   ssize_t totalWritten = 0; // Total bytes written so far
   ssize_t toWrite; // Bytes to write in the current iteration
   int loopcounter = 0;


   while (totalWritten < contentLength) {
       loopcounter++;
       fprintf(stderr, "loopcounter %d, \n", loopcounter);
       // Read up to the size of the buffer or whatever is left to read to meet contentLength
       fprintf(stderr, "totalwritten: %zd\n", totalWritten);
       ssize_t maxReadSize = min((size_t) sizeof(buffer), (size_t) contentLength - totalWritten);
       fprintf(stderr, "Max Read Size: %zd \n", maxReadSize);

       //the offending read call
       bytesRead = read(STDIN_FILENO, buffer, maxReadSize);

       fprintf(stderr, "bytesread: %zd \n", bytesRead);
       if (bytesRead < 0) {
           fprintf(stderr, " \nbytesRead <= 0 \n");
           // Handle read error or end of input
           break;
       }

       ssize_t bytesLeftToWrite = bytesRead; // Bytes left to write from the current read
       fprintf(stderr, "this is reached \n");
       while (bytesLeftToWrite > 0) {
           toWrite = bytesLeftToWrite; // Write all of the remaining bytes unless there's an error
           bytesWrote = write(fd, buffer, toWrite);
           fprintf(stderr, "\nbyteswrote: %zd\n", bytesWrote);
           if (bytesWrote <= 0) {
               fprintf(stderr, " \n bytesWrote <= 0 \n");
               // Handle write error
               break;
           }


           bytesLeftToWrite -= bytesWrote; // Decrease the count of bytes left to write
           totalWritten += bytesWrote; // Update the total written bytes
       }


       if (totalWritten >= contentLength) {
           fprintf(stderr, "we think we have written >= contentlength");
           // If we have written up to contentLength, stop
           break;
       }
   }


   close(fd);
   fprintf(stdout, "OK\n");
}

此函数有效,当输入字符数少于 4096 时,将写入所有输入,但如果我输入 10000 作为内容长度并向 stdin 输入 12000 个字符的文本,该函数将仅写入前 4095 个字符,然后挂起因为 read 只会返回 0,从而阻止达到 contentlength。输入到 stdin 的内容中没有任何换行符。

c io
1个回答
0
投票

您使用的是具有 4096 个空间的 char 数组,这意味着您不能在其中放入超过 4096 个字符作为缓冲区

将其视为您为自己购买的一个小玻璃杯,现在您正在努力用一桶水将其装满。

© www.soinside.com 2019 - 2024. All rights reserved.