<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>扫地老僧的Blog &#187; C++</title>
	<atom:link href="http://www.doyj.com/tag/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.doyj.com</link>
	<description>Laputa - 远方地平线，闪耀着光芒</description>
	<lastBuildDate>Thu, 10 Nov 2011 17:24:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>在linux下一个有趣的STL文件IO问题</title>
		<link>http://www.doyj.com/2006/10/12/%e5%9c%a8linux%e4%b8%8b%e4%b8%80%e4%b8%aa%e6%9c%89%e8%b6%a3%e7%9a%84stl%e6%96%87%e4%bb%b6io%e9%97%ae%e9%a2%98/</link>
		<comments>http://www.doyj.com/2006/10/12/%e5%9c%a8linux%e4%b8%8b%e4%b8%80%e4%b8%aa%e6%9c%89%e8%b6%a3%e7%9a%84stl%e6%96%87%e4%bb%b6io%e9%97%ae%e9%a2%98/#comments</comments>
		<pubDate>Wed, 11 Oct 2006 17:39:10 +0000</pubDate>
		<dc:creator>oldmonk</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[io]]></category>
		<category><![CDATA[stl]]></category>

		<guid isPermaLink="false">http://www.doyj.com/2006/10/12/%e5%9c%a8linux%e4%b8%8b%e4%b8%80%e4%b8%aa%e6%9c%89%e8%b6%a3%e7%9a%84stl%e6%96%87%e4%bb%b6io%e9%97%ae%e9%a2%98/</guid>
		<description><![CDATA[在linux下读一个巨大的日志文件, 2.4G 用正文文件的方式打开, 一行一行的读 char achbuf[ 4096 ] ; ifstream ifile( "/cygdrive/h/logs/zz/ex051117.log" ) ; if ( !ifile ) { cout &#60;&#60; "error in opening" &#60;&#60; endl ; return -1... ]]></description>
			<content:encoded><![CDATA[<p>在linux下读一个巨大的日志文件, 2.4G</p>
<p>用正文文件的方式打开, 一行一行的读</p>
<blockquote>
<pre><span style="color: #0000ff">char</span> achbuf[ 4096 ] ;

ifstream ifile( "<span style="color: #8b0000">/cygdrive/h/logs/zz/ex051117.log</span>" ) ;

<span style="color: #0000ff">if</span> ( !ifile ) {

cout &lt;&lt; "<span style="color: #8b0000">error in opening</span>" &lt;&lt; endl ;
<span style="color: #0000ff">return</span> -1 ;
}

<span style="color: #0000ff">int</span> i ;

<span style="color: #0000ff">for</span>( i = 0 ; !ifile.eof() ; i++ )
{
ifile.getline( achbuf , <span style="color: #0000ff">sizeof</span>( achbuf ) - 1 ) ;
}</pre>
</blockquote>
<pre>这个过程用了51秒</pre>
<p>2.4G的文件用51秒, 47M每秒, 已经接近硬盘的最高速度了.</p>
<p>当时想做个尝试, 看看用二进制方式打开一次读入16M能否会更快.</p>
<blockquote>
<pre><span style="color: #0000ff">char</span> achbuf[ 4096 * 4096 ] ;
ifstream ifile( "<span style="color: #8b0000">file.log</span>" , ios::in | ios::binary ) ;

<span style="color: #0000ff">if</span> ( !ifile ) {

cout &lt;&lt; "<span style="color: #8b0000">error in opening</span>" &lt;&lt; endl ;
<span style="color: #0000ff">return</span> -1 ;
}

<span style="color: #0000ff">int</span> i ;

<span style="color: #0000ff">for</span>( i = 0 ; !ifile.eof() ; i++ )
{
ifile.read( achbuf , <span style="color: #0000ff">sizeof</span>( achbuf ) ) ;
}</pre>
</blockquote>
<pre>这个过程竟然用了96秒!!!!!!!!!!</pre>
<pre>到论坛请教了一下, co给出一个链接: <a target="_blank" href="http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/845beed6e4382f83/a0e82948def301fb">Fast read of binary files that alternate type</a></pre>
<pre>试了试co推荐的文章里说的方法, 加了 ifile.imbue( std::locale::classic());, 结果为88秒, 有提高.</pre>
<pre>改用下面的代码读是54秒, 和第一个速度相近了</pre>
<blockquote>
<pre>FILE *pfile ;

pfile = fopen( "<span style="color: #8b0000">file.log</span>" , "<span style="color: #8b0000">rbS</span>" ) ;

<span style="color: #0000ff">if</span> ( pfile == NULL ) {

cout &lt;&lt; "<span style="color: #8b0000">error in opening</span>" &lt;&lt; endl ;
<span style="color: #0000ff">return</span> -1 ;
}

<span style="color: #0000ff">int</span> i ;

<span style="color: #0000ff">for</span>( i = 0 ; !feof( pfile ) ; i++ )
{
fread( achbuf, 1 , <span style="color: #0000ff">sizeof</span>( achbuf ) , pfile ) ; <span style="color: #008000">//16M</span>
}

fclose( pfile ) ;</pre>
</blockquote>
<pre>刚开始学习stl,不太清楚stl文件io实现的内部机制, 不清楚为什么二进制和正文文件的读入速度差这么多.</pre>
<pre>有知道的请不吝赐教. 有能答疑解惑者,赠烤鸭一只<img alt="smile_tongue" src="http://spaces.live.com/rte/emoticons/smile_tongue.gif" /></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.doyj.com/2006/10/12/%e5%9c%a8linux%e4%b8%8b%e4%b8%80%e4%b8%aa%e6%9c%89%e8%b6%a3%e7%9a%84stl%e6%96%87%e4%bb%b6io%e9%97%ae%e9%a2%98/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>try{} catch(&#8230;){}</title>
		<link>http://www.doyj.com/2006/09/11/try-catch/</link>
		<comments>http://www.doyj.com/2006/09/11/try-catch/#comments</comments>
		<pubDate>Mon, 11 Sep 2006 14:20:31 +0000</pubDate>
		<dc:creator>oldmonk</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.doyj.com/2006/09/11/try-catch/</guid>
		<description><![CDATA[以前都是用try{} catch(&#8230;){}来捕获C++中一些意想不到的异常， 今天看了Winhack的帖子才知道，这种方法在VC中其实是靠不住的。例如下面的代码： try { BYTE* pch ; pch = (&#160;BYTE* )00001234 ;&#160;&#160; /... ]]></description>
			<content:encoded><![CDATA[<p>以前都是用try{} catch(&#8230;){}来捕获C++中一些意想不到的异常， 今天看了Winhack的帖子才知道，这种方法在VC中其实是靠不住的。例如下面的代码：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">try</span></li>
<li><span style="color: Olive;">{</span></li>
<li><span style="color: Blue;">BYTE</span><span style="color: Gray;">* </span><span style="color: Blue;">pch</span><span style="color: Gray;"> ;</span></li>
<li><span style="color: Blue;">pch</span><span style="color: Gray;"> = </span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">BYTE</span><span style="color: Gray;">* </span><span style="color: Olive;">)</span><span style="color: Maroon;">00001234</span><span style="color: Gray;"> ;&nbsp;&nbsp; </span><span style="color: #ffa500;">//给予一个非法地址</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">*</span><span style="color: Blue;">pch</span><span style="color: Gray;"> = </span><span style="color: Maroon;">6</span><span style="color: Gray;"> ; </span><span style="color: #ffa500;">//对非法地址赋值，会造成Access Violation 异常</span></li>
<li><span style="color: Olive;">}</span></li>
<li><span style="color: Green;">catch</span><span style="color: Olive;">(</span><span style="color: Gray;">...</span><span style="color: Olive;">)</span></li>
<li><span style="color: Olive;">{</span></li>
<li><span style="color: Blue;">AfxMessageBox</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">catched</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> ;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>这段代码在debug下没有问题，异常会被捕获，会弹出”catched”的消息框。 但在Release方式下如果选择了编译器代码优化选项，则VC编译器会去搜索try块中的代码， 如果没有找到throw代码， 他就会认为try catch结构是多余的， 给优化掉。 这样造成在Release模式下，上述代码中的异常不能被捕获，从而迫使程序弹出错误提示框退出。</p>
<p>那么能否在release代码优化状态下捕获这个异常呢， 答案是有的。 就是__try, __except结构， 上述代码如果改成如下代码异常即可捕获。</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">__try</span></li>
<li><span style="color: Olive;">{</span></li>
<li><span style="color: Blue;">BYTE</span><span style="color: Gray;">* </span><span style="color: Blue;">pch</span><span style="color: Gray;"> ;</span></li>
<li><span style="color: Blue;">pch</span><span style="color: Gray;"> = </span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">BYTE</span><span style="color: Gray;">* </span><span style="color: Olive;">)</span><span style="color: Maroon;">00001234</span><span style="color: Gray;"> ;&nbsp;&nbsp; </span><span style="color: #ffa500;">//给予一个非法地址</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">*</span><span style="color: Blue;">pch</span><span style="color: Gray;"> = </span><span style="color: Maroon;">6</span><span style="color: Gray;"> ; </span><span style="color: #ffa500;">//对非法地址赋值，会造成Access Violation 异常</span></li>
<li><span style="color: Olive;">}</span></li>
<li><span style="color: Blue;">__except</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">EXCEPTION_EXECUTE_HANDLER</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Olive;">{</span></li>
<li><span style="color: Blue;">AfxMessageBox</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">catched</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> ;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>但是用__try, __except块还有问题， 就是这个不是C++标准， 而是Windows平台特有的扩展。 而且如果在使用过程中涉及局部对象析构函数的调用，则会出现<a href="http://www.google.com/url?sa=t&#038;ct=res&#038;cd=1&#038;url=http%3A%2F%2Fmsdn2.microsoft.com%2Fen-us%2Flibrary%2Fxwtb73ad.aspx&#038;ei=yG8FRcLRKpHisALKxaDJCQ&#038;sig=__0o26_U6kzjC5tci9Pyqb9tdM4BE=&#038;sig2=Gjdjsi-xt_pIbvGvMGAFlg"><span id="nsrTitle">C2712</span></a> 的编译错误。 那么还有没有别的办法呢？</p>
<p>当然有， 就是仍然使用C++标准的try{}catch(..){}， 但在编译命令行中加入  <strong>/EHa</strong> 的参数。这样VC编译器不会把try catch模块给优化掉了。</p>
<p><span class="postbody"> 找到一篇比较好的英文文章谈这个问题： <a target="_blank" href="http://members.cox.net/doug_web/eh.htm">http://members.cox.net/doug_web/eh.htm</a></span></p>
<p>用C++10 年多了 ， 居然这么基础的问题都搞错， 真是汗颜。 要加紧学习啊， Stay Hungry, Stay Foolish!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.doyj.com/2006/09/11/try-catch/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

