二进制读取器在读取确切的字节数时未触发eof位

Binary reader not triggering eof bit when reading exact number of bytes

本文关键字:读取 eof 二进制 字节数      更新时间:2023-10-16

我正在使用以下代码将图像写入二进制文件:

std::ofstream edgefile("C:\****\edge.bin", std::ofstream::binary | std::ofstream::app | std::ofstream::out);
Mat edges;
    Canny(bilat, edges, cthr1, cthr2, 3); //cany sliders
    if (writeedge){
        int rows = edges.rows;
        int cols = edges.cols;
        edgefile.write(reinterpret_cast<const char *>(&rows), sizeof(int));
        edgefile.write(reinterpret_cast<const char *>(&cols), sizeof(int));
        edgefile.write(reinterpret_cast<char*>(edges.data), edges.rows*edges.cols*sizeof(uchar));
        cout << "writen r:" << rows << "C: " << cols << "Bytes: " << edges.rows*edges.cols*sizeof(uchar) << endl;
    }

然后用这个读取相同的图像:

std::ifstream infile;
int main(int argc, char* argv[])
{
    int * ptr;
    ptr = new int;
    int rows;
    int cols;
    infile.open("C:\****\edge.bin", std::ofstream::binary | std::ofstream::app | std::ofstream::in);
    while (!infile.eof())
    {
            infile.read(reinterpret_cast<char*>(ptr), sizeof(int));
            rows = *ptr;
            infile.read(reinterpret_cast<char*>(ptr), sizeof(int));
            cols = *ptr;
            Mat ed(rows, cols, CV_8UC1, Scalar::all(0));
            infile.read(reinterpret_cast<char*>(ed.data), rows * cols * (sizeof uchar));
            cout << "writen r: " << rows << " C: " << cols << " Bytes: " << rows * cols * (sizeof uchar) << endl;
            imshow("God Knows", ed);
            cvWaitKey();        
    }
    infile.close();
    return 0;
}

图像被准确地读取,但是在末尾没有触发eof位,因此乘以最后一个ptr值并在末尾读取另一个空白图像。在此之后,循环结束。如何在不重置当前读取位置的情况下检查下一位是否为EOF位?

(我知道如果再读取1个字节,就会触发EOF位)

EOF位是在您试图读取文件末尾之后设置的,这就是流的工作方式。

您可以很容易地重组主循环,以检查第一次读取后的状态。这是因为read的返回值是对流的引用,并且将引用强制转换为bool会检查流是否仍处于良好状态(即没有EOF)。

while (infile.read(reinterpret_cast<char*>(ptr), sizeof(int)))
{
    // ...