美国对冲基金概貌

        对冲基金,在全球资本市场中已经几度风云涤荡,其独立的对冲交易模式,为资本市场的多元化注入了多种活力。在中国式对冲基金雏形期,外围的历史提供了一个相对清晰的借鉴
在美国,对冲基金经理人常被称为“刺猬”。也许只是个文字游戏,因为对冲基金hedgefund同刺猬hedgehog字形相近。这些“刺猬”也许是金融世界里最机警、最敏锐、最偏执,也最不为人所知的一个群体。
       “过山车”不用多解释,相信读者诸君都是全球金融市场的弄潮儿,或是研究者和观察家,想必也都知道坐过山车的感受,更知道在金融市场上踏波逐浪同坐过山车之间的类似之处。或许一直以来,我们都希望对冲基金不过是金融市场上又一个风靡一时但转瞬即逝的新鲜玩意儿,完全可以不必理会。不错,它们的确是令人兴奋的时髦玩意儿,但是没有任何迹象表明它们会过时。最近几年是也许是全球金融史上最自由、最生机勃勃的时期,我们正身处其中。所以,是时候停止对对冲基金说三道四了,该弄明白它究竟是怎么回事。
神话与现实
Hedge Fund:Myth and Reality
        不久前,人们谈起对冲基金时,常见的话题不外乎它所带来的意想不到的财富:你可能会听说某个名不见经传的家伙花8000万美元买了一件艺术品;某人花2500万美元买下了康涅狄格州格林威治的一处遗址;或是某人付给自己10亿美元年薪。
从某种意义上说,对冲基金是一个颇为吸引眼球的竞赛项目,荒唐,但颇富娱乐性。然后关于对冲基金的话题开始变得严肃起来。比如,对冲基金是否人为抬高了原油价格?某一交易员由于对天然气价格的糟糕预感而损失了60亿美元。或者想想进入2007年以来的两起小规模的市场恐慌:对冲基金是否就是害得市场僵仆在地的病毒?又或者,对冲基金根本就是企图统治世界的惊天大阴谋?类似这样的问题越来越多地出现在人们的闲谈中,尽管有很多人仍然在谈论这些话题,但是很快他们就会失去谈资——因为几乎很少有人真正了解对冲基金。在乔治索罗斯(George Soros)藉此变得富可敌国后,似乎每个人都想在对冲基金上碰碰运气。但是真正懂得它的人并不总把它挂在嘴边。而且你几乎再也见不到这些基金经理们了,因为他们要么躲在自己的洞穴里享受生活,要么在法属波利尼西亚的波拉岛(Bora Bora)潜水。
        但真的是时候理解究竟什么是对冲基金了。估计到2007年3月份,全球已有2万亿美元的资金流入对冲基金,这一数字是1999年的10倍。今天,有9000多家对冲基金投资机构,其中的351家机构管理着超过10亿美元的资产。传统投资公司的人才正在向对冲基金转移,因为这一领域给他们留出了很大的施展才华的空间。最近一项由基金咨询机构Casey,Quirk 和纽约银行共同发布的研究预计,到2010年对冲基金所控制的资产将接近目前的3倍。截至2006年,对冲基金的平均寿命只有5.3年。
对冲基金到底是什么?
        对冲基金只是一种投资工具,尽管它碰巧比大多数投资工具的限制少一些。普通投资工具,以批量制造、为老百姓熟知的共同基金为例,能为你购买股票和债券,但仅此而已。大多数甚至不允许“卖空”。而对冲基金则可采用任意投资工具,包括卖空、杠杆以及期权、期货等衍生工具。多年以前,《纽约时报》就开始喋喋不休地谈论对冲基金使用的这些交易工具“奇怪而且有风险”,这大大增加了对冲基金的神秘感。但可笑的是,实际上所有的金融机构都在使用这些所谓“奇怪”的工具。其实有一种更为简便的方法来定义对冲基金,一位行业精英如是说。AQR资本的Cliff Asness认为:“对冲基金是一种集合投资方式,其运作所受限制较小。相对来说,他们基本不受监管,至少目前还是;收取的费用相当高;如果你想要回你的钱,他们不见得会给你;而且一般不会告诉你他们做什么。投资者指望他们一直赚钱,但如果基金做不到这一点,投资者马上’跳槽‘到另外一家最近在赚钱的机构。每隔三四年,他们会造成一场’百年不遇‘的大灾难。”
        尽管对冲基金的肇始可以追溯到Alfred Winslow Jone(s1901~1989,美国社会学家、作家、财经记者,业内公认的“对冲基金之父”,其在1949年创办的A。W。Jones集团被普遍认为是美国最早的对冲基金),但直到1960年代末,对冲基金才雏形显现,逐步发展为今天广为人知的模式:操作技巧高超的交易商满足非常富有的客户要求巨额回报的投资需求,这些富翁非常愿意为了高额回报“赌一把”。
        对冲基金界的第一批耀眼明星是像索罗斯、Michael Steinhardt以及Bruce Kovner这样的人。他们都堪称大宗商品和货币方面的专家,能够充分利用市场的无效性。他们通过非公开途径,主要是朋友和商业伙伴来募集资本,因此规避了美国证券相关法律的绝大多数信息披露要求,也就是说,他们无需向任何人解释他们究竟有多少钱,又用这些钱做了什么。说白了就是,有钱人可以不受监管地从另外一批有钱人那里集资,只要他们承诺对公众守口如瓶,包括不利用报纸、杂志或类似媒体进行沟通,或使用其他可以被视为向公众募集资金的行为。其实对冲基金本来也没必要向公众集资。想参与对冲基金,你需要投入250万美元。基金经理自己最好也投些钱进去,这是一种非正式的制衡机制,旨在确保基金经理不会肆无忌惮地冒险。
