A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© lilongbin2016 中级黑马   /  2016-12-10 22:13  /  836 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

1Java输入输出流

所有的程序语言都提?copy;与本机文件系统交互的方式;Java也不例外。我们将看看Java是怎样处理标准文件输入输出的(包括stdin,stout,stderr)。当你在网络上开发小程序时,你必须注意直接文件输入输出是不安全因素的关键。大多数用户设置他们的浏览器,可让你自由的访问他们的文件系统,但有?copy;不让你访问。当然,如果你开发你内部的应用程序,你也许需要直接访问文件。

标准输入输出Unix的用户,或其他基于命令行系统的用户(如DOS),都知道标准输入输出的含义。标准输入文件是键盘,标准输出文件是你的终端屏幕。标准错误输出文件也指向屏幕,如果有必要,它也可以指向另一个文件以便和正常输出区分。

系统类Java通过系统类达到访问标准输入输出的功能。上面提到的三个文件在这个系统类中实现:StdinSystem.in作为InputStream类的一个实例来实现stdin,你可以使用read()和skip(longn)两个成员函数。read()让你从输入中读一个字节,skip(longn)让你在输入中跳过n个字节。

StoutSystem.out作为PrintStream来实现stdout,你可以使用print()和println()两个成员函数。这两个函数支持Java的任意基本类型作为参数。

StderrSystem.err同stdout一样实现stderr。象System.out一样,你可以访问PrintStream成员函数。

2标准输入输出例子

这里有一个例子,功能象Unix里的cat或type:

