所以,我环顾四周,但找不到一个从文件末尾删除字节而不重写整个文件的方法。 我发现truncate
函数适用于Linux,但没有find任何东西的Windows。 现在,显然,扩展一个文件,我可以用空字节来填充结尾,但是为了减小文件的大小,是否有必要在Windows上重写整个文件? 或者有一个函数,也许在windows.h
,允许我像在Linux上truncate
,重新分配一个文件的大小?
编辑:我只是find函数_chdir(int,long)
,我正在阅读如何使用它。
编辑:而且,为什么fstream
离开这个重要的function呢?
编辑:好的,所以它似乎_chdir()
将无法正常工作(我忘了提及这一点,顺便说一句),因为该function必须支持大于4 GB的文件 – 即,我正在使用64位文件指针。 我认为这是固有的,但在阅读chsize
的参数后,长度不是size_t
。
通过调用SetFilePointer
或SetFilePointerEx
到所需的位置,然后调用SetFilePointer
来截断文件。 下面显示了如何实现truncate
函数:
bool truncate( HANDLE hFile, LARGE_INTEGER NewSize ) { LARGE_INTEGER Size = { 0 }; if ( GetFileSizeEx( hFile, &Size ) ) { LARGE_INTEGER Distance = { 0 }; // Negative values move the pointer backward in the file Distance.QuadPart = NewSize.QuadPart - Size.QuadPart; return ( SetFilePointerEx( hFile, Distance, NULL, FILE_END ) && SetEndOfFile( hFile ) ); } return false; } // Helper function taking a file name instead of a HANDLE bool truncate( const std::wstring& PathName, LARGE_INTEGER NewSize ) { HANDLE hFile = CreateFileW( PathName.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if ( hFile == INVALID_HANDLE_VALUE ) { return false; } bool Success = truncate( hFile, NewSize ); CloseHandle( hFile ); return Success; }
编辑:较短的版本 truncate
函数可以缩短为以下内容:
bool truncate( HANDLE hFile, LARGE_INTEGER NewSize ) { return ( SetFilePointerEx( hFile, NewSize, NULL, FILE_BEGIN ) && SetEndOfFile( hFile ) ); }
如果您希望传递缩小文件的字节数,则可以使用以下实现:
bool truncate( HANDLE hFile, LARGE_INTEGER ShrinkBy ) { ShrinkBy.QuadPart = -ShrinkBy.QuadPart; return ( SetFilePointerEx( hFile, ShrinkBy, NULL, FILE_END ) && SetEndOfFile( hFile ) ); }
要生长文件,请使用包含dwDesiredAccess
使用CreateFile
打开文件。 再次使用SetFilePointer
将文件指针设置为文件末尾,然后可以写入调用WriteFile
新数据。 有关示例,请参阅将一个文件附加到另一个文件 。
编辑:生长一个文件,而不写入它
如果您不关心超出原始文件大小的文件内容,则可以应用与显示的截断文件相同的顺序来扩展它:
bool SetFileSize( HANDLE hFile, LARGE_INTEGER NewSize ) { return ( SetFilePointerEx( hFile, NewSize, NULL, FILE_BEGIN ) && SetEndOfFile( hFile ) ); }
这是SetEndOfFile
记录的行为:
SetEndOfFile函数可用于截断或扩展文件。 如果文件被扩展,文件的旧的结尾和文件的新结尾之间的文件内容没有定义。
您可能需要SetEndOfFile函数。
编辑:这应该与大于4GB的文件。 使用SetFilePointerEx函数。