神话是怎样炼成的
        金融界人士对超级投资英雄们顶礼膜拜。这些超级英雄中有些的确名至实归:索罗斯抛空英镑几乎令英格兰银行破产。随着索罗斯声誉日隆,他作为投资人的影响力也与日俱增。Julian Robertson的老虎基金(Tiger Management)是另一个传奇,没人愿意跟他下相反的赌注。他们当年10亿或20亿美元的投资组合,在今天看来简直就像电影《王牌大贱谍》中大反派“魔鬼博士”只要100万美元就不会毁灭世界一样,小里小气得不可思议。但是索罗斯们的大胆举动极大地激励了追随者。当然,想复制索罗斯们传奇经历的人越多,复制成功的机会就越小。JohnH Makin是Kovner的Caxton Associates的一位主管,在他看来,“1980年代和 1990年代初期是对冲基金的黄金时代,当时创下的超乎寻常的收益并非高到令人难以置信的地步,只是令凡夫俗子无法企及而已。”
■对冲基金是对冲的基金是……
一直以来,公众误以为所有对冲基金的操作都差不多,事实并非如此。
一个极端是一群书呆子:博士们不再满足于躲在象牙塔里看风景,而是想从现实生活中得到更多东西,比如金钱。他们利用精准的软件驱动投资策略,而这些软件则由“火箭科学家”们不断完善。这些家伙被称作“定量投资者”(quants,quantitative investor的缩写)。目前他们之中的“王者”是总部位于长岛的复兴科技(Renaissance Technology)的James Simons。他本质上是一位学者,据说他的研究报告包含了一些对资本市场的新发现。
而另一个极端则是一些敲桌瞪眼、蔑视权贵的激进分子。他们中的代表人物有Third Point的Daniel Loeb,还有名字极富创意的海盗投资(Pirate Capital)的Tom Hudson。他们使用的策略最能吸引媒体关注,从而在一定程度上决定了公众对对冲基金的感知,尽管事实上对冲基金更加依赖头脑而不是肌肉。不管怎么说,最精彩的大戏来自于公开争斗。就像Loeb向家电制造商 Salton Inc。开火:Loeb 声称他亲眼看见该公司CEO在美国网球公开赛上优哉游哉地呷着冰镇琼瑶浆(Gewürztraminer,一种酿制白葡萄酒的葡萄及用该种葡萄酿造的白葡萄酒,主要产于法国阿尔萨斯和德国),由公司买单。
在大家的想象中,一名对冲基金交易者应该是坐在一个看起来要完成火星探险的高科技操作台旁,整天忙于买进卖出。肯定有人是这个样子的,SAC Capital的Steve Cohen就是其中之一。但事实上,绝大多数投资公司的办公室要安静得多。一家典型的多空仓(long/short)对冲基金可能在建仓后的几天甚至几周里什么也不做,只是观望事态发展。或许某个下午他们突然心血来潮,请来某个书卷气十足的教授上门兜售他玄之又玄的金融理论。老实说,做对冲基金是一件非常枯燥的事情。
■简单的心理分析
根据《财富的堡垒》(Fortune's Fortress)的作者RussAlanPrince对294位个人掌控资本超过3000万美元的基金经理做的一项调查,结果显示97%的基金经理将自己的投资组合看作是自己的化身。他们经常思考的问题就是“失败”。他们中54%的人声称自己患有“伊卡洛斯综合症”(Icarus Syndrome,伊卡洛斯,希腊神话中修建迈诺斯迷宫的雅典发明家代达罗斯之子。为逃出迷宫,代达罗斯为自己和儿子伊卡洛斯装上翅膀。在飞行中,伊卡洛斯因飞得离太阳太近,结果翅膀融化,堕海而死),总是担心飞得离太阳太近,有一天会坠落。他们还会想到刀光剑影,这是因为,几乎 3/4的基金经理相信他们财富足以使他们成为罪犯的靶子。这就是我们津津乐道的生活吗?
■对冲基金有时会混淆于私募股权基金
在过去的几个月里,关于私募股权基金的报道汗牛充栋。私募股权基金,如黑石集团(Blackstone Group)或KKR,与典型的对冲基金的区别在于,他们倾向于长期控制企业,通常会将上市企业私有化,并力图通过企业重组发一笔横财。像黑石的史蒂夫?施瓦茨曼(Stephen Schwarzman)和KKR的Henry Kravis这样的高手看起来更像是穿着斜纹西装、躲在密室里、抽着雪茄的大人物,而对冲基金经理们则穿着卡其布休闲装,忙于自己的交易,尽量避开外界的视线。
        你可以把这两类人看作是华尔街的“阴阳两仪”。从事私募股权基金的人人情练达,往往来自传统投资银行业中客户关系那一部分,而对冲基金经理们更加注重交易本身,倾向于更快速地进行交易,而不愿意花更多时间分析交易背后的事情。“他们每天考评自己的表现,常常扪心自问,’如果我今天买了这个,明天会不会看起来很傻?‘”一位私募股权专业人士如是说。“而一位从事私募股权基金交易的人常常会坐在一边思考’三五年以后世界会变成什么样子?‘”他们都沉溺于杠杆交易,就是用借来的钱交易。他们肆无忌惮地利用杠杆融资,力图最大化交易收益。事实上,对冲基金的概念从一开始就是基于这样一个假设前提:他们可以以小博大,用借来的钱下大赌注,从而充分发掘利用哪怕再微小的获利机遇。而对冲基金的“对冲”两字源自用对冲手段规避下行风险。这意味着在买进一支股票的同时需要卖空另一支。尽管许多对冲基金仍然采用实实在在的对冲技术,但这种做法早就不时髦了。而杠杆则当行依旧,也就意味着在几乎毫无下行风险防护的情况下放手一搏——一句话,风险重重。
■富有的基金经理
有一件事是所有参与对冲基金交易的人都认可的:他们值那么多钱。管理自己的对冲基金可能是人类最快捷的致富捷径。
对冲基金的费用结构通常是这样的:大多数基金公司抽取2%的管理费和相当于投资利润20%的提成。举例说,假如一笔10亿美元的基金获得了30%的回报,那么他的基金经理将因此获得7880万美元的报酬(10亿X2%+(10亿——10亿X2%)X30%X20%)。而假如这10亿美元分文收益都没得到,他的基金经理仍然可以获得大约2000万美元的报酬。有些基金甚至还要“贵”些,比如James Simons会毫不留情的抽取5%的管理费和 44%的提成。最好的基金经理收入极为可观:这一行最顶尖的几个人每年收入均超过5亿美元。尽管对冲基金经理们总是对他们财富的具体数字三缄其口,但这个圈子里的人都知道谁是“热门”,谁不是。以绿光资本(Greenlight Capital)的David Einhorn为例,本来在这个行当里广受尊敬,但最近在次级住房抵押贷款公司股票投资上蒙受重大损失,结果成了对冲基金圈子里的谈资。下一个倒霉鬼一样会被幸灾乐祸。这个圈子就是如此。
2007年1月底,参议员Chuck Schumer点名邀请了大约20位顶尖对冲基金经理到曼哈顿上东区的Bottegadel Vino意大利餐厅共进晚餐,这是对冲基金影响力崛起的又一标志。这次晚餐应该是一次友好的闲谈。Schumer 参议员传递出的信息是,告诉我们你们究竟在做什么,完全没有必要担心监管部门会给你们找麻烦。当时的参加者包括Kyniko资本的imChanos,Chilton投资公司的Rich Chilton,Steve Cohen,Stanley Druckenmiller,Tudor资本的Paul Tudor Jones二世,以及Appaloosa管理公司的David Tepper。与会者所掌控的资本加起来高达2000亿美元。想想一群极富权势的人秘密聚集在一起就不免让人心惊胆战,就像1957年来自美国、加拿大和意大利的100多位黑手党头目在纽约州的Apalachin小镇举行峰会一样。
华尔街历史上声誉最盛的评论员Byron Wien,2005年为加入Pequot资本而辞去摩根士丹利轻轻松松大把赚钱的工作。前者是一家对冲基金公司,Byron的角色是首席投资战略家。显然,他无须像黑手党党徒一样要被迫遵从圈子里的“荣誉准则”、发誓“拒不招供”。当被问到为何近来对冲基金收益增长止步不前时,他的回答相当简练:“一个主要原因是,现在机构投资者可以合法地投资于对冲基金。过去,这么做好比拿着手电筒在黑黢黢的胡同里干些见不得人的勾当,而现在,典型的机构投资组合中总会有15%~25%是对冲基金之类的另类投资。”
虽然再也用不着手电筒了,但这个行业招致诸多批判,且批判的声音多种多样。有担忧杠杆交易和像“旅鼠跳海”似的跟风冲动会威胁到全球市场稳定的,还有对对冲基金天文数字的高昂费用深恶痛绝的。也难怪巴菲特这样的权威要批评这个行业是在卖噱头,他们索要的高昂费用是“怪胎”。但有趣的是,知道谁被《商业周刊》(BusinessWeek)封为巴菲特的继承人吗?答案是EddieLampert,一位对冲基金经理。
■大的会变得更大
一年前,规模在200亿美元以上的对冲基金机构只有4家,但现在却有了7家,他们是JP摩根、高盛、Bridgewater Associate、D。E。Shaw、Farallon资本、复兴科技、Och——Ziff资本。第一家股票上市的对冲基金机构Fortress在交易的第一天,股价就上涨了67.6个百分点。更多的对冲基金公司会紧随其后。
■他们左顾右盼
在这些巨头当中,你很难发现有谁还是“纯粹”的对冲基金,也就是说依然专注于某个特定的投资风格或缝隙市场。当拥有巨额资金时,你可能会被迫偏离自己的专长,以免最后演变成自己和自己交易。例如,SAC刚刚同KKR同场竞技,以38亿美元竞购一家教育公司。有些基金公司走得更远,甚至会投资拍电影。
■他们在干草堆中寻找一根针
问及任何一位对冲基金经理,他都会跟你说轻松挣钱的日子已经一去不复返,如今可没有那么容易赚的钱了。德累斯顿佳信证券(Dresdner Kleinwort)最近的一份报告指出,在对冲基金交易中,往往对冲基金管理的资产中有4%要作为管理费消耗掉,加上另外4%~5%要花在交易提成和利息上,所以只有每年收益在20%以上才能保证赚钱。这种状况迫使他们冒险。
■圈子已容不下更多新成员
不管你信不信,现在创办一家对冲基金公司要比前几年难多了。一份关于对冲基金的研究报告显示:2006年有1518家对冲基金开业,而2005年则有2073家。2006年,诺贝尔经济学奖得主罗伯特o默顿(Robert Merton)试图开办一家对冲基金公司,终因不能筹到足够的钱而不得不放弃。当然,这倒不是说开一家对冲基金公司是完全不可行的,前提是如果你拥有一支精干的团队再加上良好的从业记录的话。前Mackay Shields投资顾问公司高收益证券业务主管Don Morgan于2006年另起炉灶,创办Brigade Capital。因为同原雇主非竞争协议的限制,过了一年多他原来的团队方能入伙,开办了一支专注于信贷产品的多空仓对冲基金。结果是,当你需要至少 1亿美元作为参与“游戏”的入场费时,Bridge早已坐在了赌桌边了。
■高额代理费正在变得更高
对冲基金是这样一种不可思议的行业:在这个行当里,新手比老手要价还高。从某种意义上讲,这简直是疯了:金融圈里最不公平的一条规则是“你赚,我也赚;你赔了,我还赚”。这种“不平等条约”在对冲基金里正变得更加一边倒。
有人会说,不能再继续下去了。但真的不能了吗?除非竞争本身导致服务费下降,但别指望这种情况会很快发生。因为至少现在机构投资者还在往这一行里扔钱。AQR资本CliffAsness这样解释这种现象:“我们经常会从圈子里听到某某机构正在加入对冲基金行列的传言,这样费用一定会降下来,因为机构对费用高度敏感。但你听说过任何行当里巨大的需求会导致费用降低的吗?反正对冲基金不会是第一个这样的行当。”
■政府正“蠢蠢欲动”
2004年,美国证券交易委员会(SEC)要求对冲基金公司向其注册,这就像是让所有年满19岁的孩子都要去兵役局登记备案一样。法院很快否决了这条法规,于是关于监管的讨论声渐渐消失了。直到去年,总部位于康涅狄格的Amaranth基金公司在天然气期货交易中损失了60亿美金,监管呼声又起,之后又归于沉寂。但只要再出一次市场崩盘或是一起丑闻,监管呼声肯定又会卷土重来。难怪最近所有的大基金都在为游说政界准备庞大的预算。
■投资银行正悄然变身为对冲基金机构
如果你不能打败它,就加入它!高盛及其同业越来越多地靠自有资金交易(proprietary trading)赚钱,使得传统投资银行业务,如并购已经变得不那么重要。高盛造就诸多对冲基金高手,就像多米尼加共和国盛产棒球高手一样。全世界有约1/5的顶级对冲基金经理曾经在高盛工作过。从这一点看,高盛简直就是对冲基金的“黄埔军校”。
■对冲基金是不公平,但是为什么大量的资金仍然源源不断地注入?
当然,第一个原因是,投资者们对风险的容忍度似乎处在历史高位。但是与此相矛盾的是,他们对下行保护的需求也很高。信不信由你,对冲基金的声望还是与5年前他们的表现有关。在2000年~2002年熊市期间,网络泡沫破裂,股市下挫40%。即使在这种情况下,对冲基金平均下来并没有赔钱。养老金基金经理们和其他机构投资者对刚刚发生的危机依然记忆犹新,因此都愿意为了获得下行保护而少赚一点。问题是还有多少基金仍然存在?
■期待闪光灯的青睐
很多成功的对冲基金经理人都在做着“新贵”们会做的事情。比如,试图接近政治权力(通过政治捐赠)或者获得社会声誉(通过涉足慈善事业和艺术品)。大道资本(Avenue Capital)的MarcLasry最近就雇佣了切尔西?克林顿(Chelsea Clinton)做分析师。
■对冲基金的世界末日?
历史上唯一一次对冲基金管理资产缩水发生在1994年。为什么?升息和消化此前几年的大规模增长是原因所在。听起来很耳熟,是吗?对于一个高度依赖“借来的钱”的行业而言,利率的急剧上涨会带来灭顶之灾。以Citadel为例,2006年,其表上负债是当时资本金的11.5倍,使其总资产敞口飙升至1500亿美元。这种高负债大大加重了企业的风险。一位著名的对冲基金经理指出,理论上,除了3家他想得出来的大机构,任何一家对冲基金垮台对大市都不会产生任何影响。但如果这3家机构——Citadel是其中之一——有一家垮掉,那么多米诺骨牌就要开始倒下了。
所以,当某人不假思索地说“对冲基金就是一种暴富骗局,等到曲终人散时,我们要为此付出高昂代价”,你会严肃地颔首赞同吗?不,用不着。试着和一位真正的对冲基金经理谈谈。
对冲基金的普及,一方面降低了市场的波动性,另一方面却增加了系统性崩溃的长期风险。关于第一点,对冲基金比传统的只做长线的基金对市场的反应更加敏捷,它可以通过“突袭”的方式在市场走向极端之前纠正其定价错误。但这同时意味着市场机遇将变得更少。由于对冲基金在整个经济周期内都必须要带来良好回报,机遇的减少迫使他们越来越冒险,其风险敞口日渐加大。因此从长远看,增加了市场发生系统性恐慌的可能性。
德累斯顿佳信证券的分析师在他们的报告中将这种“恐慌”称为“大撒把”。这种情况一旦发生你肯定很快就会得到消息:除了报纸上耸人听闻的新闻标题,以及CNBC电视台比平时更加声泪俱下,你在曼哈顿的公寓价格会突然贬值一半。尽管德累斯顿的分析师认为,发生恐慌是不可避免的,但也承认不能准确预期。这就是说,这种情况可能发生,但是可能就在明天也可能在100年以后,到那时候,整个曼哈顿可能都已经沉没海底,你的公寓值不值钱也已经无所谓了。
基金经理人运作风格分类
Style Guide of Hedge Fund Pros
■交易员(Trader)
研究证券价格的短期波动。交易员并不需要评价所交易股票背后公司的价值或是某种汇率水平是否恰如其分。只要对证券的短期走势给出意见就可以了。
■拣股者(Stock Picker)
与交易员不同,拣股者倾向于分析一家公司(或一个行业或某个国家)的商业基本面,在此基础上赌未来发展走势。与交易员相比,他们更倾向于做“长线”。积极主义拣股者总是试图亲身介入所投资股票企业的运营。CEO们痛恨他们。
■危机投资者(Distressed Investor)
买卖那些陷入困境的公司的证券,关于如何评价此类公司的股票或债券的价值的不同意见通常会比正常情况下更多。危机投资者也有可能成为一个积极主义投资人,试图买下目标企业的大部分股权,或在公司破产时买下其大部分债务,以此控制目标公司。
■定量投资者(Quantitative Investor)一般来说,他们靠软件驱动的模型来分析历史交易模式,以此帮助作出当前投资决策。寻找价格无效或者破解财务报表数据来判定一个理论上的价格。完全靠数字,没有任何惊心动魄的情节。

Posted by 星辰守护者 2012年5月13日 00:01


关于BufferedReader的mark(int),mark()解惑

相信BufferedReader应该是大家所熟悉的一个操作类,但是其中的mark,reset方法,不知大家是否有过关注,
近日工作中碰到问题,不解,所以就Google并记录下来,给自己个记录,也希望与大家分享。
关于BufferedReader:

 

public class BufferedReader
extends Reader

Read text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.

The buffer size may be specified, or the default size may be used. The default is large enough for most purposes.

In general, each read request made of a Reader causes a corresponding read request to be made of the underlying character or byte stream. It is therefore advisable to wrap a BufferedReader around any Reader whose read() operations may be costly, such as FileReaders and InputStreamReaders. For example,

 BufferedReader in
   = new BufferedReader(new FileReader("foo.in"));
 

will buffer the input from the specified file. Without buffering, each invocation of read() or readLine() could cause bytes to be read from the file, converted into characters, and then returned, which can be very inefficient.

Programs that use DataInputStreams for textual input can be localized by replacing each DataInputStream with an appropriate BufferedReader.

Since:
    JDK1.1
See Also:
    FileReader, InputStreamReader

关于它的mark,reset方法:

 

public class BufferedReader
extends Reader

Read text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.

The buffer size may be specified, or the default size may be used. The default is large enough for most purposes.

In general, each read request made of a Reader causes a corresponding read request to be made of the underlying character or byte stream. It is therefore advisable to wrap a BufferedReader around any Reader whose read() operations may be costly, such as FileReaders and InputStreamReaders. For example,

 BufferedReader in
   = new BufferedReader(new FileReader("foo.in"));
 

will buffer the input from the specified file. Without buffering, each invocation of read() or readLine() could cause bytes to be read from the file, converted into characters, and then returned, which can be very inefficient.

Programs that use DataInputStreams for textual input can be localized by replacing each DataInputStream with an appropriate BufferedReader.

Since:
    JDK1.1
See Also:
    FileReader, InputStreamReader

 

 

reset

public void reset()
           throws IOException

    Reset the stream to the most recent mark.

    Overrides:
        reset in class Reader

    Throws:
        IOException - If the stream has never been marked, or if the mark has been invalidated

在项目中有如下代码:

 

protected static String readToTag(BufferedReader br)
    {
        String string = "";
        try
        {
            br.mark(9);
            int charVal = br.read();
            
            while (charVal != '<' && !isFileEnd(br))
            {
                if(charVal == '\r'){
                        currentLineNo ++;
                }
                
                string += (char)charVal;
                br.mark(9);
                charVal = br.read();
            }

            br.reset();
            if (isFileEnd(br) && charVal>0)
            {
                string += (char)charVal;
            }

            return (string);
        }
        catch (IOException ioe)
        {
            Message.show(Message.error, ioe.getMessage());
            return (null);
        }
    }

其功能是:在html文件解析中,读取当前BufferedReader至第一个tag。
其实,BufferedReader的功能是有很多用处的,比如统计文件行数,在html中读取发现tag后再将文件指针返回指向tag前面的位置;
1.在上面的code中,我查阅后(原作者已离职)的理解是:此处就是要在当前处mark一下,读取下一个char后,判断是否'<',重复画线处,直到发现'<',然后返回tag前的文本;则此处的9(就是这个9害我思索许久),不一定是9,可以是8,7...2,后面只读一次就又mark了; 1不行(后面讨论)。
2.在文件读取中,使用mark方法时,要注意,要设置mark参数int readAheadLimit=file.length + 1,否则就会爆出异常java.io.IOException: Mark invalid.
原因在于: 

jdk中声明:
readAheadLimit - Limit on the number of characters that may be read while still preserving the mark. After reading this many characters, attempting to reset the stream may fail. A limit value larger than the size of the input buffer will cause a new buffer to be allocated whose size is no smaller than limit. Therefore large values should be used with care. 

英文声明可能有些confused,来看中文的:
readAheadLimit - 在仍保留该标记的情况下,对可读取字符数量的限制。在读取达到或超过此限制的字符后,尝试重置流可能会失败。限制值大于输入缓冲区的大小将导致分配一个新缓冲区,其大小不小于该限制值。因此应该小心使用较大的值。 //就是建议使用大于最大值的值

给大家一段代码可以参考运行:

 

import java.io.BufferedReader;
import java.io.CharArrayReader;
import java.io.IOException;

public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException {
        String s = "Message.show(Message.error, ioe.getMessage()).一";
        char buf[] = new char[s.length()];
        s.getChars(0, s.length(), buf, 0);
        CharArrayReader in = new CharArrayReader(buf);
        BufferedReader f = new BufferedReader(in);
        String d = "";
        int c;
        System.out.println(s.length() );
        f.mark(s.length() +1);
        while ((c = f.read()) != -1) {
            d += (char)c;
        }
        f.reset();
        System.out.println(d);
    }
}

 

