关于写文件的性能问题(200分)

  • 主题发起人 主题发起人 追命
  • 开始时间 开始时间

追命

Unregistered / Unconfirmed
GUEST, unregistred user!
我用assignfile、rewrite、writeln写文件,共15000个文件,95M,用时3小时。<br>其中包括数据库操作。我作过一些实验,如果去掉writeln操作,则用时不到10分钟,<br>生成全部文件(当然,文件全是空的),因此,可以认为时间几乎全部消耗在writeln上了。<br><br>不知能否用其他写文件的方式将此时间减少,提高效率,请各位大侠指点指点<br>
 
用多线程
 
我想先确认一下,针对单个文件的写入,用什么方式写快一些。DELPHI中其他写文件的方法<br>好象有TFileStream.write,或用win api的writefile,我不知道这些是否快一些,而且,<br>我用writefile写不了,总错。
 
把你的程序贴出来看看吧,writeln并不慢的。<br><br>TFileStream.write比writeln应该要快一些,缓冲得多。<br><br>另外,可以强制增加文件操作的缓冲<br>var<br>&nbsp; Buf: array[0..4096] of char;<br>&nbsp; F: TextFile;<br>System.SetTextBuf(F, Buf);
 
下面的代码是一个函数,主程序是一个循环,每循环一次调用一次这个函数,<br>共循环15000次。文件的创建、关闭是在主程序中。写文件的时候使用了自己写<br>的函数。<br>procedure Tfrm_IDXML.makesubcategory(qrtemp:TAdoquery);<br>var<br>&nbsp; str : string;<br>&nbsp; i : integer;<br>&nbsp; levelstr,orderstr : string;<br>begin<br>//<br>&nbsp; with dm do<br>&nbsp; begin<br>&nbsp; &nbsp; levelstr := '';<br>&nbsp; &nbsp; str := '';<br>&nbsp; &nbsp; str := str + 'select b.category_id,b.category_xml ';<br>&nbsp; &nbsp; str := str + ' from FEE_category_xml b,category a,category_temp c ';<br>&nbsp; &nbsp; str := str + ' where a.category_id = b.category_id ';<br>&nbsp; &nbsp; str := str + ' and a.category_id = c.category_id ';<br>&nbsp; &nbsp; str := str + ' and c.resource_count &gt; 0 ';<br>&nbsp; &nbsp; str := str + ' and a.inuse = 1 ';<br>&nbsp; &nbsp; str := str + ' and a.father_id = ' + qrtemp.fieldbyname('category_id').asstring;<br>&nbsp; &nbsp; levelstr := ' and a.level_id = 0 ';<br>&nbsp; &nbsp; orderstr := ' order by a.orderno ';<br><br>&nbsp; &nbsp; runsql(str+levelstr+orderstr,qr_func);<br>{}<br>&nbsp; &nbsp; writeutf8('&lt;CurrentCategories&gt;');<br>&nbsp; &nbsp; writeutf8(getCategoryNavStr(qrtemp.fieldbyname('category_longcode').asstring<br>&nbsp; &nbsp; &nbsp; &nbsp;,qrtemp.fieldbyname('category_longname').asstring));<br>&nbsp; &nbsp; writeutf8('&lt;/CurrentCategories&gt;');<br><br><br>&nbsp; &nbsp; if qr_func.RecordCount &gt; 0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; writeutf8('&lt;StyleCategories&gt;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' &nbsp; &nbsp;&lt;First&gt;&lt;![CDATA[1]]&gt;&lt;/First&gt;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' &nbsp; &nbsp;&lt;Last&gt;&lt;![CDATA['+inttostr(qr_func.recordcount)+']]&gt;&lt;/Last&gt;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' &nbsp; &nbsp;&lt;Total&gt;&lt;![CDATA['+inttostr(qr_func.RecordCount)+']]&gt;&lt;/Total&gt;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' &nbsp; &nbsp;&lt;SubCatsResults&gt;');<br><br>&nbsp; &nbsp; &nbsp; for i := 0 to qr_func.RecordCount - 1 do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; writeutf8(qr_func.fieldbyname('category_xml').asstring);<br>&nbsp; &nbsp; &nbsp; &nbsp; qr_func.Next;<br>&nbsp; &nbsp; &nbsp; end;//end for<br><br>&nbsp; &nbsp; &nbsp; writeutf8(' &nbsp; &nbsp; &nbsp; &nbsp;&lt;/SubCatsResults&gt;'+<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/StyleCategories&gt;');<br><br>&nbsp; &nbsp; end;//end if<br>&nbsp; {}<br>&nbsp; &nbsp; qr_func.Close;<br><br>&nbsp; &nbsp; str := '';<br>&nbsp; &nbsp; str := str + 'select b.category_id,b.category_xml ';<br>&nbsp; &nbsp; str := str + ' from FEE_category_xml b,category a,category_temp c ';<br>&nbsp; &nbsp; str := str + ' where a.category_id = b.category_id ';<br>&nbsp; &nbsp; str := str + ' and a.category_id = c.category_id ';<br>&nbsp; &nbsp; str := str + ' and c.resource_count &gt; 0 ';<br>&nbsp; &nbsp; str := str + ' and a.inuse = 1 ';<br>&nbsp; &nbsp; str := str + ' and a.father_id = ' + qrtemp.fieldbyname('category_id').asstring;<br>&nbsp; &nbsp; levelstr := ' and a.level_id = 1 ';<br>&nbsp; &nbsp; orderstr := ' order by a.orderno ';<br><br>&nbsp; &nbsp; runsql(str+levelstr+orderstr,qr_func);<br>&nbsp; &nbsp; if qr_func.RecordCount &lt; 1 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; qr_func.Close;<br>&nbsp; &nbsp; &nbsp; exit;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; writeutf8('&lt;ContentCategories&gt;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; ' &nbsp; &nbsp;&lt;First&gt;&lt;![CDATA[1]]&gt;&lt;/First&gt;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; ' &nbsp; &nbsp;&lt;Last&gt;&lt;![CDATA['+inttostr(qr_func.recordcount)+']]&gt;&lt;/Last&gt;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; ' &nbsp; &nbsp;&lt;Total&gt;&lt;![CDATA['+inttostr(qr_func.RecordCount)+']]&gt;&lt;/Total&gt;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; ' &nbsp; &nbsp;&lt;SubCatsResults&gt;');<br><br>&nbsp; &nbsp; if qr_func.RecordCount &gt; 0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; for i := 0 to qr_func.RecordCount - 1 do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; writeutf8(qr_func.fieldbyname('category_xml').asstring);<br>&nbsp; &nbsp; &nbsp; &nbsp; qr_func.Next;<br>&nbsp; &nbsp; &nbsp; end;//end for<br><br>&nbsp; &nbsp; end;//end if<br>&nbsp; &nbsp; writeutf8(' &nbsp; &nbsp; &nbsp; &nbsp;&lt;/SubCatsResults&gt;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; '&lt;/ContentCategories&gt;');<br><br>&nbsp; &nbsp; qr_func.Close;<br><br><br>&nbsp; end;//end with<br><br>end;//end makesubcategory<br><br>//写文件的函数<br>procedure Tfrm_IDXML.writeutf8(s:string);<br>begin<br>&nbsp; if cb_code.Checked then<br>&nbsp; &nbsp; writeln(f,ansitoutf8(s))<br>&nbsp; else<br>&nbsp; &nbsp; writeln(f,s);<br>end;<br><br>
 
我用C++的&lt;&lt;操作,写1兆的文件感觉不到停顿的。
 
你按我说的作过了吗? 试试看!<br><br>如果还是不行的话就用TFileStream
 
to lww:<br><br>&nbsp; &nbsp; &nbsp;这个操作转到DELPHI是什么操作?我现在写一个30M的文件,需要1小时<br><br>to Adnil:<br><br>&nbsp; &nbsp; &nbsp;我增加了缓存大小,但效果不大。另外,Buf最长可定义多少?
 
二进制文件读写函数:<br>BlockRead<br>BlockWrite<br>两个函数,缓存大于512K后速度非常快!
 
//二进制文件读写函数:<br>//BlockRead<br>//BlockWrite<br>//两个函数,缓存大于512K后速度非常快!<br>我试过,本地30m文件,3秒搞定<br>
 
加缓存,不要一行一行写,先写到缓存,一起存盘
 
我认为写大文件还是不要加缓存,直接写文件要快的多。
 
后退
顶部