100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 《Java编程思想》Java I/O系统章节阅读笔记

《Java编程思想》Java I/O系统章节阅读笔记

时间:2023-02-10 23:09:51

相关推荐

《Java编程思想》Java I/O系统章节阅读笔记

今天正好要写个小程序需要用到io操作,突然想起来java有个nio一直没用过,就找了点资料研究了一下,顺便做点笔记,以便日后查阅。

-------------------------------------------------------------------------------------------------------------------------------------------

编程语言的I/O类库中常使用流的概念,但它屏蔽了实际的I/O设备中处理数据的细节。在Java中很少使用单一的类来创建流对象,而是通过叠合多个对象来提供所期望的功能(用到了装饰器模式)。InputStream和OutputStream就是用来输入和输出的。在Java1.1中,Reader和Writer利用适配器转换了它们来实现国际化,因为老的I/O流继承结果仅支持8位字节流,不能很好的处理16位的Unicode字符。

文件操作的类:FileInputReader,FileOutputReader,RandomAccessFile。其中RandomAccessFile是一个自我独立的类,虽然可读可写,但都是自己内部实现,并没继承输入输出流的层次结构。在JDK1.4中,其大部分功能已经由nio内存映射文件所取代。

基本的文件输出:FileWriter对象可以向文件写入数据,实际上,我们通常会用BufferedWriter将其包装起来用以缓冲输出,为了提供格式化机制,它又被装饰成PrintWriter。例如:new PrintWriter(new BufferedWriter(new FileWriter(file))),在J2SE 5中甲了一个辅助构造器,可以简写成new PrintWriter(file)。

管道流:PipedInputStream,PipedOutputStream,PipedReader及PipedWriter,它们的价值在多线程中才能体现,因为管道流用于任务之间的通信。

-------------------------------------------------------------------------------------------------------------------------------------------

new I/O:目的是为了提高速度,在新版本的JDK中,旧的I/O也使用nio重新实现,有性能提升。速度的提高来自于所使用的结构更接近于操作系统的执行I/O方式——通道和缓冲器。

流使用getChannel()方法会产生一个FileChannel。通道是一种相当基础的东西:可以向它传送用于读写的ByteBuffer,并且可以锁定文件的某些区域用于独占式访问(后面有提到)。