Posted by 星辰守护者 2012年1月31日 17:05


浅谈Android五大布局

 

     Android的界面是有布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦。组件按照布局的要求依次排列,就组成了用户所看见的界面。Android的五大布局分别是LinearLayout(线性布局)、FrameLayout(单帧布局)、RelativeLayout(相对布局)、AbsoluteLayout(绝对布局)和TableLayout(表格布局)。

  LinearLayout:

  LinearLayout按照垂直或者水平的顺序依次排列子元素,每一个子元素都位于前一个元素之后。如果是垂直排列,那么将是一个N行单列的结构,每一行只会有一个元素,而不论这个元素的宽度为多少;如果是水平排列,那么将是一个单行N列的结构。如果搭建两行两列的结构,通常的方式是先垂直排列两个元素,每一个元素里再包含一个LinearLayout进行水平排列。

  LinearLayout中的子元素属性android:layout_weight生效,它用于描述该子元素在剩余空间中占有的大小比例。加入一行只有一个文本框,那么它的默认值就为0,如果一行中有两个等长的文本框,那么他们的android:layout_weight值可以是同为1。如果一行中有两个不等长的文本框,那么他们的android:layout_weight值分别为1和2,那么第一个文本框将占据剩余空间的三分之二,第二个文本框将占据剩余空间中的三分之一。android:layout_weight遵循数值越小,重要度越高的原则。显示效果如下:

 

 

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
     <TextView  android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#ff000000" android:text="@string/hello"/>
     <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent">
         <TextView  android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#ff654321" android:layout_weight="1" android:text="1"/>
         <TextView  android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#fffedcba" android:layout_weight="2"  android:text="2"/>
     </LinearLayout>
 </LinearLayout>

    FrameLayout:  
    FrameLayout是五大布局中最简单的一个布局,在这个布局中,整个界面被当成一块空白备用区域,所有的子元素都不能被指定放置的位置,它们统统放于这块区域的左上角,并且后面的子元素直接覆盖在前面的子元素之上,将前面的子元素部分和全部遮挡。显示效果如下,第一个TextView被第二个TextView完全遮挡,第三个TextView遮挡了第二个TextView的部分位置。


 

