java io 字节流 字符流

来源:互联网 发布:centos搭建lnmp 编辑:程序博客网 时间:2024/06/03 22:09

1.流的概念

在程序中,所有的数据都是以流的形式进行传输和保存的,当程序需要数据的时候要使用输入流读取数据,而当程序需要保存数据时要使用输出流写数据

2.字节流和字符流

字节流:处理单元为1个字节,操作字节和字节数组,在字节流中输出数据用OutputStream,输入使用InputStream

字符流:处理单元为由2个字节组成的Unicode字符,操作字符、字符数组或字符串,在字符流中输出流用Writer,输入流用Reader

二者关系:字符流是Java虚拟机将字节流转化为2个字节的Unicode字符为单位的字符组成的,所以它对多国语言支持性比较好,如果是音频文件、图片、歌曲,就用字节流,如果是关系到中文(文本)的,用字符流好点

区别:1.字节流在操作的时候本身不会用到缓冲区(内存)的,是与文件本身直接操作的,而字符流在操作的时候是使用到缓冲区的

          2.字节流在操作文件时,即使不关闭资源(close方法),文件也能输出,但是如果字符流不使用close方法的话,则不会输出任何内容,说明字符流用的是缓冲            区,并且可以使用flush方法强制进行刷新缓冲区,这时才能在不close的情况下输出内容

          3.在所有的硬盘上保存文件或进行传输的时候都是以字节的方法进行的,包括图片也是按字节完成的,而字符是只有在缓冲区(内存)中才会形成的,所以           使用字节的操作是最多的

4.类常见操作

操作步骤,以文件操作为例,主要流程如下:

 1.使用File类打开一个文件

 2.通过字节流或字符流的子类,指定输出的位置

 3.进行读/写操作

 4.关闭输入/输出

4.1 OutputStream类


4.1.1 FileOutputStream: 文件输出流是向 File 或 FileDescriptor 输出数据的一个输出流。
constructor
(A)FileOutputStream(File name) 创建一个文件输出流,向指定的 File 对象输出数据。
(B)FileOutputStream(FileDescriptor) 创建一个文件输出流,向指定的文件描述器输出数据。
(C)FileOutputStream(String name) 创建一个文件输出流,向指定名称的文件输出数据。
(D)FileOutputStream(String, boolean) 用指定系统的文件名,创建一个输出文件。


4.1.2PipedOutputStream: 管道输出流是指一个通讯管道的发送端。 一个线程通过管道输出流发送数据,

而另一个线程通过管道输入流读取数据,这样可实现两个线程间的通讯。
constructor
(A)PipedOutputStream() 创建一个管道输出流,它还未与一个管道输入流连接。
(B)PipedOutputStream(PipedInputStream) 创建一个管道输出流,它已连接到一个管道输入流。
4.1.3
ByteArrayOutputStream : 把信息存入内存中的一个缓冲区中 . 该类实现一个以字节数组形式写入数据的输出流。
当数据写入缓冲区时,它自动扩大。用 toByteArray() 和 toString() 能检索数据。
constructor
(A)--- ByteArrayOutputStream() 创建一个新的字节数组输出流。
(B)--- ByteArrayOutputStream() 创建一个新的字节数组输出流。
(C)--- ByteArrayOutputStream(int) 创建一个新的字节数组输出流,并带有指定大小字节的缓冲区容量。
toString(String) 根据指定字符编码将缓冲区内容转换为字符串,并将字节转换为字符。

OutputStream是整个IO包中字节输出流的最大父类,此类的定义如下:

public abstract class OutputStream extends Object implements Closeable,Flushable

