黑马程序员_IO流(三)
来源:互联网 发布:java nestedinteger 编辑:程序博客网 时间:2024/05/21 10:15
-------- ASP.Net+Unity开发、.Net培训、期待与您交流! -----------
IO流(三)
PipedOutputStream/PipedIutputStream和PipedWriter/PipedReader(管道流)
前面说到读取流的时候,读取流和写入流之间没有直接的关系,它们之间需要一个数组或者字符串来进行数据之间的传输,管道就解决了读取流和写入流没有直接关系的局面,管道流可以将读取流和写入流接在一起,一边读取,一遍写入。那就要面临一个问题,是读取先还是写入先?由于它们之间的关系就像一根管子,所以要用到多线程执行读取和写,不然会照成死锁(因为read()是一个阻塞方法)。
管道流的一些特性:
可以将连个流直接关联在一起,形如:PipedInputStream(PipedOutputStream src)
在管道输入流中通过参数直接关联到管道输出流,也可以通过connect(PipedOutputStream)方法进行连接。下面的实例启用了两个线程来跑管道流的读取和写入,使用connect的方法将两者连接起来,
实例理解:
package cn.itheima.IO;import java.io.FileInputStream;import java.io.IOException;import java.io.PipedInputStream;import java.io.PipedOutputStream;class PipedInOut {/** * @param args */public static void main(String[] args) throws Exception{// TODO Auto-generated method stubPipedInputStream pis =new PipedInputStream();PipedOutputStream pos = new PipedOutputStream();pis.connect(pos);new Thread(new myread(pis)).start();new Thread(new myWriter(pos)).start();}}class myread implements Runnable{PipedInputStream pis =null;myread(PipedInputStream pis){this.pis=pis;}@Overridepublic void run(){// TODO Auto-generated method stubbyte[] b= new byte[1024];int len=0;try {len=pis.read(b);System.out.println("数据写入管道");System.out.println("等待数据写入。。。。。。");System.out.println("收到的数据位:"+(new String(b,0,len)));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {pis.close();} catch (IOException e) {// TODO Auto-generated catch blockthrow new RuntimeException("管道写入流错误");}}}}class myWriter implements Runnable{PipedOutputStream pos =null;myWriter(PipedOutputStream pos){this.pos = pos;}@Overridepublic void run() {// TODO Auto-generated method stubbyte[] str = "黑马程序员".getBytes();try {Thread.sleep(7000);pos.write(str);}catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {pos.close();} catch (IOException e) {// TODO Auto-generated catch blockthrow new RuntimeException("管道写入流失败");}}}}
RandomAccessFile:
随机访问文件的读取,读、取一体,不属于IO类的继承类,直接继承Object类,但是他却是IO包中的成员,因为他具备了读和写的方法,内部封装了一个数组,可以通过指针获取数组里面的值,可以通过可以通过seek改变指针的位置。通过getFielPionter获取指针的位置。其内部完成读写的操作就是底部封装了读取流和写入流的功能,通过构造函数可知,该流对象只能操作文件,而且操作文件还有模式也就是:"r"、"rw"、"rws" 或"rwd"写错了就报错。如果模式为"r",会去读一个已经存在的文件,文件不存在报告异常,模式里带有”w“,操作的文件不存在,则自动创建,如果存在,不覆盖
了解该类的方法:
read(int a):获取a的最低8位
readInt(int a):获取a的整数值32位
seek(int a):指针向前移动a个字节,a可为负值
sikpByte(int a):向前跳a个字节,只能向前,不能向后
package cn.itheima.IO;import java.io.FileNotFoundException;import java.io.IOException;import java.io.RandomAccessFile;public class RandomAccessFileDemo {/** * @param args * @throws Exception */public static void main(String[] args) throws Exception {// TODO Auto-generated method stubmyWriter();myRead();}private static void myRead() throws IOException {// TODO Auto-generated method stubRandomAccessFile raf = new RandomAccessFile("test.txt", "r");//跳转指针去读数据//raf.seek(8);try {byte[] buf = new byte[4];int len = raf.read(buf);String str = new String(buf,0,len);System.out.println(str);int n = raf.readInt();System.out.println(n);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}raf.close();}private static void myWriter() throws FileNotFoundException, IOException {RandomAccessFile raf = new RandomAccessFile("test.txt", "rw");raf.write("王五".getBytes());raf.writeInt(12);raf.write("李四".getBytes());raf.writeInt(55);raf.close();}}
ByteArrayInputStream/ByteArrayOutputStream
ByteArrayInputStream:其内包括了一个内部缓冲区,关联到源,将源中的数据存入自己的内部缓冲区,关联的是源而已,没有调用底层资源,所以关闭流是无效的(关闭后任然可以调用,也不会产生任何异常)。在构造的时候需要接受数据源,且数据源是一个字节数组,
ByteArrayOutputStream:数据被写入字节数组,缓冲区会随着字节数据的增长而增长,且不用flush,也不涉及底层资源操作,也就不需关闭流。在构造的时候不要定义目的,因为在封装的时候就已近封装了一个可变长的数组,实际上这个数组就是该流的目的。(使用流的思想来操作数组)
实例:
package cn.itheima.IO;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;public class ByteArrayInOut {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stub ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFG".getBytes()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); int len = 0 ; while((len=bis.read())!=-1){ bos.write(len); } System.out.println(bos);}}
相对应的有CharArrayReader/CharArrayWriter:操作字符与StringReader/StringWriter操作字符串,不做详细介绍
字节编码:
关于转换流的的字符编码,就是在进行流的操作的时候指定了固定的编码,在编码和解码是也指定了固定的编码表,有什么编码表编的码就得用什么编码表去解,不然就会得到乱码,就那UTF-8和GBK来说,当向转换流中写入数据的时候,指定的编码是UTF-8,但是在编码的时候指定的GBK,则得到的将会是乱码,反之亦然。原因:使用UTF-8编码,一个字符将会有三个字节表示,也就是说在UTF-8中三个字节表示一个字符,但是在GBK中表示一个字符的只是两个字节,解码的时候如果去查GBK,原本在UTF-8中表示一个字符的三个字节在GBK中只需用到两个就可以表示一个字符,GBK码表拿到两个字节去查询GBK码表,得到的将和UTF-8中的自然不一样。所以说使用什么样的编码表去编码就得使用什么样的编码表去解码,以免出现乱码。
下面的实例是使用GBK编码,使用UTF-8解码导致的结果:
package cn.itheima.IO;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.UnsupportedEncodingException;public class UnicodeDemo {/** * @param args */public static void main(String[] args) throws Exception {// TODO Auto-generated method stubOut();In();}private static void In() throws UnsupportedEncodingException, FileNotFoundException {// TODO Auto-generated method stubInputStreamReader isr =new InputStreamReader(new FileInputStream("test.txt"), "UTF-8");char[] buf =new char[50];int len =0 ;try {len = isr.read(buf);String str = new String(buf,0,len);System.out.println(str);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {isr.close();} catch (IOException e) {// TODO Auto-generated catch blockthrow new RuntimeException("读取失败");}}}private static void Out() throws UnsupportedEncodingException,FileNotFoundException, IOException {OutputStreamWriter osw =newOutputStreamWriter(new FileOutputStream("test.txt"), "GBK");osw.write("黑马程序员");osw.write(97);osw.close();}//运行结果:????????a}
如果想要得到正确的字符,则需要将解码使用的编码改变成为GBK编码,
注意:
如果在使用GBK编码的,而使用的ISO-8859解码,得到的也是乱码,如果想在不改变编码的情况下得到正确的结果,只需把得到的字符再进行一次ISO-8859编码,最后使用GBK解码即可得到正确的结果,原理:ISO-8859解码是一个字节代表一个字符,也就是说它会把GBK编的码一个一个地去查询ISO-8859编码,当然不会改变这些字节地大小,将他再次进行一编码,得到的字节码还是原来GBK所编的码,使用GBK解码当然能得到正确的结果,但是GBK和UTF-8就不一样,比如说只有一个字符,使用GBK编码就只会产生两个字节,但是使用UTF-8解码就需要三个字节,那么UTF-8就会去查询相似的结果,也就会把字节变为三个,就算再用UTF-8编码,GBk解码也不能得到原来的结果了。
-------- ASP.Net+Unity开发、.Net培训、期待与您交流! -----------
- 黑马程序员_IO流(三)
- 黑马程序员_IO流(三)
- 黑马程序员_IO流(三)
- 黑马程序员_IO流(三)
- 黑马程序员_IO(三)
- 黑马程序员_IO流(三)——InputStream,OutputStream
- 黑马程序员_IO流
- 黑马程序员_IO流
- 黑马程序员_IO流
- 黑马程序员_IO流
- 黑马程序员_IO流
- 黑马程序员_IO流
- 黑马程序员_IO流
- 黑马程序员_IO流
- 黑马程序员_IO流
- 黑马程序员_IO流
- 黑马程序员_IO流
- 黑马程序员_IO流
- H.264X相关的一些实用的软件。
- 【换行符读入】#14 A. Letter
- POJ 2653 Pick-up sticks(线段相交)
- HDU 1513 最长公共子序列拓展DP
- hdu 2289 Cup(数学题)
- 黑马程序员_IO流(三)
- python的string操作总结
- <转>贝叶斯推断及其互联网应用(一):定理简介
- Android四大组件--Broadcast Receiver详解
- 深入理解ext2/ext3文件系统真相
- python 学习过程中自己总结的tips
- 用udev绑定裸设备(RHEL5)
- vim显示行号、语法高亮、自动缩进的设置
- NC开发配置环境