c-如何读取块设备直到最后一个字节



我想读取一个块设备文件,逐块读取,直到最后一个字节,即使块中充满了零。我的代码是这样的。size是我希望它一次读取的字节数,可以是4K、8K等。

for (int i = 1; i <= num; i++){
read_bytes = read(fd, buf, size);
if (read_bytes < 0) {
perror("read failed");
return 1;
}
lseek_offset = lseek(fd, size, SEEK_CUR);
if (lseek_offset < 0){
perror("lseek failed.n");   
return 1;
}
}

当一个块填充了零个字节(不是块的长度,而是块中的数据(时,lseek会因EINV而失败。我可以从df -h中看到,这个磁盘是半满的,其余的是零字节,因为它在使用之前是用ext4格式化的

正如@Mat在注释中提到的,read已经更新了文件偏移量,因此您应该删除lseek调用。来自read(2)手册页:

在支持查找的文件上,读取操作从当前文件偏移量开始,文件偏移量按读取的字节数递增。如果当前文件偏移量位于或超过文件末尾,则不会读取任何字节,并且read((返回零。

还要注意,read调用可能会由于中断而失败,因此您应该检查errno的值(我猜您仍然希望继续阅读(。

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
for (int i = 1; i <= num; i++) {
read_bytes = read(fd, buf, size);
if (read_bytes < 0 && errno != EINTR) {
perror("read failed");
return 1;
}
}

最后,请注意,不能保证一次性读取size字节数(请参阅read(2)(,这很可能是因为信号中断。这是我的一个想法。您可以在for循环的一次迭代中检查while循环中的文件大小,以确定您还需要读取多少。例如:

for (int i = 1; i <= num; i++) {
size_t remain = size;
while(remain) {    // keep reading until you've read size bytes
read_bytes = read(fd, buf, remain);
if (read_bytes < 0 && errno != EINTR) {
perror("read failed");
return 1;
}
....           // determine the amount of bytes read in the last iteration
remain = ...   // update the size to the bytes still needed to be read
}                  
}

相关内容

最新更新