仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 811|回复: 18
打印 上一主题 下一主题

[学习教程] JAVA网站制作之调剂JavaTM 的I/O功能(一)(zt)

[复制链接]
蒙在股里 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:44:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
Java到底会发战成什么样,让我们拭目以待吧,我始终坚信着java会更好。以上都是俺个人看法,欢迎大家一起交流.功能调剂JavaTM的I/O功能
这篇文章会商并举例论述了进步JavaTMI/O功能的多种手艺。尽年夜多半手艺是环绕着磁盘文件I/O的调剂来谈的,可是,有些手艺对收集I/O和视窗输入也一样合用。起首先容的手艺包括底层I/O成绩,然后对诸如压缩、格局化和序列化如许的高层I/O举行会商。可是,请注重,本会商不触及使用计划成绩,搜刮算法和数据布局的选择,也不会商相似文件高速缓存(filecaching)如许的体系级成绩。


当会商JavaI/O时,Java编程言语所假定的两种分歧的磁盘文件构造是没有任何意义的。这两种磁盘文件组织,一种基于字撙节,另外一种基于字符序列。在Java言语中,一个字符利用两个字节暗示,而不是象C言语那样利用一个字节暗示一个字符。正由于云云,从文件中读取字符时必要一些转换。在某些情形下,如许的区分十分主要,我们将用几个例子对此举行申明。


底层I/O成绩
简介
减速I/O的基础划定规矩
缓冲
读/写文本文件
格局化的开支
随机存储

高层I/O成绩
紧缩
高速缓存
标记化(Tokenization)
序列化(Serialization)
猎取文件信息
更多的信息
减速I/O的基础划定规矩


作为入手下手会商的一种办法,上面列出了减速I/O的一些基础划定规矩:


1.制止会见磁盘

2.制止会见上面的操纵体系

3.制止办法挪用

4.制止对字节和字符的独自处置


明显,这些划定规矩不克不及被周全而严厉地使用,由于假如那样的话,I/O就不成能事情了。可是,为了检察划定规矩是怎样被使用的,就思索上面的三个例子,这些例子盘算一个文件中换行符(
)的数量。


办法一:读取的办法


第一个办法复杂天时用一个文件输出流(FileInputStream)上的读办法:


importjava.io.*;



publicclassintro1{

publicstaticvoidmain(Stringargs[]){

if(args.length!=1){

System.err.println("missingfilename");

System.exit(1);

}

try{

FileInputStreamfis=

newFileInputStream(args[0]);

intcnt=0;

intb;

while((b=fis.read())!=-1){

if(b==
)

cnt++;

}

fis.close();

System.out.println(cnt);

}

catch(IOExceptione){

System.err.println(e);

}

}

}



但是,这个办法触发了大批对底层运转体系的挪用,这就是FileInputStream.read,前往文件下一个字节的本机办法。


办法二:接纳一个年夜缓冲区


第二种办法经由过程接纳一个年夜缓冲区,制止了上述成绩:


importjava.io.*;



publicclassintro2{

publicstaticvoidmain(Stringargs[]){

if(args.length!=1){

System.err.println("missingfilename");

System.exit(1);

}

try{

FileInputStreamfis=

newFileInputStream(args[0]);

BufferedInputStreambis=

newBufferedInputStream(fis);

intcnt=0;

intb;

while((b=bis.read())!=-1){

if(b==
)

cnt++;

}

bis.close();

System.out.println(cnt);

}

catch(IOExceptione){

System.err.println(e);

}

}

}

BufferedInputStream.read从输出缓冲区中猎取下一个字节,少少会见底层体系。


办法三:间接缓冲(DirectBuffering)


第三种办法制止利用缓冲的输出流(BufferedInputStream),而间接举行缓冲,因而制止了读取办法的挪用:


importjava.io.*;



publicclassintro3{

publicstaticvoidmain(Stringargs[]){

if(args.length!=1){

System.err.println("missingfilename");

System.exit(1);

}

try{

FileInputStreamfis=

newFileInputStream(args[0]);

bytebuf[]=newbyte[2048];

intcnt=0;

intn;

while((n=fis.read(buf))!=-1){

for(inti=0;i<n;i++){

if(buf[i]==
)

cnt++;

}

}

fis.close();

System.out.println(cnt);

}

catch(IOExceptione){

System.err.println(e);

}

}

}



关于1MB的输出文件,以秒为单元,各个程序的实行工夫为:



intro16.9

intro20.9

intro30.4



大概,在最快和最慢之间存在一个17比1的差异。


这伟大的减速功能并没有一定地证实,应当老是效仿第三种办法,由于此办法中必要本人举行缓冲。假如事先没有举行细心的完成,如许的办法大概简单形成毛病,出格是在处置文件停止(end-of-file)事务时。它也大概在可读性上比其他的办法差。可是,记着工夫都消费到甚么中央往了,记着在必要时怎样改正是很有用的。


对尽年夜多半使用程序而言,办法二多是准确的选择。


缓冲