从以上的定义可以发现,此类是一个抽象类,如果想要使用此类的话,则首先必须通过子类实例化对象,那么如果现在要操作的是一个文件,则可以使用:FileOutputStream类。

    public  void Test1() throws IOException {        File f=new File("d:"+ File.separator+"test.txt");//File.separator 路径分隔符号        OutputStream os=new FileOutputStream(f);//如果文件不存在,会自动创建        String str="hello world!";        byte[] b= str.getBytes(); //因为是字节流,所以要转化为字节数组进行输出        os.write(b);        os.close();    }

也可一个字节一个字节写

    public  void Test2() throws IOException {        File f=new File("d:"+File.separator+"test.txt");        OutputStream os=new FileOutputStream(f,true);//以追加的方式往文件写数据        String str="append";        byte[] b=str.getBytes();        for(int i=0;i<b.length;i++){//一个一个字节进行输出            os.write(b[i]);        }        os.close();    }

4.2 InputStream类



    public void Test3() throws IOException {        File f = new File("d:" + File.separator + "test.txt");        InputStream is=new FileInputStream(f);        byte[] b=new byte[(int)f.length()];        is.read(b); //读取整个字符数组        is.close();        System.out.println(new String(b));    }

或者一个一个字节读取

    public void Test4() throws IOException{        File f=new File("d:"+File.separator+"test.txt");        InputStream is=new FileInputStream(f);        byte[] b=new byte[(int)f.length()];        int len=0;        while(is.read()!=-1){            b[len++]=(byte)is.read();        }        is.close();        System.out.println(new String(b));    }
4.3 Writer类


    public void Test5() throws IOException{        File f=new File("d:"+File.separator+"test.txt");        Writer w=new FileWriter(f,true);        String str="hi";        w.write(str);        w.close();    }

4.4 Reader类


    public void Test6() throws IOException{        File f=new File("d:"+File.separator+"test.txt");        Reader r=new FileReader(f);        char[] ch=new char[1024];        r.read(ch);        r.close();        System.out.println(new String(ch));    }

5.使用原则

一、按数据来源(去向)分类:
1 、是文件: FileInputStream, FileOutputStream, ( 字节流 )FileReader, FileWriter( 字符 )
2 、是 byte[] : ByteArrayInputStream, ByteArrayOutputStream( 字节流 )
3 、是 Char[]: CharArrayReader, CharArrayWriter( 字符流 )
4 、是 String: StringBufferInputStream, StringBufferOuputStream ( 字节流 )StringReader, StringWriter( 字符流 )
5 、网络数据流: InputStream, OutputStream,( 字节流 ) Reader, Writer( 字符流 )
二、按是否格式化输出分:
1 、要格式化输出: PrintStream, PrintWriter
三、按是否要缓冲分:
1 、要缓冲: BufferedInputStream, BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 )
四、按数据格式分:
1 、二进制格式(只要不能确定是纯文本的) : InputStream, OutputStream 及其所有带 Stream 结束的子类
2 、纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer 及其所有带 Reader, Writer 的子类
五、按输入输出分:
1 、输入: Reader, InputStream 类型的子类
2 、输出: Writer, OutputStream 类型的子类
六、特殊需要:
1 、从 Stream 到 Reader,Writer 的转换类: InputStreamReader, OutputStreamWriter
2 、对象输入输出: ObjectInputStream, ObjectOutputStream
3 、进程间通信: PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
4 、合并输入: SequenceInputStream
5 、更特殊的需要: PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader
决定使用哪个类以及它的构造进程的一般准则如下(不考虑特殊需要):
首先,考虑最原始的数据格式是什么: 原则四
第二,是输入还是输出:原则五
第三,是否需要转换流:原则六第 1 点
第四,数据来源(去向)是什么:原则一
第五,是否要缓冲:原则三 (特别注明:一定要注意的是 readLine() 是否有定义,有什么比 read, write 更特殊的输入或输出方法)
第六,是否要格式化输出:原则二

6、是否需要缓冲流 BufferedReader/BufferedWriter
使用缓冲流的好处是,能够高效的读写信息,原理是将数据先缓冲起来,然后一起写入或者读取出来,经常使用的是readLine()方法,表示一次读取一行数据
BufferedOutputStream/BufferedInputStream也是同样的道理
 
原创粉丝点击