importjava.io.*classmyCat{publicvoidmain(Stringargs[])throwsIOException{intb;intcount=0;while((b=System.in.read())!=-1){count++;System.out.print((char)b);}System.out.println();//blanklineSystem.err.println("counted"+count+"totalbytes.");}}

3普通输入输出类

除了基本的键盘输入和屏幕输出外,我们还需要联系文件的输入输出。我们将学习下面几个类:lFileInputStreamlDataInputStreamlFileOutputStreamlDataOutputStream

作为参考,再列出一?copy;特定应用的类:lPipedInputStreamlBufferedInputStreamlPushBackInputStreamlStreamTokenizerlPipedOutputStreamlBufferedOutputStreamlRandomAccessFile

我们不在此讨论这?copy;类,但你可以在JAVA_HOME/src/java/io目录里查看每个类的成员函数定义。

4文件

在我们进行文件操作时,需要知道一?copy;关于文件的信息。File类提?copy;了一?copy;成员函数来操纵文件和获得一?copy;文件的信息。

4.1创建一个新的文件对象

你可用下面三个方法来创建一个新文件对象:

FilemyFile;myFile=newFile("etc/motd");



myFile=newFile("/etc","motd");//moreusefulifthedirectoryorfilenamearevariables



FilemyDir=newfile("/etc");myFile=newFile(myDir,"motd");

这三种方法取决于你访问文件的方式。例如,如果你在应用程序里只用一个文件,第一种创建文件的结构是最容易的。但如果你在同一目录里打开数个文件,则第二种或第三种结构更好一?copy;。

4.2文件测试和使用

一?copy;你创建了一个文件对象,你便可以使用以下成员函数来获得文件相关信息:

文件名lStringgetName()lStringgetPath()lStringgetAbslutePath()lStringgetParent()lbooleanrenameTo(FilenewName)

文件测试lbooleanexists()lbooleancanWrite()lbooleancanRead()lbooleanisFile()lbooleanisDirectory()lbooleanisAbsolute()

一般文件信息llonglastModified()llonglength()

目录用法lbooleanmkdir()lString[]list()

4.3文件信息获取例子程序

这里是一个独立的显示文件的基本信息的程序,文件通过命令行参数传输:

importjava.io.*;classfileInfo{FilefileToCheck;publicstaticvoidmain(Stringargs[])throwsIOException{if(args.length>0){for(inti=0;i<args.length;i++){fileToCheck=newFile(args[i]);info(fileToCheck);}}else{System.out.println("Nofilegiven.");}}publicvoidinfo(Filef)throwsIOException{System.out.println("Name:"+f.getName());System.out.println("Path:"=f.getPath());if(f.exists()){System.out.println("Fileexists.");System.out.print((f.canRead()?"andisReadable":""));System.out.print((f.cnaWrite()?"andisWriteable":""));System.out.println(".");System.out.println("Fileis"+f.lenght()="bytes.");}else{System.out.println("Filedoesnotexist.");}}}

5输入流

InputStreamSequenceInputStreamFileInputStreamPipedInputStreamByteArrayInputStreamFileterInputStreamStringBufferInputStream

DataInputStreamLineNumberInputStreamPushbackInputStreamBufferedInputStream有好几个类是专门用来处理文件输入的。下面是文件输入类的层次结构:

5.1FileInputStream对象

FileInputStream典型地表示一种顺序访问的文本文件。通过使用FileInputStream你可以访问文件的一个字节、几个字节或整个文件。

5.2打开FileInputStream

为一个文件打开输入流FileInputStream,你必须将文件名或文件对象传送给结构:

FileInputStreammyFileStream;myFileStream=newFileInputStream("/etc/motd");

你还可以象下边这样从FileInputStream里读文件信息:

FilemyFile;FileInputSteammyFileStream;myFile=newFile("/etc/motd");myFileStream=newFileInputStream(myFile);

一?copy;FileInputStream输入流打开,你就可以从里面读取信息了。read()成员函数有以下几种选项:

lintread()//readsonebyte//return-1atendofstreamlintread(byteb[])//fillsentirearray,ifpossible//returnsnumberofbytesread//returns-1ifendofstreamisreached

lintread(byteb[],intoffset,intlen)//readslenbytesintobstartingatb[offset]//Returnsnumberofbytesread,//or-1ifendofstreamisreached.

5.3关闭FileInputStream

当你完成一个文件的操作,你可选两种方法关闭它:显式关闭和隐式关闭,隐式关闭是自动垃圾回收时的功能。

显式关闭如下:myFileStream.close();

6例程:显示一个文件

如果文件的访问权限足够,你可以在TextArea对象里显示文件内容。

下面是显示文件的程序片断:

FileInputStreamfis;TextAreata;publicvodinit(){byteb[]=newbyte[1024];intI;//makeitbigenoughorwaituntilyou//knowthesizeofthefileStrings;try{fis=newFileInputStream("/etc/motd");}catch(FileNotFoundExceptione){/*dosomethingappropriate*/}try{I=fis.read(b);}catch(IOExceptione){/*dosomethingappropriate*/}s=newString(b,0);ta=newTextArea(s,5,40);add(ta);}

7DataInputStreams

DataInputStreams与FileInputStreams差不多。Data流可以直接读任意一种变量类型,如浮点数,整数和字符等。一般来说,对二进制文件使用DataInputStream流。

7.1打开和关闭DataInputStreams

打开和关闭DataInputStreams对象时,其方法与FileInputStreams相同:

DataInputStreamsmyDataStream;FileInputStreamsmyFileStream;

//getafilehandlemyFileStream=newFileInputStream("/usr/db/stock.dbf");//open,or"chain"adatainputfilemyDataStream=newDataOutputStream(myFileStream);

//Nowwecanusebothinputstreamstoaccessourfile//j(Ifwewantto...)myFileStream.read(b);I=myDataStrea.readInt();

//closethedatafrielexplicityly//Alwaysclosethe"topmost"filestreammyDataStream.close();myFileStream.close();

7.2读DataInputStreams

当你从DataInputStreams流里访问文件时,你可以使用与FileInputStream流相同的成员函数read()。但你也可以使用其他访问方法来读取不同种类的数据:

lbytereadByte()lintreadUnsignedByte()lshortreadShort()lintreadUnsighedShort()lcharreadChar()lintreadIntllongreadLong()lfloatreadFloat()ldoublereadDouble()lStringreadLine()

以上每一个成员函数都读取相应的数据对象。象StringreadLine()成员函数,你可使用\n,\r,\r\n,或EOF作为字符?reg;结束符。

读一个长整型,例如:

longserialNo;...serialNo=myDataStream.readLong();

8URL输入流

除了基本文件访问外,Java还提?copy;了通过网络使用URL访问对象的功能。在下面这个例子里,我们用getDocumentBase()成员函数并显式指定URL对象来访问声音和图象。

StringimageFile=newString("images/Duke/T1.gif");images[0]=getImage(getDocumentBase(),imageFile();

如果我们愿意,可以直接使用URL:URLimageSource;imageSource=newURL("http://555-1212.com/~info");images[0]=getImage(imageSource,"Duke/T1.gif");

我们可以为相应的URL打开输入流。例如,下面的程序里包括一个数据文件:InputStreamis;bytebuffer[]=newbyte[24];is=newURL(getDocumentBase(),dataname).openStream();

现在我们可以使用is,就象使用FileInputStream对象一样:is.read(buffer.0,buffer.length);

注意:有?copy;用户设置了他们的浏览器安全属性,可以不让你的程序访问他们的文件。

9OutputStreams

上面我们谈到了读数据,那么如何实现写数据呢?象输入流一样,输出流也有类似的层次结构:

OutputStream

FileOutputStreamPipedOutputStreamByteArrayOutputStreamFilterOutputStream

DataOutputStreamPrintStreamBufferedOutputStream

我们将分析FileOutputStream和DataOutputStream类来完成我们碰到的输出流问题。其它的输出流包含了更多的信息和成员函数。象输入流的源文件一样,这?copy;文件在$JAVA_HOME/src/java/io目录下。

9.1FileOutputStream类

FileOutputStream对象用于向一个文本文件写数据。象输入文件一样,你得先打开这个文件后才能写这个文件。

9.2打开一个FileOutputStream对象

要打开一个FileOutputStream对象,象打开一个输入流一样,你可以将字符?reg;或文件对象作为参数:FileOutputStreammyFileStream;myFileStream=newFileOutputStream("/etc/motd");

象输入流一样,你也可这样使用:FilemyFile;FileOutputStreammyFileStream;myFile=newFile("/etc/motd");myFileStream=newFileOutputStream(myFile);

9.3写入一个流

一?copy;文件被打开,你便可以使用write()函数向文件里写一?copy;数据。就象输入流的read()函数一样,你可有三种方法:lvoidwrite(intb);//writesoutonebytelvoidwrite(byteb[]);//writesoutentirearraylvoidwrite(byteb[],intoffset,intlength);//writeoutlengthbytesofb[],startingatb[offset]

9.4关闭一个FileOutputStream对象

关闭输出流和关闭输入流方法一样,你可以使用显式方法:myFileStream.close();你也可以让系统自动关闭它。

10例子:存储信息

下面有一个程序,让用户输入一?copy;姓名和电话号码。每一个姓名和号码将加在文件里。用户通过点“Done"按钮来告诉系统整个列表已输入完毕。

一?copy;用户输入完整个列表,程序将创建一个输出文件并显示或打印出来。例如:

555-1212,Tom123-456-7890,PeggyL.234-5678,Marc234-5678,Ron876-4321,Beth&Brian33.1.42.45.70,Jean-Marc

下面是程序的源代码:importjava.io.*;

//Phones.java//Asimpledatabasecreationprogram

classPhones{staticFileOutputStreamfos;publicstaticfinalintlineLength=81;publicstaticvoidmain(Stringargs[])throwsIOExciption{byte[]phone=newbyte[lineLength];byte[]name=newbyte[lineLenght];intI;fos=newFileOutputStream("phone.numbers");while(true){System.err.println("Enteraname(enter'done'toquit)");readLine(name);if("done".equalsIgnoreCase(newString(name,0,0,4))){break;}System.err.println("Enterthephonenumber");readLine(phone);for(i=0;phone[i]!=0;i++){fos.write(phone[i]);}fos.write(',');for(i=0;name[i]!=0;I++){fos.write(name[i]);}fos.write('\n');}fos.close();}

privatestaticvoidreadLine(byteline[])throwsIOException{inti=0,b=0;

while((i<lineLengh-1))&&((b=System.ini.read())!='\n')){line[i++]=(byte)b;}line[i]=(byte)0;}}

11BufferedOutput流

如果你处理的数据量很多,或向文件写很多次小数据,你可以使用一个BufferedOutput流。BufferedOutput流提?copy;和FileOutputStream类同样的写操作方法,但所有输出全部存放在一个缓冲区里。当你填满缓冲区,它将一次性写入磁盘。或者你主动将缓冲区写入磁盘。

11.1创建BufferedOutput流

如果要创建一个BufferedOutput流,首先需要一个FileOutput流。然后将缓冲区链接到FileOutput流:FileOutputStreammyFileStream;BufferedOutputStreammyBufferStream;//getafilehandlemyFileStream=newFileOutputStream("/usr/db/stock.dbf");//chainabufferedoutputstreammyBufferSSstream=newBufferedOutputStream(myFileStream);

11.2更新和关闭BufferedOutput流

和普通FileOutput流一样,向BufferedOutput流里的每一次写操作和写入磁盘操作并不是一一对应的。要想在程序结束?reg;前将缓冲区里的数据写入磁盘,除非填满缓冲区,否则只有显式调用flush()函数://forceleft-overdatatodiskmyBufferStream.flush();//closethedatafileexplicitly//Alwaysclosethe"topmost"filestreammyBufferStream.close();myFileStream.close();

12DataOutput流

和DataInputStream对应,Java还提?copy;了DataOutput流。使用DataOutput流,我们可以向文件写入二进制数据。

12.1打开和关闭DataOutput流对象

打开和关闭DataOutput流对象与打开、关闭FileOutput流对象方法一样:DataOutputStreammyDataStream;FileOutputStreammyFileStream;BufferedOutputStreammyBufferStream;

//getafilehandlemhyFileStream=newFileOutputStream("/usr/db/stock.dbf");//chainabufferedoutputstream(forefficiency);myBufferStream=newBufferedOutputStream(myFileStream);//chainadataoutputfilemyDataStream=newDataOutputStream(myBufferStream);

//Nowwecanusebothinputstreamstoaccessourfile//(iiIfwewantto...)myBufferStream.write(b);myDataStream.writeInt(i);

//closethedatafileexplicitly//Alwayscolsethe"topmost"filestreammyDataStream.close();myBuffersStream.close();myFileStream.close();

12.2向DataOutput流写数据

FileOutput流里的write()函数各种方法都适用于DataOutput流。你还可以看到DataInput流的类似函数方法:lvoidwriteBoolean(booleanv)lvoidwriteByte(intv)lvoidwriteShort(intv)lvoidwriteChar(intv)lvoidwriteInt(intv)lvoidwriteFloat(floatv)lvoidwriteDouble(doublev)lvoidwriteBytes(strings)lvoidwriteChars(strings)

对字符?reg;来说,有两种选择:byte和char。记住byte是8位数据而char是16位数据。如果你想利用Unicode字符的优点,你应使用writeChars()函数。

12.3输出记数

在使用二进制数据输出时常用的另外一个函数是size()。这个函数返回写入文件数据的总字节数。你也可用size()函数将数据文件分成四字节为单位的块,例如:...intbytesLeft=myDataStream.size()%4;for(intI=0;I<bytesLeft;I++){myDataStrea.write(0);}...

13随机访问文件

我们读文件常常不是从头至尾顺序读的。你也许想将一文本文件当作一个数据库,读完一个记录后,跳到另一个记录,它们在文件的不同地方。Java提?copy;了RandomAccessFile类让你操作这种类型的输入输出。

13.1创建随机访问文件

打开随机访问文件有两种方法:l用文件名myRAFile=newRandomAccessFile(Stringname,Stringmode);l用文件对象myRAFile=newRandomAccessFile(Filefile,Stringmode);

mode参数决定了访问文件的权限,如只读'r'或读写'wr'等。

例如,我们打开一个数据库更新数据:RandomAccessFilemyRAFile;myRAFile=newRandomAccessFile("/usr/db/stock.dbf","rw");

13.2访问信息

RandomAccessFile对象的读写操作和DataInput/DataOutput对象的操作方式一样。你可以使用在DataInputStream和DataOutputStream里出现的所有read()和write()函数。

还有几个函数帮助你在文件里移动指针:llonggetFilePointer();返回当前指针lvoidseek(longpos);将文件指针定位到一个绝对地址。地址是相对于文件头的偏移量。地址0表示文件的开头。llonglength();返回文件的长度。地址"length()"表示文件的结尾。

13.3增加信息

你可以使用随机访问文件来设置成增加信息模式:myRAFile=newRandomAccessFile("/tmp/java.log","rw");myRAFile.seek(myRAFile.length());//Anysubsequentwrite()swillbeappendedtothefile

9.13.4追加信息例子下面是一个在已存在文件后面追加字符?reg;的例子:importjava.io.IOException;importjava.io.RandomAccessFile;

classraTest{publicstaticvoidmain(Stringargs[])throwsIOException{RandomAccessFilemyFAFile;Strings="InformationtoAppend\nHimom!\n";//openourrandomaccessfilemyRAFile=newRandomAccessFile("/tmp/java.log","rw");//movetotheendofthefilemyRAFile.seek(myRAFile.length());//Startappending!myRAFile.writeBytes(s);

myRAFile.close();}}
总结:
1.Java通过系统类达到访问标准输入输出的功能。2.你可以创建、读、写文件。

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马