办法二和办法三利用了缓冲手艺,个中,文件中的一整块从磁盘中读掏出来,然后再一次一个字节大概字符地举行会见。缓冲是减速I/O的一种基础和主要的手艺,并且很多Java类都撑持缓冲(BufferedInputStream用于字节,BufferedReader用于字符)。


一个分明的成绩是:是不是缓冲区越年夜就可以够使I/O越快呢?Java缓冲区典范的缺省值是1024大概2048个字节。年夜于此值的缓冲区大概可以匡助减速I/O,但一般只要几个百分点,即5%到10%。


办法四:全部文件


这个极度的例子必要断定文件的长度,然后将全部文件读取到缓冲区中。


importjava.io.*;



publicclassreadfile{

publicstaticvoidmain(Stringargs[]){

if(args.length!=1){

System.err.println("missingfilename");

System.exit(1);

}

try{

intlen=(int)(newFile(args[0]).length());

FileInputStreamfis=

newFileInputStream(args[0]);

bytebuf[]=newbyte[len];

fis.read(buf);

fis.close();

intcnt=0;

for(inti=0;i<len;i++){

if(buf[i]==
)

cnt++;

}

System.out.println(cnt);

}

catch(IOExceptione){

System.err.println(e);

}

}

}



这类办法很便利,由于文件能够被看成字节数组来看待。可是,一个分明的成绩是大概没有充足的内存来读取一个十分年夜的文件。


缓冲的另外一方面触及到终端窗口的文本输入。缺省情形下,System.out(一个打印流――PrintStream)是行缓冲的,也就是说,当碰到一个换行符时输入行列被清空。关于交互式使用来讲,这是很主要的,阅赡芟不对谑导适输出前,有一个输出提醒符。


办法五:克制行缓冲


可是行缓冲能够被克制,正以下面例子中所示的:


importjava.io.*;



publicclassbufout{

publicstaticvoidmain(Stringargs[]){

FileOutputStreamfdout=

newFileOutputStream(FileDescriptor.out);

BufferedOutputStreambos=

newBufferedOutputStream(fdout,1024);

PrintStreamps=

newPrintStream(bos,false);



System.setOut(ps);



finalintN=100000;



for(inti=1;i<=N;i++)

System.out.println(i);



ps.close();

}

}

该程序输入整数1至100000,而且比利用行缓冲的程序快三倍。缓冲也是上面几个例子之一的一个主要部分,个中缓冲区被用来减速对随机文件的会见。


读/写文本文件


先条件及的一个设法是,在从文件中读取字符时,办法挪用的体系开支十分可不雅。这类情形的另外一个例子可以在如许一个程序中找到,该程序盘算一个文本文件的行数。


importjava.io.*;



publicclassline1{

publicstaticvoidmain(Stringargs[]){

if(args.length!=1){

System.err.println("missingfilename");

System.exit(1);

}

try{

FileInputStreamfis=

newFileInputStream(args[0]);

BufferedInputStreambis=

newBufferedInputStream(fis);

DataInputStreamdis=

newDataInputStream(bis);

intcnt=0;

while(dis.readLine()!=null)

cnt++;

dis.close();

System.out.println(cnt);

}

catch(IOExceptione){

System.err.println(e);

}

}

}

这个程序利用老版本的DataInputStream.readLine办法,该办法的完成是经由过程利用读取办法挪用来取得每一个字符。一个更新的办法是:


importjava.io.*;



publicclassline2{

publicstaticvoidmain(Stringargs[]){

if(args.length!=1){

System.err.println("missingfilename");

System.exit(1);

}

try{

FileReaderfr=newFileReader(args[0]);

BufferedReaderbr=newBufferedReader(fr);

intcnt=0;

while(br.readLine()!=null)

cnt++;

br.close();

System.out.println(cnt);

}

catch(IOExceptione){

System.err.println(e);

}

}

}

这类办法可以快一些。比方,关于6MB字节200,000行的文本文件,第二个程序比第一个约莫快20%。


可是,即便是第二个程序,也其实不够快,这里有一个主要成绩值得注重。第一个程序在Javatm2编译器上会招致一个严峻的告诫,这是由于DataInputStream.readLine太陈腐了,不克不及准确地将字节转换为字符,而且也不是操纵某些包括有非ASCII字节文本文件的得当选择,(请注重,Java言语利用Unicode字符集,而不是ASCII字符集)。


后面提到的字撙节和字符流的分歧,鄙人列程序中发生了效果:


importjava.io.*;



publicclassconv1{

publicstaticvoidmain(Stringargs[]){

try{

FileOutputStreamfos=

newFileOutputStream("out1");

PrintStreamps=

newPrintStream(fos);

ps.println("uffffu4321u1234");

ps.close();

}

catch(IOExceptione){

System.err.println(e);

}

}

}

写进一个输入文件,但没有保存实践输入的Unicode字符。读/写I/O类是基于字符的,而且是计划用来办理这个成绩的。在OutputStreamWriter中,薪辛舜幼址蜃纸诘谋嗦胱弧?


