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