<?xml version="1.0" encoding="utf-8"?>
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
     <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ff000000" android:gravity="center" android:text="1"/>
     <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ff654321" android:gravity="center" android:text="2"/>
     <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#fffedcba" android:gravity="center" android:text="3"/>
 </FrameLayout>

 AbsoluteLayout:   
    AbsoluteLayout是绝对位置布局。在此布局中的子元素的android:layout_x和android:layout_y属性将生效,用于描述该子元素的坐标位置。屏幕左上角为坐标原点(0,0),第一个0代表横坐标,向右移动此值增大,第二个0代表纵坐标,向下移动,此值增大。在此布局中的子元素可以相互重叠。在实际开发中,通常不采用此布局格式,因为它的界面代码过于刚性,以至于有可能不能很好的适配各种终端。显示效果如下:

 

<?xml version="1.0" encoding="utf-8"?>
 <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
     <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#ffffffff" android:gravity="center" android:layout_x="50dp" android:layout_y="50dp" android:text="1"/>
     <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#ff654321" android:gravity="center" android:layout_x="25dp" android:layout_y="25dp" android:text="2"/>
     <TextView  android:layout_width="50dp" android:layout_height="50dp" android:background="#fffedcba" android:gravity="center" android:layout_x="125dp" android:layout_y="125dp" android:text="3"/>
 </AbsoluteLayout>

 

