在实际的开发过程中,我们可能需要在文件生成时就立即将文件更改为指定的大小,以便于后续简化对文件的并发操作,
这一点在各类的下载工具中有很好的体现。
要满足这一需求,通常可以使用的最直观的方式是:生成文件后,通过循环向文件中写入任意数据,直到文件大小达到预期的大小。
对于较小的文件,这种方法可以接受,但是如果文件大小过大,那么这种方法就显得不够简洁且低效。
这里介绍一种高效且简单的方法,基于函数"lseek"。
执行"man lseek"之后,我们可以看到关于lseek特性的关键信息,如下:
The lseek() function shall allow the file offset to be set beyond the end of the existing data in the file.
If data is later written at this point, subsequent reads of data in the gap shall return bytes with the
value 0 until data is actually written into the gap.
The lseek() function shall not, by itself, extend the size of a file.
简单的总结就是:
1. lseek 函数本身不会扩展文件的大小.
2. lseek 允许文件的偏移值超过文件的末端,如果下一次在这个偏移点写入数据,那么在偏移之前的文件末端与偏移点之间的数据将会自动填充为0。
了解了上面几点,大家应该想到了扩展文件大小将是一件多么简洁高效的事情了:)
//! @brief 扩展文件大小
boolEnlargeFile(intiFileHandle , off_t iNewSize )
{
if( ( iFileHandle<0)||( iNewSize<0) )
{
LOG_DEBUG_INFO("parameter for is not valid", iFileHandle , iNewSize );
returnfalse;
}
structstat fileState;
intiStatus=fstat( iFileHandle ,&fileState );
if(0!=iStatus )
{
LOG_DEBUG_INFO("invoke fail , ErrCode:%d , ErrMsg:%s", \
iFileHandle ,&fileState , errno , strerror( errno ) );
returnfalse;
}
constoff_t iCurSize=fileState.st_size;
if( iNewSize<=iCurSize )
{
LOG_DEBUG_INFO("new file size = %ld , current file size = %ld , can not resize file to smaller size.", \
iNewSize , iCurSize );
returnfalse;
}
constoff_t iCurPos=lseek( iFileHandle ,0, SEEK_CUR );//保存文件指针的当前位置以便于在扩展文件大小后恢复到当前位置
if( iCurPos<0)
{
LOG_DEBUG_INFO("invoke fail , ErrCode:%d , ErrMsg:%s", \
iFileHandle , errno , strerror( errno ) );
returnfalse;
}
constoff_t iMoveOffset=iNewSize-1;
iStatus=lseek( iFileHandle , iMoveOffset , SEEK_SET );
if( iStatus!=iMoveOffset )
{
LOG_DEBUG_INFO("invoke fail , ErrCode:%d , ErrMsg:%s", \
iFileHandle , iMoveOffset , errno , strerror( errno ) );
returnfalse;
}
constintWRITE_BYTE_COUNT=1;
iStatus=write( iFileHandle ,"", WRITE_BYTE_COUNT );//写入一个字节的数据,完成对文件大小的更改
if( iStatus!=WRITE_BYTE_COUNT )
{
LOG_DEBUG_INFO("invoke fail , ErrCode:%d , ErrMsg:%s", \
iFileHandle , WRITE_BYTE_COUNT , errno , strerror( errno ) );
returnfalse;
}
iStatus=lseek( iFileHandle , iCurPos , SEEK_SET );//恢复文件指针到之前保存的文件位置
if( iStatus!=iCurPos )
{
LOG_DEBUG_INFO("invoke fail , ErrCode:%d , ErrMsg:%s", \
iFileHandle , iCurPos , errno , strerror( errno ) );
returnfalse;
}
returntrue;
}
点击下载
Linux manpages CHM文件下载:
Linux_manpages_part_1_of_4
Linux_manpages_part_2_of_4
Linux_manpages_part_3_of_4
Linux_manpages_part_4_of_4
(由于cppblog限制单个文件上传大小,这里将CHM分割成4部分,全部下载后解压即可).
如果下载速度太慢,请前往这里下载.
posted on 2010-03-01 21:48 luckycat 阅读(5613) 评论(5) 编辑 收藏 引用 所属分类: Linux