利用PrintWriter输入Unicode字符的程序看上往象如许:


importjava.io.*;



publicclassconv2{

publicstaticvoidmain(Stringargs[]){

try{

FileOutputStreamfos=

newFileOutputStream("out2");

OutputStreamWriterosw=

newOutputStreamWriter(fos,"UTF8");

PrintWriterpw=newPrintWriter(osw);

pw.println("uffffu4321u1234");

pw.close();

}

catch(IOExceptione){

System.err.println(e);

}

}

}

本程序利用了UTF8编码,它将ASCII编码为其自己,其他字符编码为两个大概三个字节。
通过视频学习比传统的大课堂学习更适合成人化的学习规律。有人说大课堂气氛好,学习氛围浓,热闹,可以认识很多人。
爱飞 该用户已被删除
沙发
发表于 2015-1-19 09:05:03 | 只看该作者
Java 编程语言的风格十分接近C、C++语言。
活着的死人 该用户已被删除
板凳
发表于 2015-1-24 11:29:03 | 只看该作者
是一种语言,用以产生「小应用程序(Applet(s))
兰色精灵 该用户已被删除
地板
发表于 2015-1-25 11:59:21 来自手机 | 只看该作者
Java是一个纯的面向对象的程序设计语言,它继承了 C++语言面向对象技术的核心。Java舍弃了C ++语言中容易引起错误的指针(以引用取代)、运算符重载(operator overloading)
莫相离 该用户已被删除
5#
发表于 2015-1-25 14:59:20 | 只看该作者
有时间再研究一下MVC结构(把Model-View-Control分离开的设计思想)
admin 该用户已被删除
6#
发表于 2015-2-2 13:07:13 | 只看该作者
那么我书也看了,程序也做了,别人问我的问题我都能解决了,是不是就成为高手了呢?当然没那么简单,这只是万里长征走完了第一步。不信?那你出去接一个项目,你知道怎么下手吗,你知道怎么设计吗,你知道怎么组织人员进行开发吗?你现在脑子里除了一些散乱的代码之外,可能再没有别的东西了吧!
柔情似水 该用户已被删除
7#
发表于 2015-2-7 20:42:03 | 只看该作者
在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。
小魔女 该用户已被删除
8#
发表于 2015-2-17 04:43:51 | 只看该作者
Java自面世后就非常流行,发展迅速,对C++语言形成了有力冲击。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台
山那边是海 该用户已被删除
9#
发表于 2015-3-3 12:49:14 | 只看该作者
在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。
蒙在股里 该用户已被删除
10#
 楼主| 发表于 2015-3-11 06:35:01 | 只看该作者
我大二,Java也只学了一年,觉得还是看thinking in java好,有能力的话看英文原版(中文版翻的不怎么好),还能提高英文文档阅读能力。
飘灵儿 该用户已被删除
11#
发表于 2015-3-11 13:30:26 | 只看该作者
是一种使网页(Web Page)由静态(Static)转变为动态(Dynamic)的语言
小女巫 该用户已被删除
12#
发表于 2015-3-11 19:42:25 | 只看该作者
是一种突破用户端机器环境和CPU
谁可相欹 该用户已被删除
13#
发表于 2015-3-15 21:12:59 | 只看该作者
Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。
金色的骷髅 该用户已被删除
14#
发表于 2015-3-16 02:13:37 | 只看该作者
Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。
老尸 该用户已被删除
15#
发表于 2015-3-18 17:26:38 | 只看该作者
另外编写和运行Java程序需要JDK(包括JRE),在sun的官方网站上有下载,thinking in java第三版用的JDK版本是1.4,现在流行的版本1.5(sun称作J2SE 5.0,汗),不过听说Bruce的TIJ第四版国外已经出来了,是专门为J2SE 5.0而写的。
精灵巫婆 该用户已被删除
16#
发表于 2015-3-18 20:52:51 | 只看该作者
你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。
简单生活 该用户已被删除
17#
发表于 2015-3-28 04:03:17 | 只看该作者
任职于太阳微系统的詹姆斯·高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak,目标设置在家用电器等小型系统的程序语言
变相怪杰 该用户已被删除
18#
发表于 2015-3-29 22:34:27 | 只看该作者
任职于太阳微系统的詹姆斯·高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak,目标设置在家用电器等小型系统的程序语言
愤怒的大鸟 该用户已被删除
19#
发表于 2015-4-2 06:52:29 | 只看该作者
自从Sun推出Java以来,就力图使之无所不包,所以Java发展到现在,按应用来分主要分为三大块:J2SE,J2ME和J2EE,这也就是Sun ONE(Open Net Environment)体系。J2SE就是Java2的标准版,主要用于桌面应用软件的编程;J2ME主要应用于嵌入是系统开发,如手机和PDA的编程;J2EE是Java2的企业版,主要用于分布式的网络程序的开发,如电子商务网站和ERP系统。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-11-15 16:21

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表