RelativeLayout:

  RelativeLayout按照各子元素之间的位置关系完成布局。在此布局中的子元素里与位置相关的属性将生效。例如android:layout_below, android:layout_above等。子元素就通过这些属性和各自的ID配合指定位置关系。注意在指定位置关系时,引用的ID必须在引用之前,先被定义,否则将出现异常。

  RelativeLayout里常用的位置属性如下:
    android:layout_toLeftOf —— 该组件位于引用组件的左方
    android:layout_toRightOf —— 该组件位于引用组件的右方
    android:layout_above —— 该组件位于引用组件的上方
    android:layout_below —— 该组件位于引用组件的下方
       android:layout_alignParentLeft —— 该组件是否对齐父组件的左端
       android:layout_alignParentRight —— 该组件是否齐其父组件的右端
       android:layout_alignParentTop —— 该组件是否对齐父组件的顶部
       android:layout_alignParentBottom —— 该组件是否对齐父组件的底部
    android:layout_centerInParent —— 该组件是否相对于父组件居中
    android:layout_centerHorizontal —— 该组件是否横向居中
    android:layout_centerVertical —— 该组件是否垂直居中

  RelativeLayout是Android五大布局结构中最灵活的一种布局结构,比较适合一些复杂界面的布局。下面示例就展示这么一个情况,第一个文本框与父组件的底部对齐,第二个文本框位于第一个文本框的上方,并且第三个文本框位于第二个文本框的左方。

 

