游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

谈谈代码JavaIO业务代码优化之路Java开发实战

  版本
  日期
  备注
  1。0
  2019。4。27
  文章首发
  1。1
  2021。6。10
  修改标题:从一段代码谈起浅谈JavaIO接口谈谈代码:JavaIO业务代码优化之路1。前言
  前阵子休息天日常在寻找项目里不好的代码,看到了这样的一段代码:privateResultsshSameExec(Sessionsession,Stringcmd){if(log。isDebugEnabled()){log。debug(shellcommand:{},cmd);}UserInfouigetUserInfo();session。setUserInfo(ui);intexitStatus0;StringBuilderbuildernewStringBuilder();ChannelExecchannel;InputStreamin;InputStreamerr;try{session。connect(connectTimeout);channel(ChannelExec)session。openChannel(exec);channel。setCommand(cmd);inchannel。getInputStream();errchannel。getErrStream();channel。connect();}catch(Exceptione){thrownewCloudRuntimeException(e);}try{longlastReadLong。MAXVALUE;byte〔〕tmpnewbyte〔1024〕;while(true){while(in。available()0err。available()0){inti0;if(in。available()0){iin。read(tmp,0,1024);}elseif(err。available()0){ierr。read(tmp,0,1024);}if(i0){break;}lastReadSystem。currentTimeMillis();builder。append(newString(tmp,0,i));}if(channel。isClosed()){if(in。available()0){continue;}exitStatuschannel。getExitStatus();break;}if(System。currentTimeMillis()lastReadexeTimeout){break;}}}catch(IOExceptione){thrownewCloudRuntimeException(e);}finally{channel。disconnect();session。disconnect();}if(0!exitStatus){returnResult。createByError(ErrorData。builder()。errorCode(ResultCode。EXECUTESSHFAIL。getCode())。detail(builder。toString())。title(ResultCode。EXECUTESSHFAIL。toString())。build());}else{returnResult。createBySuccess(builder。toString());}}
  简单解释一下这段代码即通过ssh到一台机器上,然后执行一些命令。对命令输出的东西,开了一个循环,每一次读一定的位置,然后以字节流的形式读回来。
  这段代码有点丑,于是我闻到了学习的味道。
  首先是对两个Stream的消费,很显然,在多核环境下,我们同时也只能够消费其中一个Stream。其次,这代码太挫了,自己定义一个tmp,然后1024、1024这样的去取出来。
  在改良之前,我们先来回顾一下JavaIO的接口定义。2。JavaIO接口知识回顾2。1低级抽象接口:InputStream和OutputStream
  这里有同学可能问了,为啥叫它低抽象接口呢?因为它离底层太近了,计算机本来就是处理二进制的,而这两个接口正是用来处理二进制数据流的。
  先简单看一眼这两个接口:InputStreamThisabstractclassisthesuperclassofallclassesrepresentinganinputstreamofbytes。pApplicationsthatneedtodefineasubclassofcodeInputStreammustalwaysprovideamethodthatreturnsthenextbyteofinput。authorArthurvanHoffseejava。io。BufferedInputStreamseejava。io。ByteArrayInputStreamseejava。io。DataInputStreamseejava。io。FilterInputStreamseejava。io。InputStreamread()seejava。io。OutputStreamseejava。io。PushbackInputStreamsinceJDK1。0publicabstractclassInputStreamimplementsCloseable{。。。。。}codeOutputStreamThisabstractclassisthesuperclassofallclassesrepresentinganoutputstreamofbytes。Anoutputstreamacceptsoutputbytesandsendsthemtosomesink。pApplicationsthatneedtodefineasubclassofcodeOutputStreammustalwaysprovideatleastamethodthatwritesonebyteofoutput。authorArthurvanHoffseejava。io。BufferedOutputStreamseejava。io。ByteArrayOutputStreamseejava。io。DataOutputStreamseejava。io。FilterOutputStreamseejava。io。InputStreamseejava。io。OutputStreamwrite(int)sinceJDK1。0publicabstractclassOutputStreamimplementsCloseable,Flushable{。。。}code
  我们可以发现,它们都实现了Closeable的接口。因此大家在使用这些原生类时,要注意在结束时调用Close方法哦。
  这两个接口的常用实现类有:FileInputStream和FileOutputStreamDataInputStream和DataOutputStreamObjectInputStream和ObjectOutputStream2。2高级抽象接口Writer和Reader
  为啥说它是高级抽象接口呢?我们先来看看它们的注释:WriterAbstractclassforwritingtocharacterstreams。Theonlymethodsthatasubclassmustimplementarewrite(char〔〕,int,int),flush(),andclose()。Mostsubclasses,however,willoverridesomeofthemethodsdefinedhereinordertoprovidehigherefficiency,additionalfunctionality,orboth。seeWriterseeBufferedWriterseeCharArrayWriterseeFilterWriterseeOutputStreamWriterseeFileWriterseePipedWriterseePrintWriterseeStringWriterseeReaderauthorMarkReinholdsinceJDK1。1publicabstractclassWriterimplementsAppendable,Closeable,Flushable{ReaderAbstractclassforreadingcharacterstreams。Theonlymethodsthatasubclassmustimplementareread(char〔〕,int,int)andclose()。Mostsubclasses,however,willoverridesomeofthemethodsdefinedhereinordertoprovidehigherefficiency,additionalfunctionality,orboth。seeBufferedReaderseeLineNumberReaderseeCharArrayReaderseeInputStreamReaderseeFileReaderseeFilterReaderseePushbackReaderseePipedReaderseeStringReaderseeWriterauthorMarkReinholdsinceJDK1。1publicabstractclassReaderimplementsReadable,Closeable{
  我们可以看到,这个抽象类是用来面向character的,也就是字符。字符的抽象等级必然比字节高,因为字符靠近上层,即人类。2。3优化输入和输出Buffered
  如果我们直接使用上述实现类去打开一个文件(如FileWriter、FileReader、FileInputStream、FileOutputStream),对其对象调用read、write、readLine等,每个请求都是由基础OS直接处理的,这会使一个程序效率低得多因为它们都会引发磁盘访问or网络请求等。
  为了减少这种开销,Java平台实现缓冲IO流。缓冲输入流从被称为缓冲区(buffer)的存储器区域读出数据;仅当缓冲区是空时,本地输入API才被调用。同样,缓冲输出流,将数据写入到缓存区,只有当缓冲区已满才调用本机输出API。
  用于包装非缓存流的缓冲流类有4个:BufferedInputStream和BufferedOutputStream用于创建字节缓冲字节流,BufferedReader和BufferedWriter用于创建字符缓冲字节流。3。着手优化
  之前,我们提到了这段代码写得搓的地方:首先是对两个Stream的消费,很显然,在多核环境下,我们同时也只能够消费其中一个Stream。其次,这代码太挫了,自己定义一个tmp,然后1024、1024这样的去取出来。
  故此,我们可以考虑对每个Stream都进行包装,支持用线程去消费,其次我们可以用高级抽象分接口去适配Byte,然后去装饰成Buffer。
  接下来,我们来看一段ZStack里的工具类ShellUtils,为了节省篇幅,我们仅仅截出它在IDE里的Structure:
  run方法的核心:
  我们可以看到StreamConsumer这个类,我们来看一下它的代码:privatestaticclassStreamConsumerextendsThread{finalInputStreamin;finalPrintWriterout;finalbooleanflush;StreamConsumer(InputStreamin,PrintWriterout,booleanflushEveryWrite){this。inin;this。outout;flushflushEveryWrite;}Overridepublicvoidrun(){BufferedReaderbrnull;try{brnewBufferedReader(newInputStreamReader(in));Stringline;while((linebr。readLine())!null){out。println(line);if(flush){out。flush();}}}catch(Exceptione){logger。warn(e。getMessage(),e);}finally{try{if(br!null){br。close();}}catch(IOExceptione){logger。warn(e。getMessage(),e);}}}}
  这段代码已经达到了我们的理想状态:线程消费,高级抽象。3。1使用Kotlin3。1。1KotlinIO
  闲话不多说,先贴代码为敬:importjava。io。InputStreamimportjava。io。InputStreamReaderclassStreamGobbler(privatevalinputStream:InputStream,privatevarresult:StringBuilder):Runnable{overridefunrun(){InputStreamReader(inputStream)。buffered()。use{it。lines()。forEach{rresult。append(r)}}}}
  还是一样熟悉的配方,我们逐行来解读:定义一个类,并且要求构造函数必须传入InputStream和一个StringBuilder。且实现了Runnable接口,这意味着它可以被线程消费。覆写run方法。我们可以看到InputStream被适配成了InputStreamReader,这意味着它可以输出字符流了,然后我们使用了Kotlin的接口将其装饰成了Buffer。读每一行buffer,并appned到result这个StringBuilder里去。读完就可以告辞了,close。(use会将其关闭)3。1。2KotlinCoroutine
  先看一下上面的图,我们都知道内核态线程是由OS调度的,但当一个线程拿到时间片时,却调到了阻塞IO,那么只能等在那边,浪费时间。
  而协程则可以解决这个问题,当一个Jobhang住的时候,可以去做别的事情,绕开阻塞。更好的利用时间片。
  最后,我们来看一下成品代码:overridefunsshExecWithCoroutine(session:Session,cmd:String):SimpleResultoutString{valuiInnerUserInfo()session。userInfouivalexitStatus:IntvarchannelChannelExec()valinputBuilderStringBuilder()valerrorBuilderStringBuilder()try{session。connect(connectTimeout)channelsession。openChannel(exec)asChannelExecchannel。setCommand(cmd)channel。connect()valinputStreamStreamGobbler(channel。inputStream,inputBuilder)valerrStreamStreamGobbler(channel。errStream,errorBuilder)valcustomJobGlobalScope。launch{customStream(inputStream,errStream)}while(!customJob。isCompleted){waitjobbedone}exitStatuschannel。exitStatus}catch(e:IOException){throwjava。lang。RuntimeException(e)}finally{if(channel。isConnected){channel。disconnect()}if(session。isConnected){session。disconnect()}}returnif(0!exitStatus){returnSimpleResult。createByError(ErrorData。Builder()。errorCode(ResultCode。EXECUTESSHFAIL。value)。detail(errorBuilder。toString())。title(ResultCode。EXECUTESSHFAIL。toString())。build())}else{SimpleResult。createBySuccess(inputBuilder。toString())}}privatesuspendfuncustomStream(inputStream:StreamGobbler,errorStream:StreamGobbler){valinputDeferredGlobalScope。async{inputStream。run()}valerrorDeferredGlobalScope。async{errorStream。run()}inputDeferred。join()errorDeferred。join()}
  作者:泊浮目
  链接:https:juejin。cnpost6971215096282513416

掌阅FaceNote电纸书,让阅读真正的无处不在CiaoBello,我是老房。提到掌阅想必大家都很熟悉,作为一款知名电子书阅读软件,掌阅其实很早就推出了自家的电纸书阅读器,超高的性价比搭配掌阅海量的正版图书资源,在当年……中国的电商直播很火让外国零售商很羡慕随着直播购物视频在中国越来越受欢迎,它们对各大品牌在中国最大购物节日阿里巴巴双11购物节里体现了其重要作用。今年,阿里巴巴将金卡戴珊韦斯特(KimKardashianWe……供应链未来之战产融结合,生态共荣知名未来学家凯文凯利曾说过这样一句话:科技可以对事物标记金融价值,故任何事物的略微变动都会引起其金融价值的变动。按照这种逻辑推演,倘若映射至某条与科技高度相关的产业链中,……嫁保镖,做小三,未婚先孕,180亿的财产她为啥只分到1?她自小便深陷母亲死亡之谜,人们都说她是生母车祸的元凶;她身为公主叛逆骄纵,下嫁王室保镖,未婚先孕生下一对儿女;她的第二个孩子不知其父,混乱的情史让王室有苦难言;……汉ev新配色,苏州园林限定今天跟朋友去看汉,在店门口看到了一辆白色内饰的汉ev,我上网查了一下,原来是苏州园林限定版。白色内饰让整个车子显得更加的高级,方向盘也变车成深蓝色,让人驾驶的欲望更强烈,……国货之光,比亚迪汉以前一直以为比亚迪是买不起车的人才会去买,直到朋友买了个比亚迪汉,无论是外观还是内饰都比我的a4l强的太多了。一眼看过去一点都不像一辆二十几万的车隐藏式门把手逼格满满,主……windows764旗舰版如何清空剪切板的方法有不少深度技术的小伙伴都喜欢在windows764旗舰版中使用到剪切板功能,但是每次使用之后会留有痕迹,如果我们长时间的未清理,就会影响系统的运行速度,可是有小伙伴不知道在wi……肉类食品公司OscarMayer视觉形象升级OscarMayer成立于1883年,是一家美国肉类和冷切食品生产公司,拥有广泛的肉类加工产品组合,包括热狗、腊肠、培根、火腿和火鸡。1981年出售给通用食品,最终成为现在的卡……户外艺术展PiedmontArtWalk视觉形象升级PiedmontArtWalk最早于2020年举办,是一项年度活动,展示居住在美国加州皮埃蒙特的艺术家的多样性。在春天,皮埃蒙特整个城市的人行道、花园和草坪都会被改造成适合步行……专业定制方案TruAudio臻傲定制安装系列私人影院定制安装市场的热度逐渐升温,对于高端的私人影院定制安装需求也在增长,越来越多这类型的用家提出更高的要求。也因这样,许多扬声器厂牌都推出了入墙式(嵌入式)扬声器,在这个领……碳中和领涨,聊聊目前市场的风险因素今天接着昨天的复盘讲,目前市场面临的最大风险点是什么。根据DDM模型,我们分别来看货币政策和市场整体盈利目前到底怎么样。流动性的框架可分为三层:狭义流动性、广义流动……2021年LED市场产值有望增长至165。31亿美金根据TrendForce集邦咨询最新《金级会员市场报告:全球LED产业资料库与LED厂商季度更新》表示,展望2021年,COVID19疫情有望得到缓解,车用LED、显示屏、照明……
工业级SPI接口WiFi模块WG228助力工业物联网数据传输工业物联网简单来说就是工业领域的物联网技术,物联网架构可分为三层:感知层、网络层和应用层,主要涵盖了数据的采集、传输及分析应用。物联网应用都有一个共同点:收集数据并将其发送到服……美团电单车,一年减碳40。9万吨目前共享电单车全行业每年可减碳163。6万吨,其中美团电单车用户一年减碳40。9万吨。以上数据来自近日极光行业研究院联合西安交通大学发布《低碳出行让生活更美好共享电单车社……一加9RT直屏党的选择从一加9RT的宣传来看,这是一款性能旗舰。整体配置在30003500非常具有特点,可以说这是一款为数不多拍照能力强的直屏手机,其次游戏方面也有不错表现,因此,如果是直屏党,这款……未来可期,可怡礼品展完美收官23日,为期4天的第二十八届深圳礼品家居展完美收官,礼品展到目前为止举办已有28个年头,是中国大型的专业家居礼品贸易平台之一。可怡科技作为深耕数码3C领域多年的老牌企业亮……全新奥迪Q5L应运而来,车身靓丽引人注目最新的汽车市场不断更新,有不少新型的汽车横空出世,引起了广大人群的瞩目,其中的一个品牌一汽大众新出品了多款车型,都得到了汽车消费市场的一致好评。而这其中有一款车型尤为特别,是刚……荣耀Play4T正式发布,1199的4G手机是否值得入手呢?4月9日晚19点,荣耀发布了面向年轻人的潮玩新品荣耀Play4T及荣耀Play4TPro手机。外观屏幕屏幕方面,荣耀Play4T使用了6。39寸魅眼屏设计(1560……iPhoneSE3消息频频出现,是否入你的法眼呢?在我们大众的认知里,以前感觉苹果iPhone是绝对信仰的存在,几乎没有任何手机厂商可以与之抗衡,无论设计理念还是软硬件细节做得非常的出色,深得果粉喜爱。但现在,许多网友都……新零售商机尽显,LED屏企加入黄金赛道近年来,新零售模式给各行各业都带来了颠覆性的变革,新型零售模式的资源聚合能力给传统零售模式带来了冲击和市场挤占,传统电商由于互联网和移动互联网终端大范围普及所带来的用户增长以及……2021OPPO开发者大会召开,OPPO游戏全面赋能平台开发10月27日,以开放互融致善创新为主题的2021OPPO开发者大会(ODC21)在上海世博中心正式落幕。作为一家生态型科技公司,OPPO在游戏专场中向外界展示了自身在构建平台生……屏幕规格拉满!小米笔记本Pro官方预热高分辨率只是起点近日,小米官方正式宣布即将发布新一代高端笔记本产品小米笔记本Pro。这个产品线目前已经三年时间未曾推出新品,官方透露此次回归将带来全面的重磅升级,小米集团合伙人张峰在社交……英国气候变化委员会ClimateChangeCommitte英国《气候变化法案》于2008年正式通过生效,该法案承诺,英国将在2050年将温室气体排放量在1990年基础上减少80,并确定了今后五年的碳预算。在通过法案的同时,英国方面还成……华为Mate20pro体验明明可以靠颜值,却偏偏要靠才华不久前华为发布的mate20系列手机,其中最吸引人的一定是mate20pro了!翡冷翠的配色更是让大家眼前一亮。不过对于配色,萝卜白菜,各有所爱,我就喜欢宝石蓝。等快递的……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网