我的学校给了一个小图书馆来做一些项目。这个库是用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在有换行符时返回错误号码的建议?
答案 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);