<?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
     <TextView android:id="@+id/text_01" android:layout_width="50dp" android:layout_height="50dp" android:background="#ffffffff" android:gravity="center" android:layout_alignParentBottom="true" android:text="1"/>
     <TextView android:id="@+id/text_02" android:layout_width="50dp" android:layout_height="50dp" android:background="#ff654321" android:gravity="center" android:layout_above="@id/text_01" android:layout_centerHorizontal="true" android:text="2"/>
     <TextView android:id="@+id/text_03" android:layout_width="50dp" android:layout_height="50dp" android:background="#fffedcba" android:gravity="center" android:layout_toLeftOf="@id/text_02" android:layout_above="@id/text_01" android:text="3"/>
 </RelativeLayout>

 

TableLayout:

  TableLayout顾名思义,此布局为表格布局,适用于N行N列的布局格式。一个TableLayout由许多TableRow组成,一个TableRow就代表TableLayout中的一行。

  TableRow是LinearLayout的子类,它的android:orientation属性值恒为horizontal,并且它的android:layout_width和android:layout_height属性值恒为MATCH_PARENT和WRAP_CONTENT。所以它的子元素都是横向排列,并且宽高一致的。这样的设计使得每个TableRow里的子元素都相当于表格中的单元格一样。在TableRow中,单元格可以为空,但是不能跨列。

  下面示例演示了一个TableLayout的布局结构,其中第二行只有两个单元格,而其余行都是三个单元格。

 

