阅读windows文件; _stat返回不正确的值

时间:2011-10-31 22:20:07

标签: c++ windows file mingw newline

我的学校给了一个小图书馆来做一些项目。这个库是用linux编写的,所以我试图改变一些东西来使用我的MinGW编译器。一个特定的程序用于读取给定URL的文件。我不得不将stat更改为_stat以使其正常工作。打开文件工作正常,但_stat似乎返回不正确的值。我将在下面提供相关代码:

#ifdef WIN32
    #define stat _stat
#endif

    //return true if the number of chars read is the same as the file size
bool IsDone() const
{
    cout << "checking if numRead " << numRead << " is fileSize " << fileSize << endl;
    return (numRead == fileSize);
}

char Read()
{
    if (IsDone())
        throw IllegalStateException("stream is done");
    else
    {
        char c;
        file.get(c);
        cout << "reading: " << c << endl;
        if (file.fail())
            throw FileException(std::string("error reading from file ") + fileName);

        ++numRead;
        return c;
    }
}

void OpenFile(string fileName)
{
    struct stat buf;
    #ifdef WIN32
        if (_stat(fileName.c_str(), &buf) < 0){
            switch (errno){
                case ENOENT:
                  throw FileException(std::string("Could not find file ") + name);
                case EINVAL:
                    throw FileException(std::string("Invalid parameter to _stat.\n"));
                default:
                  /* Should never be reached. */
                    throw FileException(std::string("Unexpected error in _stat.\n"));
            }
        }
    #else
        if (stat(fileName.c_str(), &buf) < 0)
            throw FileException(std::string("could not determine size of file ") + fileName);
    #endif
        fileSize = buf.st_size;
        file.open(fileName.c_str());
}

如果您想查看整个图书馆,可以从here获取。我知道代码看起来很糟糕;我只是试图破解一个正在运行的Windows版本。这个东西在Linux上工作正常;问题是,当我在Windows上读取文件时,我在输入文件中使用的每个换行的大小都是1,所以如果我有一个看起来像这样的文件:

 text

它工作正常,但是:

text\r\n

它断开了,输出看起来像这样:

checking if numRead 0 is fileSize 6
checking if numRead 0 is fileSize 6
reading: t
checking if numRead 1 is fileSize 6
checking if numRead 1 is fileSize 6
reading: e
checking if numRead 2 is fileSize 6
checking if numRead 2 is fileSize 6
reading: x
checking if numRead 3 is fileSize 6
checking if numRead 3 is fileSize 6
reading: t
checking if numRead 4 is fileSize 6
checking if numRead 4 is fileSize 6
reading:

checking if numRead 5 is fileSize 6
checking if numRead 5 is fileSize 6
reading:
File Error: error reading from file H:/test/data/stuff.txt

它因为IsDone()错误地返回false(没有双关语)而中断,并且程序试图读取超过文件末尾的内容。有关为什么_stat在有换行符时返回错误号码的建议?

2 个答案:

答案 0 :(得分:2)

_stat返回的内容非常正确。 Windows使用“\ r \ n”来表示行的结尾,但是当您以文本模式打开文件时,在读取流时,该文件将转换为单个换行符。

如果您希望所读取的流与外部长度匹配,请改为以二进制模式打开文件。

如果你原谅我这么说,那么一旦你完成了这个,我的建议是抛弃这些代码,改变你的名字,这样如果有人看到你的帖子,他们就不会责怪你。你在这里有很多代码,至少在我看来,使一项简单的任务变得更加复杂和困难。

答案 1 :(得分:1)

在我看来你应该用二进制模式打开文件。不知道为什么你需要使用stat来读取文件,在你的代码的Windows版本中,你再次调用_stat然后调用stat。

在Windows中有几种​​方法可以做到这一点。我个人的偏好是使用类似的东西:

char strBuffer[1024];

FILE *fp = fopen (file,"rb");  // Binary read mode
while (!feof (fp))
   fread (strBuffer,1,sizeof (strBuffer),fp);

fclose (fp);