importjava.nio.*; importjava.nio.channels.*; importjava.io.*; publicclassGetChannel{ privatestaticfinalintBSIZE=1024; publicstaticvoidmain(String[]args)throwsException{ //Writeafile: FileChannelfc= newFileOutputStream("data.txt").getChannel(); fc.write(ByteBuffer.wrap("Sometext".getBytes())); fc.close(); //Addtotheendofthefile: fc=newRandomAccessFile("data.txt","rw").getChannel(); fc.position(fc.size());//Movetotheend fc.write(ByteBuffer.wrap("Somemore".getBytes())); fc.close(); //Readthefile: fc=newFileInputStream("data.txt").getChannel(); ByteBufferbuff=ByteBuffer.allocate(BSIZE); fc.read(buff); buff.flip(); while(buff.hasRemaining()) System.out.print((char)buff.get()); } }

将字节存放于ByteBuffer有2种方法:一是用put方法直接填充一个或多个字节,或基本数据类型;另一种是用warp方法将已存在的字节数组包装到ByteBuffer中。对于只读访问,我们必须显示的使用静态的allocate方法分配ByteBuffer。nio的目标就是快速移动大量数据,因此ByteBuffer的大小就很重要——需要在实际运行的程序中测试来找到最佳值。要达到更高的速度也有可能,方法就是使用allocateDirect()而不是allocate(),以产生一个与操作系统有更高耦合性的“直接”缓冲器,但效果需要实际测试一下。

importjava.nio.*; importjava.nio.channels.*; importjava.io.*; publicclassChannelCopy{ privatestaticfinalintBSIZE=1024; publicstaticvoidmain(String[]args)throwsException{ if(args.length!=2){ System.out.println("arguments:sourcefiledestfile"); System.exit(1); } FileChannelin=newFileInputStream(args[0]).getChannel(); FileChannelout=newFileOutputStream(args[1]).getChannel(); //有一种特殊的办法,将2个通道直接相连 //in=transferTo(0,in.size(),out);或者out=transferFrom(in,0,in.size()); ByteBufferbuffer=ByteBuffer.allocate(BSIZE); while(in.read(buffer)!=-1){ buffer.flip();//Prepareforwriting out.write(buffer); buffer.clear();//Prepareforreading } } }

BufferWriter转换成char型来操作,很不方便,我们利用CharBuffer的toString()方法来转换成String型就方便多了。

importjava.nio.*; importjava.nio.channels.*; importjava.nio.charset.*; importjava.io.*; publicclassBufferToText{ privatestaticfinalintBSIZE=1024; publicstaticvoidmain(String[]args)throwsException{ FileChannelfc= newFileOutputStream("data2.txt").getChannel(); fc.write(ByteBuffer.wrap("Sometext".getBytes())); fc.close(); fc=newFileInputStream("data2.txt").getChannel(); ByteBufferbuff=ByteBuffer.allocate(BSIZE); fc.read(buff); buff.flip(); //Doesn'twork: System.out.println(buff.asCharBuffer()); //Decodeusingthissystem'sdefaultCharset: buff.rewind(); Stringencoding=System.getProperty("file.encoding"); System.out.println("Decodedusing"+encoding+":" +Charset.forName(encoding).decode(buff)); //Or,wecouldencodewithsomethingthatwillprint: fc=newFileOutputStream("data2.txt").getChannel(); fc.write(ByteBuffer.wrap( "Sometext".getBytes("UTF-16BE"))); fc.close(); //Nowtryreadingagain: fc=newFileInputStream("data2.txt").getChannel(); buff.clear(); fc.read(buff); buff.flip(); System.out.println(buff.asCharBuffer()); //UseaCharBuffertowritethrough: fc=newFileOutputStream("data2.txt").getChannel(); buff=ByteBuffer.allocate(24);//Morethanneeded buff.asCharBuffer().put("Sometext"); fc.write(buff); fc.close(); //Readanddisplay: fc=newFileInputStream("data2.txt").getChannel(); buff.clear(); fc.read(buff); buff.flip(); System.out.println(buff.asCharBuffer()); } }

-------------------------------------------------------------------------------------------------------------------------------------------

内存映射文件:它允许我们创建和修改那些因为太大而不能放入内存的文件。

importjava.nio.*; importjava.nio.channels.*; importjava.io.*; importstaticnet.mindview.util.Print.*; publicclassLargeMappedFiles{ staticintlength=0x8FFFFFF;//128MB publicstaticvoidmain(String[]args)throwsException{ MappedByteBufferout= newRandomAccessFile("test.dat","rw").getChannel() .map(FileChannel.MapMode.READ_WRITE,0,length); for(inti=0;i<length;i++) out.put((byte)'x'); print("Finishedwriting"); for(inti=length/2;i<length/2+6;i++) printnb((char)out.get(i)); } }

文件加锁:通过对FileChannel调用tryLock()和lock(),就可以获得整个文件的FileLock。启动tryLock()是非阻塞式的,它设法获取锁,但如果不能获得,将直接放方法调用返回。lock()是阻塞式的,它要阻塞线程直到获得锁,或者调用lock()的线程中断,或者调用lock()的通道关闭。

importjava.nio.channels.*; importjava.util.concurrent.*; importjava.io.*; publicclassFileLocking{ publicstaticvoidmain(String[]args)throwsException{ FileOutputStreamfos=newFileOutputStream("file.txt"); FileLockfl=fos.getChannel().tryLock(); if(fl!=null){ System.out.println("LockedFile"); TimeUnit.MILLISECONDS.sleep(100); fl.release(); System.out.println("ReleasedLock"); } fos.close(); } }

对映射文件的部分加锁:

importjava.nio.*; importjava.nio.channels.*; importjava.io.*; publicclassLockingMappedFiles{ staticfinalintLENGTH=0x8FFFFFF;//128MB staticFileChannelfc; publicstaticvoidmain(String[]args)throwsException{ fc= newRandomAccessFile("test.dat","rw").getChannel(); MappedByteBufferout= fc.map(FileChannel.MapMode.READ_WRITE,0,LENGTH); for(inti=0;i<LENGTH;i++) out.put((byte)'x'); newLockAndModify(out,0,0+LENGTH/3); newLockAndModify(out,LENGTH/2,LENGTH/2+LENGTH/4); } privatestaticclassLockAndModifyextendsThread{ privateByteBufferbuff; privateintstart,end; LockAndModify(ByteBuffermbb,intstart,intend){ this.start=start; this.end=end; mbb.limit(end); mbb.position(start); buff=mbb.slice(); start(); } publicvoidrun(){ try{ //Exclusivelockwithnooverlap: FileLockfl=fc.lock(start,end,false); System.out.println("Locked:"+start+"to"+end); //Performmodification: while(buff.position()<buff.limit()-1) buff.put((byte)(buff.get()+1)); fl.release(); System.out.println("Released:"+start+"to"+end); }catch(IOExceptione){ thrownewRuntimeException(e); } } } }

本文转自passover 51CTO博客,原文链接:/passover/425926,如需转载请自行联系原作者

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。