2011-11-28 330 views
1

我正在运行一个windows C++多线程应用程序,其中服务器类的一个实例/线程附加到该文件。其他线程运行客户端实例,它们仅在每个客户端启动时才加载文件 。 当我在加载文件结束时的2k字节范围内时,我检查文件的大小是否已更改为 ,因此我知道要更新要读取的总字节数。偶尔文件大小 我回来错误地被确定为零(0)。我正在使用下面的统计调用。当返回零时,然后作为完整性检查,然后调用getFileSizeWithTellg()以查看它返回的内容,并返回预期的非零值。与初始值相同或更大的值。 我意识到,转换为无符号整数可能会有问题,但文件不会大于5毫比特大小的文件是 。为什么stat()调用返回文件大小为零的错误值(0)?

什么可能导致stat()调用返回一个零值,当..Tellg调用不? 感谢您对此的任何洞察。

/

/ snippets from methods in different classes 
// 
// from client class 
ifstream fileSeqIn 
fileSeqIn.open(fName.c_str(), ios::in | ios::binary |ios::ate); 
// to get initial size 
size = fileSeqIn.tellg(); 
fileSeqIn.seekg(0, ios::beg); 


// later to determine if the file has grown 
struct stat filestatus; 
unsigned int size; 
if (stat(fName, &filestatus) == 0) { 
    size = (unsigned int)filestatus.st_size; 
} 

// 
unsigned int getFileSizeWithTellg(char *fname) 
{ 
    // get length of file 
    is.open (fname, ios::binary); 
    is.seekg (0, ios::end); 
    length = is.tellg(); 
    is.close(); 
    return(length); 
} 


//----------------------------------------------------------------------------- 
// from server class 
ofstream fileSeqOut; 
fileSeqOut.open(fName.c_str(), ios::app | ios::out |ios::ate |ios::binary); 

回答

1

一个显著差异:stat返回文件大小的系统的视图; tellg返回流的内部状态的值依赖。文件库流会被缓冲,并且在刷新或关闭文件之前,数据可能不会传递到系统。如果您在调用stat之前刷新了数据流,您是否也获得了相同的区别?

+0

更具体一点:stat()调用返回FindFirstFileEx返回的文件大小 - 这个信息在文件关闭之前是不可靠的。 –

+0

这是相当随机的。但写完后我并没有脸红。但现在我是。另外,在负载开始时,我使用tellg。当我接近尾声时,我使用统计信息,因为它不会更改文件指针位置,而我需要移动到文件的ed,然后调用tellg并将其重新定位到我所在的位置,这只是更多一点的代码。但这可能是一条路。在书写线上的每次写入都应该正常工作后,请结合冲洗。正确? –

+0

如果您想获得关于文件状态的准确信息并且拥有文件句柄,请调用使用句柄的API,而不是使用文件名的API。通常,使用文件名的API将比使用句柄的API更准确(句柄总是反映文件状态的最新文件系统度量)。 –

1

如果拉里奥斯特曼说是真的,使用GetFileInformationByHandle可能会解决问题。

+1

您或任何其他人都可以通过在MSVS安装目录中的某处检查“crt-src \ stat.c”来验证Osterman先生是否确实说出了真相。 – user786653

+0

我没有看到奥斯特曼先生的评论。他们在哪? –

+0

One * minor *使用GetFileInformationByHandle注意 - 我相信它需要为FILE_QUERY_INFORMATION访问打开文件 - 如果您打开GENERIC_READ文件,这将毫无问题地工作,但是如果您只打开GENERIC_WRITE文件,它就会获得“T。 –

相关问题