Re: BUG REPORT: CStdioFile::GetLength() and unix-style text files
On 19 nov, 16:15, Dave Calkins <DaveCalk...@discussions.microsoft.com>
wrote:
Not sure if this is the best place to report this or not. If we should=
be
sending this elsewhere, please notify and we'll do that.
We've discovered that when reading unix-style text files (i.e. files usin=
g
LF to terminate lines instead of CR LF), CStdioFile::GetLength() can caus=
e
problems. Specifically, during the below read loop, the call to
CStdioFile::GetLength() appears to disturb the file pointer at times, cau=
sing
it to backup in the file to previously read content.
CStdioFile fp;
fp.Open("file",CFile::modeRead);
CString line;
while (fp.ReadString(line))
{
// do stuff with the read line
fp.GetLength();
}
For a sample file, we observed the above loop correctly reading the first=
8
lines, however, when calling ReadString() to read the 9th line, it had ba=
cked
up to a place in the middle of the lines 2 lines prior. Interestingly,=
the
terminator (LF) for the 8th line happened to occur at offset 255 in the f=
ile.
Simply removing the call to CStdioFile::GetLength() eliminated the proble=
m
and the entire file was read correctly.
If you examine the source for CStdioFile::GetLength(), you'll see it does
some seeking in the file. So apparently, this is causing problems.
The solution was to simply call CStdioFile::GetLength() only once,
immediately after the file was opened, before any reading was done. By
calling it only once and then just using that value in the loop (it was b=
eing
used to update a progress bar), the code works fine.
We're using MSVC++ 2005 SP1. The source we have in our install path fo=
r the
GetLength() method is shown below for reference.
---
ULONGLONG CStdioFile::GetLength() const
{
ASSERT_VALID(this);
LONG nCurrent;
LONG nLength;
LONG nResult;
nCurrent = ftell(m_pStream);
if (nCurrent == -1)
AfxThrowFileException(CFileException::invalidFile, _d=
oserrno,
m_strFileName);
nResult = fseek(m_pStream, 0, SEEK_END);
if (nResult != 0)
AfxThrowFileException(CFileException::badSeek, _doser=
rno,
m_strFileName);
nLength = ftell(m_pStream);
if (nLength == -1)
AfxThrowFileException(CFileException::invalidFile, _d=
oserrno,
m_strFileName);
nResult = fseek(m_pStream, nCurrent, SEEK_SET);
if (nResult != 0)
AfxThrowFileException(CFileException::badSeek, _doser=
rno,
m_strFileName);
return nLength;
}- Ocultar texto de la cita -
- Mostrar texto de la cita -
Just a comment:
I'm not sure I would call that a bug.
I guess that CStdioFile assumes the files are Windows-Style, not Unix-
Style. In that case, it would be normal it had problems reading unix-
style files. It doesn't read Unicode text files either, and I guess it
doesn't read anything not windows-style well.