您的位置:首页 > 职场人生

黑马程序员_<<字节流(含子类)和字节缓冲流(InputStream,OutputStream,BufferedInputStream,BufferedOutputStream)>>

2013-10-03 12:53 393 查看
--------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流!--------------------

1.字节流

字符流:Writer,Reader主要是用来操作的是文本文件字节流:InputStream,OutputStream主要是用来操作的是媒体文件,例如:图片,音乐,电影…等。但是也可以操作文件。如果用字符流操作媒体文件的话,复制文件的话:也能复制,只是复制后的图片不能看,因为查看的编码是不一样的,不管是读还是写,都不需要刷新缓冲,除非用到了缓冲对象。

2.FileOutStream

操作文件,向文本文件中写入数据,其没有写入字符串耳朵方法,有字节数组的写入,所以我们要把字符串转换成数组。然后写入。importjava.io.FileNotFoundException; importjava.io.FileOutputStream; importjava.io.IOException; importjava.io.OutputStream; publicclassOutStreamDemo{ publicstaticvoidmain(String[]args){ OutputStreamout=null; try{ out=newFileOutputStream("F:\\demo.txt"); out.write("helloworld".getBytes());//写入数据,把字符串转换为字节数组 }catch(IOExceptione){ e.printStackTrace(); }finally{ if(out!=null){ try{ out.close(); }catch(IOExceptione){ e.printStackTrace(); } } } } }

3.FileInputStream

读取文件,有三种方法,第一种:一个一个字符的读取,第二种:字节数组的读取。
第三种:使用available()方法,读取到文件的总大小,然后定义相同大小的字节数组,读取一次即可,但是加入文件过大,大于了虚拟的内存的大小,那么就会加载不进去,所以最好的办法是定义恰当合适的数组,然后循环读取。

1.单个字节读取

使用的read()方法,进行循环读取。
importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;publicclassInputStreamDemo{publicstaticvoidmain(String[]args){InputStreamin=null;try{in=newFileInputStream("F:\\demo.txt");/*这个为一个一个的读取,使用read()方法,然后读取到的字符的ASCII码,到结尾就返回-1*/intr=-1;while((r=in.read())!=-1){//开始读取System.out.print((char)r);}}catch(IOExceptione){e.printStackTrace();}finally{if(in!=null){try{in.close();//关闭流}catch(IOExceptione){e.printStackTrace();}}}}}

2.字节数组读取

定义恰当的数组,然后循环读取使用的read(byte[]b)
然后转换成字符串,返回。
importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;publicclassInputStreamDemo{publicstaticvoidmain(String[]args){InputStreamin=null;try{in=newFileInputStream("F:\\demo.txt");/*使用字节数组读取,然后转成字符串。到结尾就返回-1*/byte[]b=newbyte[1024];intlen=-1;while((len=in.read(b))!=-1){//开始读取System.out.print(newString(b,0,len));}}catch(IOExceptione){e.printStackTrace();}finally{if(in!=null){try{in.close();//关闭流}catch(IOExceptione){e.printStackTrace();}}}}}

3.固定数组大小

使用的available()方法,读取到文件的大小,然后定义相应的大小的字节数组,如果文件小的话,可以这样使用,但是文件很大,超过了虚拟机的申请的内存,那么就会导致加载不进入,所以最好的方法是是哟第二种方法,定义合适的字节数组的大小。
importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;publicclassInputStreamDemo{publicstaticvoidmain(String[]args){InputStreamin=null;try{in=newFileInputStream("F:\\demo.txt");/*使用字节数组读取,数组的大小用:available()方法定,然后转成字符串。到结尾就返回-1*/byte[]b=newbyte[in.available()];intlen=in.read(b);System.out.print(newString(b,0,len));}catch(IOExceptione){e.printStackTrace();}finally{if(in!=null){try{in.close();//关闭流}catch(IOExceptione){e.printStackTrace();}}}}}

4.复制图片

使用的InputStream和OutputStream步骤:1.使用读取流InputStream,与要读取的图片关联。2.定义写入流,定义好复制到的位置和图片的名称。3.然后一边读取一边写入,循环读取和循环写入。使用的是数组读取和写入。4.最后关闭流。扩展:复制后的文件名称可以改变也可以不变,格式也可以改变,jpg或者bmp.或者其他的格式都可以importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;publicclassOutAndInputStreamDemo{publicstaticvoidmain(String[]args){InputStreamin=null;//读取流字节流OutputStreamout=null;//写入流字节流try{in=newFileInputStream("F:\\A\\1.jpg");//与复制的图片关联起来out=newFileOutputStream("F:\\B\\1.bmp");//与复制到的目的关联起来,这里的图片的名称可以与原来的相同,也可以不一样byte[]b=newbyte[1024];//定义字节数组,并指定长度intl=-1;while((l=in.read(b))!=-1){//读取out.write(b,0,l);//写入,读多少写入多少,所以用write(b,0,len)}System.out.println("复制成功");}catch(IOExceptione){e.printStackTrace();}finally{if(in!=null){try{in.close();//关闭读取流}catch(IOExceptione){System.out.println("读取流关闭失败");}if(out!=null){try{out.close();//关闭写入流}catch(IOExceptione){System.out.println("写入流关闭失败");}}}}}}结果:复制成功

5.字节流的缓冲

字符流:Writer,ReaderBufferedWriter和BufferedReader字节流:InputStream,OutputStream体文BufferedInputStream和BufferedOutputStream字节流的缓冲和字符流的花冲使用方法是类似的,用的对象是BufferedInputStream和BufferedOutputStream,他们增强了字节流的读取和写入效率。

1.利用缓冲对象复制MP3文件

packagewww.fuxi.IO;importjava.io.BufferedInputStream;importjava.io.BufferedOutputStream;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;publicclassBufferedStreamDemo{publicstaticvoidmain(String[]args){BufferedInputStreambis=null;//读取缓冲流BufferedOutputStreambos=null;//写入缓冲流try{bis=newBufferedInputStream(newFileInputStream("F:\\A\\1.mp3"));//要复制的MP3文件bos=newBufferedOutputStream(newFileOutputStream("F:\\B\\1.mp3"));//复制到的目的地byte[]b=newbyte[1024];intlen=0;while((len=bis.read(b))!=-1){//读取bos.write(b,0,len);//写入}System.out.println("复制成功");}catch(Exceptione){e.printStackTrace();}finally{if(bis!=null){try{bis.close();//关闭读取缓冲对象流}catch(IOExceptione){e.printStackTrace();}if(bos!=null){try{bos.close();//关闭写入缓冲对象流}catch(IOExceptione){e.printStackTrace();}}}}}}结果:复制成功

2.模拟读取缓冲区

importjava.io.IOException;importjava.io.InputStream;publicclassMyBufferedInputStream{privateInputStreamin=null;privateintcount=0;//计数器privateintpos=0;//指针privatebyte[]bu=newbyte[1024];//封装的字节数组publicMyBufferedInputStream(InputStreamin){this.in=in;}publicintMyRead()throwsIOException{if(count==0){//说明此时缓冲区中没有数据,可能是缓冲区中还没有开始读取,或者是缓冲区中数据读取完毕count=in.read(bu);//向缓冲区中读取数据if(count<0){return-1;//这里返回的是int类型的-1}pos=0;//每次把指针都初始化byteb=bu[pos];count--;//计数器减一pos++;//指针加一returnb&0xff;//这里b是byte类型,自动提升为整形,但是前面补充的是全是1,为了防止当读取道德byte数据为11111111时,&上0xff,那么使前面的是0,那么这样额可以是原数据不变,又能避免字节数据是-1的情况}elseif(count>0){byteb=bu[pos];count--;//计数器减一pos++;//指针加一returnb&0xff;//这里b是byte类型,自动提升为整形,但是前面补充的是全是1,为了防止当读取道德byte数据为11111111时,&上0xff,那么使前面的是0,那么这样额可以是原数据不变,又能避免字节数据是-1的情况}return-1;}publicvoidmyClose()throwsIOException{in.close();}}importjava.io.BufferedInputStream;importjava.io.BufferedOutputStream;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;/**测试类,也是复制MP3*/publicclassBufferedStreamDemo{publicstaticvoidmain(String[]args){MyBufferedInputStreambis=null;//读取缓冲流BufferedOutputStreambos=null;//写入缓冲流try{bis=newMyBufferedInputStream(newFileInputStream("F:\\A\\1.mp3"));//要复制的MP3文件bos=newBufferedOutputStream(newFileOutputStream("F:\\B\\1.mp3"));//复制到的目的地//byte[]b=newbyte[1024];intr=0;while((r=bis.MyRead())!=-1){//读取bos.write(r);//写入}System.out.println("复制成功");}catch(Exceptione){e.printStackTrace();}finally{if(bis!=null){try{bis.myClose();//关闭读取缓冲对象流}catch(IOExceptione){e.printStackTrace();}if(bos!=null){try{bos.close();//关闭写入缓冲对象流}catch(IOExceptione){e.printStackTrace();}}}}}}结果:复制成功注意点:在MyRead()方法中return返回的必须写b&0xff,因为这样byte类型的提升为整形后,可以保证原数据保持不变,把原来的数据前面相当于添加的0.例如:byte:11111111这是-1自动提升为整形后的数据是11111111111111111111111111111111此时这是-1那么当byte类型的数据是八个1的时候,那么直接返回b,那么提升为整形后是四个八个1,那么还是-1,所以程序直接结束,读取完毕,解决方法是,要是在前面补充的是全是0的话,那么原数据不变没这样也避免的读取-1的情况。11111111111111111111111111111111&00000000000000000000000011111111这是255,-----------------------------------------------------------------00000000000000000000000011111111所以这样结果就是我们想要的数据,既避免了读取byte是11111111的缺点,同时还保证了原数据不变。Read方法是byte类型的提升,从1个字节提升为整形为四个字节。Write方法是把4个字节变成了1个字节,值去最后的一个字节。所以复制后的文件的大小和原来的大小一下,而不是其4倍的大小。

6.键盘读取

importjava.io.IOException;importjava.io.InputStream;publicclassClassDemo{publicstaticvoidmain(String[]args)throwsIOException{/**InputStreamin“标准”输入流:读取的设备是键盘PrintStreamout“标准”输出流。输出到控制台*//**我们可以循环输入,当输入为over时候,结束输入*/InputStreamin=System.in;StringBuilderbu=newStringBuilder();while(true){intch=in.read();if(ch=='\r')continue;if(ch=='\n'){Strings=bu.toString();if("over".equals(s))//如果输入的是over,那么结束输入break;System.out.println("输入的内容是:"+s);bu.delete(0,bu.length());}elsebu.append((char)ch);}}}结果:aa输入的内容是:aabb输入的内容是:bbcc输入的内容是:ccover--------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流!--------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