文件内部修改之后编辑器(vim)写回

一、文件中间修改写回
这个不是问题,只是一个偶尔想起的一个事儿。因为我经常看帖子回帖的时候看到精彩的内容都会记录到一个txt文件中,而且我还有一个好习惯,就是每次把新收集的内容放在文件的开始而不是像论坛的帖子一样后来的回复追加在最后,因为我还有一个习惯,看这个文件都是从后向前看的,所以也没有问题。
随着收集内容的增加,这个文件就变得越来越大,到底有多大呢?例如我现在已经收集了200KB,由于之前刚坏掉了一块硬盘,所以丢失了之前的收集。每次我把新的内容写入文件的开始的时候,经常喜欢随手按下Ctrl+S来保存一下。这里使用的是文本文件而不是word文档,所以这个操作还是有其必要性的。
铺垫了这么多,想说的问题是,后来我就发现,当文件变大之后,我在文件的开始打几个回车的时候就可以感觉到它的卡。再后来我就想,如果我在这个文件的开始只添加了哪怕一个字,文件大小为200KB,那么是不是这200KB+1字节会被逐个再次写入硬盘?可以想象,这个操作还是很耗时的,虽然那原始的200KB都是无辜的,就是因为这一个字符的“加塞”,导致了这200KB依次后移,进而这个文件占用的所有的扇区都会被蹂躏一遍。这个是一个直观的想法,因为一般直观的想法是不一定准确的,所以最好找一个文件测试一下,找了一个大概168KB的RFC文档测试了一下。
二、测试结果
使用windows下的vim编辑器来进行一个调试,然后在vim73srcfileio.c文件buf_write_bytes函数的地方打断点,在文件的最开始添加一个字符,执行wq写回修改,两次断点之间通过dir 看文件大小的变化

文件内部修改之后编辑器(vim)写回 - Tsecer - Tsecer的回音岛

可以看到文件大小在执行一次buf_write_bytes函数之后增加8KB,而修改之后的内容则是保存在了一个临时的“rfc793TRANSMISSION CONTROL PROTOCOL.txt~”文件中(当然这个可以不关心),然后以8KB为单位进行搬运。即便是8KB充分利用了扇区的批量写入,但是这个写入应该是不可避免的,也就是的确是会整个文件重新写回。
三、windows下vim写回的调用链
>    vimd.exe!_write_nolock(int fh=3, const void * buf=0x011b7158, unsigned int cnt=8192)  行475    C
     vimd.exe!_write(int fh=3, const void * buf=0x011b7158, unsigned int cnt=8192)  行75 + 0x11 字节    C
     vimd.exe!buf_write_bytes(bw_info * ip=0x0012f3ec)  行5708 + 0x13 字节    C
     vimd.exe!buf_write(file_buffer * buf=0x00ce8ce0, unsigned char * fname=0x00cef6d8, unsigned char * sfname=0x00cefab8, long start=1, long end=5247, exarg * eap=0x0012f780, int append=0, int forceit=0, int reset_changed=1, int filtering=0)  行4601 + 0xc 字节    C
     vimd.exe!do_write(exarg * eap=0x0012f780)  行2707 + 0x38 字节    C
     vimd.exe!ex_exit(exarg * eap=0x0012f780)  行6771 + 0x1e 字节    C
     vimd.exe!do_one_cmd(unsigned char * * cmdlinep=0x0012fc1c, int sourcing=0, condstack * cstack=0x0012f904, unsigned char * (int, void *, int)* fgetline=0x005225fe, void * cookie=0x00000000)  行2656 + 0x12 字节    C
     vimd.exe!do_cmdline(unsigned char * cmdline=0x00000000, unsigned char * (int, void *, int)* getline=0x005225fe, void * cookie=0x00000000, int flags=0)  行1126 + 0x25 字节    C
     vimd.exe!nv_colon(cmdarg_S * cap=0x0012fd38)  行5320 + 0x1d 字节    C
     vimd.exe!normal_cmd(oparg_S * oap=0x0012fde0, int toplevel=1)  行1190 + 0x12 字节    C
     vimd.exe!main_loop(int cmdwin=0, int noexmode=0)  行1260 + 0xb 字节    C
     vimd.exe!main()  行965 + 0x9 字节    C
     vimd.exe!__tmainCRTStartup()  行266 + 0x19 字节    C
     vimd.exe!mainCRTStartup()  行182    C
     kernel32.dll!7c816fd7()     
     [下面的框架可能不正确和/或缺失,没有为 kernel32.dll 加载符号]    
     vimd.exe!_read(int fh=-2096605813, void * buf=0x0000b8ba, unsigned int cnt=880017408)  行86 + 0x5d 字节    C
四、稍微引申一下
这个在很多的BBS中也可以看到,最新发表的评论一般都是在评论的最后面,这样看比较符合大家的阅读习惯,那就是从前到后的阅读,对应的故事情节也是从开始到结束。但是从实现的角度来看,我觉得对文件操作每次追加在文件的最后从效率上讲是有极大优势的。我这里只是在自己的PC上折腾,怎么折腾也玩不出个花来,但是对于服务器来说,这个效率是必须要考虑的,因为现在很多服务器的瓶颈就在响应速度上,而且这个响应速度平时大家可能的确是感觉不到,但是到关键时期是影响和显示产品质量的重要指标。例如网购网站搞一些限时促销活动时,此时服务器的压力就会很大;或者春运时网络订票系统等。很多东西就是这样,60分大家都可以轻易得到,但是得到90分并不是仅仅比60分多了50%的概念,而可能是300%。例如一个基站,大家平时都可以打电话,但是大话务量时区别就可以看出来;而且一年之内的系统重启次数也会有差别,虽然一般的基站一年可能也只有10次,但是和0比起来,是一个无限大的比例。

原文地址:https://www.cnblogs.com/tsecer/p/10486127.html