<?xml version="1.0" encoding="utf-8"?>
 <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
     <TableRow android:layout_width="fill_parent" android:layout_height="wrap_content">
         <TextView  android:background="#ffffffff" android:gravity="center" android:padding="10dp" android:text="1"/>
         <TextView android:background="#ff654321" android:gravity="center" android:padding="10dp" android:text="2"/>
         <TextView  android:background="#fffedcba" android:gravity="center" android:padding="10dp" android:text="3"/>
     </TableRow>
     <TableRow android:layout_width="fill_parent" android:layout_height="wrap_content">
         <TextView  android:background="#ff654321" android:gravity="center" android:padding="10dp" android:text="2"/>
         <TextView android:background="#fffedcba" android:gravity="center" android:padding="10dp" android:text="3"/>        
     </TableRow>
     <TableRow android:layout_width="fill_parent" android:layout_height="wrap_content">
         <TextView android:background="#fffedcba" android:gravity="center" android:padding="10dp" android:text="3"/>
         <TextView  android:background="#ff654321" android:gravity="center" android:padding="10dp" android:text="2"/>
         <TextView  android:background="#ffffffff" android:gravity="center" android:padding="10dp" android:text="1"/>        
     </TableRow>
 </TableLayout>

 

 

 

Posted by 星辰守护者 2012年1月21日 14:50