zoukankan      html  css  js  c++  java
  • Java IO中字节流与字符流

    Java IO中---字节流与字符流 - 代码改变世界,积累成就自己 - ITeye技术网站

    前面我主要是对IO进行了一个整体上的认识和对File类的相关操作进行了简单的说明。下面主要再来说说Java IO中的字节流和字符流;

    在整个IO包中,流的操作包括了两种-----字符流和字节流;

    字节流:

    字节输入流(InputStream):

    public
    abstract class InputStream extends Object implements Closeable

    字节输出流(OutputStream):

    public
    abstract class OutputStream extends Object implements Closeable, Flushable    

          

    字符流:(一个字符为两个字节)

    字符输入流(Reader):

    public
    abstract class Reader extends Object implements Readable, Closeable

    字符输出流(Writer):

    public
    abstract class Writer extends Object implements Appendable, Closeable,
    Flushable

     

    Java中使用IO操作的步骤:

    使用File找到一个文件;

    使用字符流或字节流的子类为OutputStreamInputStreamWriterReader进行实例化操作;

    进行读或写操作;

    关闭(Close()),在流的操作中必须进行关闭,但BufferedReader例外,我试过;

     

    范例:OutputStream 通过输出流写入内容

     

    Java代码  收藏代码
    1. package com.iflytek.io02;  
    2.   
    3. import java.io.File;  
    4. import java.io.FileOutputStream;  
    5. import java.io.OutputStream;  
    6.   
    7. /** 
    8.  * @author xudongwang 2012-1-8 
    9.  *  
    10.  *         Email:xdwangiflytek@gmail.com 
    11.  */  
    12. public class OutputStreamDemo01 {  
    13.   
    14.     public static void main(String[] args) throws Exception {  
    15.         File file = new File("d:" + File.separator + "demo.txt");// 要操作的文件  
    16.         OutputStream out = null;// 声明字节输出流  
    17.         // out = new FileOutputStream(file);// 通过子类实例化  
    18.         out = new FileOutputStream(file, true);// 表示可以追加j  
    19.         String str = "王旭东\r\n";// 要输出的信息  
    20.         byte b[] = str.getBytes();// 将String变为byte数组  
    21.         out.write(b);// 写入数据  
    22.         // for (int i = 0; i < b.length; i++) {  
    23.         // out.write(b[i]);  
    24.         // }// 通过循环一个个写入  
    25.         out.close();  
    26.     }  
    27. }   

    范例:InputStream 通过输入流来读取内容

    Java代码  收藏代码
    1. package com.iflytek.io02;  
    2.   
    3. import java.io.File;  
    4. import java.io.FileInputStream;  
    5. import java.io.InputStream;  
    6.   
    7. /** 
    8.  * @author xudongwang 2012-1-8 
    9.  *  
    10.  *         Email:xdwangiflytek@gmail.com 
    11.  */  
    12. public class InputStreamDemo01 {  
    13.   
    14.     public static void main(String args[]) throws Exception {  
    15.         File file = new File("d:" + File.separator + "demo.txt");// 要操作的文件  
    16.         InputStream input = null;// 声明字节输入流  
    17.         input = new FileInputStream(file);// 通过子类进行实例化操作  
    18.         byte b[] = new byte[1024];// 开辟空间存储读取的内容  
    19.         int len = input.read(b);// 将内容读取到byte数组中  
    20.         System.out.println(new String(b, 0, len));// 输出内容  
    21.         input.close();  
    22.     }  
    23. }   

      但是读取是一种常见的读取方式,但是上面的代码读取受到开辟空间的限制,所以如果现在想动态的开辟数组空间,则可以根据文件的大小来决定,采用read()方法一个个的读取数据;

     

    范例:read()

    Java代码  收藏代码
    1. package com.iflytek.io02;  
    2.   
    3. import java.io.File;  
    4. import java.io.FileInputStream;  
    5. import java.io.InputStream;  
    6.   
    7. /** 
    8.  * @author xudongwang 2012-1-8 
    9.  *  
    10.  *         Email:xdwangiflytek@gmail.com 
    11.  */  
    12. public class InputStreamDemo02 {  
    13.     public static void main(String args[]) throws Exception {  
    14.         File file = new File("d:" + File.separator + "demo.txt");  
    15.         InputStream input = new FileInputStream(file);  
    16.         byte b[] = new byte[(int) file.length()];// 开辟空间接收读取的内容  
    17.         for (int i = 0; i < b.length; i++) {  
    18.             b[i] = (byte) input.read();// 一个个的读取数据  
    19.         }  
    20.         System.out.println(new String(b));// 输入内容,直接转换  
    21.         input.close();// 关闭  
    22.     }  
    23. }  

    范例:Writer

    Java代码  收藏代码
    1. package com.iflytek.io02;  
    2.   
    3. import java.io.File;  
    4. import java.io.FileWriter;  
    5. import java.io.IOException;  
    6. import java.io.Writer;  
    7.   
    8. /** 
    9.  * @author xudongwang  2012-1-8 
    10.  * 
    11.  *  Email:xdwangiflytek@gmail.com 
    12.  */  
    13. public class WriterDemo {  
    14.     public static void main(String args[]) throws IOException {  
    15.         File file = new File("d:" + File.separator + "demo.txt");  
    16.         Writer out = null;// 声明字符输出流  
    17. //      out = new FileWriter(file);// 通过子类实例化  
    18.         out = new FileWriter(file,true);//表示可以追加  
    19.         String str = "王旭东\r\n";// 要输出的信息  
    20.         out.write(str);// 写入数据  
    21.         out.close();  
    22.     }  
    23. }  

     范例:Reader

    Java代码  收藏代码
    1. package com.iflytek.io02;  
    2.   
    3. import java.io.File;  
    4. import java.io.FileReader;  
    5. import java.io.IOException;  
    6. import java.io.Reader;  
    7.   
    8. /** 
    9.  * @author xudongwang 2012-1-8 
    10.  *  
    11.  *         Email:xdwangiflytek@gmail.com 
    12.  */  
    13. public class ReaderDemo {  
    14.     public static void main(String args[]) throws IOException {  
    15.         File file = new File("d:" + File.separator + "demo.txt");  
    16.         Reader input = null;  
    17.         input = new FileReader(file);  
    18.         char c[] = new char[1024];  
    19.         int len = input.read(c);  
    20.         System.out.println(new String(c, 0, len));  
    21.         input.close();  
    22.     }  
    23. }  

     或者通过一个个读取:

    Java代码  收藏代码
    1. package com.iflytek.io02;  
    2.   
    3. import java.io.File;  
    4. import java.io.FileReader;  
    5. import java.io.IOException;  
    6. import java.io.Reader;  
    7.   
    8. /** 
    9.  * @author xudongwang  2012-1-8 
    10.  * 
    11.  *  Email:xdwangiflytek@gmail.com 
    12.  */  
    13. public class ReaderDemo02 {  
    14.     public static void main(String args[]) throws IOException {  
    15.         File file = new File("d:" + File.separator + "demo.txt");  
    16.         Reader input = null;  
    17.         input = new FileReader(file);  
    18.         char c[] = new char[(int) file.length()];  
    19.         for (int i = 0; i < c.length; i++) {  
    20.             c[i] = (char) input.read();// 一个个读取  
    21.         }  
    22.         System.out.println(new String(c));  
    23.         input.close();  
    24.     }  
    25. }  

     下面我们来通过一组实例来观察字节流与字符流的区别:此程序就是向文件中保存内容

    范例:字节流OutputStream实现:

    Java代码  收藏代码
    1. package com.iflytek.io02;  
    2.   
    3. import java.io.File;  
    4. import java.io.FileOutputStream;  
    5. import java.io.IOException;  
    6. import java.io.OutputStream;  
    7.   
    8. /** 
    9.  * @author xudongwang  2012-1-8 
    10.  * 
    11.  *  Email:xdwangiflytek@gmail.com 
    12.  */  
    13. public class OutputStreamDemo {  
    14.     public static void main(String args[]) throws IOException {  
    15.         File file = new File("d:" + File.separator + "demo.txt");  
    16.         OutputStream out = new FileOutputStream(file);  
    17.         String str = "java";  
    18.         byte b[] = str.getBytes();  
    19.         out.write(b);  
    20.     }  
    21. }  

     注意:以上的操作并没有进行关闭操作,发现内容却可以正常的输出;

    范例:字符流Writer实现

    Java代码  收藏代码
    1. package com.iflytek.io02;  
    2.   
    3. import java.io.File;  
    4. import java.io.FileWriter;  
    5. import java.io.IOException;  
    6. import java.io.Writer;  
    7.   
    8. /** 
    9.  * @author xudongwang  2012-1-8 
    10.  * 
    11.  *  Email:xdwangiflytek@gmail.com 
    12.  */  
    13. public class WriterDemo02 {  
    14.     public static void main(String args[]) throws IOException{  
    15.         File file = new File("d:" + File.separator + "demo.txt");  
    16.         Writer out = new FileWriter(file);  
    17.         String str = "java";  
    18.         out.write(str);  
    19.     }  
    20. }  

     此时,字符流中也没有进行流的关闭操作,但与字节流不同的是,字符流并没有将内容成功的写入进去。如果此时在字符流操作的最后加入out.flush()操作,则可以成功的写入;

    此时来看可以知道因为早期只有字节流,换而言之,也就是说早期是没有刷新操作的,但是因为使用了关闭,所以表示会强制刷新,注意的是其中刷新的是缓冲区(内存),但是这里我认为任何流只要初始化了最后都将其关闭了,这是一种习惯,注此处除了BufferedReader

    此时可以得到这样的一个结论:

    字节流在操作的时候是直接与文件本身进行关联的,不使用缓冲区

                  · 字节文件  字节流直接实现底层的IO操作;

           字符流在操作的时候是通过缓冲区与文件进行操作的,使用缓冲区

                  · 字符缓冲文件

           综上比较来说,在传输或者在硬盘上保存的内容都是以字节的形式存在,所以字节流操作较多,但是在操作文件的时候字符流比较好使

     

    内存操作流

    其主要是保存临时文件,通过内存操作流输入输出的目标是内存。使用ByteArrayInputStream(从程序向内存写入)和ByteArrayOutputStream(从内存向程序输出)完成内存的操作流。在内存操作流中所有的输入和输出都是以内存为操作源头的;

    范例:通过内存流完成字符串小写变为大写的操作;

    Java代码  收藏代码
    1. package com.iflytek.io02;  
    2.   
    3. import java.io.ByteArrayInputStream;  
    4. import java.io.ByteArrayOutputStream;  
    5.   
    6. /** 
    7.  * @author xudongwang  2012-1-8 
    8.  * 
    9.  *  Email:xdwangiflytek@gmail.com 
    10.  */  
    11. public class ByteArrayInputStreamDemo {  
    12.     public static void main(String args[]) {  
    13.         String str = "hello world!";  
    14.         ByteArrayInputStream bis = null;// 内存输入流,从程序向内存写入  
    15.         ByteArrayOutputStream bos = null;// 内存输出流  
    16.         bis = new ByteArrayInputStream(str.getBytes());// 将内存保存在内存中  
    17.         bos = new ByteArrayOutputStream();  
    18.         int temp = 0;  
    19.         while ((temp = bis.read()) != -1) {// 依次读取  
    20.             char c = (char) temp;  
    21.             bos.write(Character.toUpperCase(c));// 输出  
    22.         }  
    23.         String newStr = bos.toString();// 取出内存输出的内容  
    24.         System.out.println(newStr);  
    25.     }  
    26. }  

     注意,虽然内存流在J2EE阶段没什么感觉,但是在Java WEB中的Ajax技术中会结合XML解析和JavaScriptAjax完成一些动态效果;

     

    管道流:

    管道流就是进行两个线程间通讯,使用PipedInputStreamPipedOutputStream两个类完成,这两个类在使用上基本上跟InputStreamOutputStream类似,唯一的区别在于连接管道的操作上public void connect(PipedOutputStream src) throws IOException,此处就暂时不举例了;

     

    打印流:

    PrintStreamPrintWriter

    public
    class PrintStream extends FilterOutputStream implements Appendable, Closeable

    从上面可知,PrintStreamOutputStream的子类,而实际上,PrintStream类属于装饰,也就是说根据实例化PrintStream类对象的不同,输出的位置也不同;

    范例:使用PrintStream向文件输出

    Java代码  收藏代码
    1. package com.iflytek.io02;  
    2.   
    3. import java.io.File;  
    4. import java.io.FileOutputStream;  
    5. import java.io.PrintStream;  
    6.   
    7. /** 
    8.  * @author xudongwang  2012-1-8 
    9.  * 
    10.  *  Email:xdwangiflytek@gmail.com 
    11.  */  
    12. public class PrintStreamDemo {  
    13.     public static void main(String args[]) throws Exception {  
    14.         File file = new File("d:" + File.separator + "demo.txt");  
    15.         PrintStream ps = new PrintStream(new FileOutputStream(file));  
    16.         ps.print("hello");  
    17.         ps.print("world");  
    18.         ps.print(10);  
    19.         ps.print(10.0);  
    20.         ps.close();  
    21.     }  
    22. }  

     此处,发现使用打印流输出比较方便,所以建议以后都使用打印流完成输出;

    JDK1.5之后打印流可以使用格式化输出

    public
    PrintStream format(String format,Object... args)

    Java代码  收藏代码
    1. package com.iflytek.io02;  
    2.   
    3. import java.io.File;  
    4. import java.io.FileOutputStream;  
    5. import java.io.PrintStream;  
    6.   
    7. /** 
    8.  * @author xudongwang  2012-1-8 
    9.  * 
    10.  *  Email:xdwangiflytek@gmail.com 
    11.  */  
    12. public class PrintStreamFormatDemo {  
    13.     public static void main(String args[]) throws Exception {  
    14.         File file = new File("d:" + File.separator + "demo.txt");  
    15.         PrintStream out = new PrintStream(new FileOutputStream(file));    
    16.         String name = "王旭东";  
    17.         int age = 21;  
    18.         float score = 99.0f;  
    19.         char sex = 'N';  
    20.         out.printf("姓名:%s;年龄:%d;成绩:%5.2f;性别:%c。",name,age,score,sex);  
    21.         out.close();  
    22.     }  
    23. }  

     这里需要注意,在打印流中始终记住一下原则:

           · 根据实例化其子类的不同,完成的打印输出功能也不同

     

    SystemIO的支持:

    System.in:它是PrintStream的实例,常用的方法就是向屏幕上打印信息,当然如果使用System.out的话也可为OutputStream实例化

    System.err:表示错误的输出

    Java代码  收藏代码
    1. package com.iflytek.io02;  
    2.   
    3. /** 
    4.  * @author xudongwang  2012-1-8 
    5.  * 
    6.  *  Email:xdwangiflytek@gmail.com 
    7.  */  
    8. public class SystemerrDemo {  
    9.     public static void main(String args[]) {  
    10.         try {  
    11.             Integer.parseInt("hello");  
    12.         } catch (Exception e) {  
    13.             System.out.println(e);//e打印出来是黑字  
    14.             System.err.println(e);//e打印出来是红字  
    15.         }  
    16.     }  
    17. }  

     其区别只能从概念上讲:

           System.out:一般的信息是愿意展示给用户看见的;

           System.err:一般的信息是不愿意展示给用户看见的;

           System.in:表示键盘的输入;

     

    Java代码  收藏代码
    1. package com.iflytek.io02;  
    2.   
    3. import java.io.InputStream;  
    4.   
    5. /** 
    6.  * @author xudongwang  2012-1-8 
    7.  * 
    8.  *  Email:xdwangiflytek@gmail.com 
    9.  */  
    10. public class SystemInDemo {  
    11.     public static void main(String args[]) throws Exception {  
    12.         InputStream input = System.in;  
    13.         System.out.println("请输入内容:");  
    14.         int temp = 0;  
    15.         StringBuilder bud = new StringBuilder();  
    16.         while ((temp = input.read()) != -1) {  
    17.             char c = (char) temp;  
    18.             if (c == '\n') {  
    19.                 break;  
    20.             }  
    21.             bud.append(c);  
    22.         }  
    23.         System.out.println("输入的内容是:" + bud);  
    24.     }  
    25. }  

     虽然此时读取时没有长度但此处注意的是每次读取的是字节,所以在输入中文时会出现错误,只能通过后面的BufferedReader来实现;

    重定向问题:

    · System.outSystem.err都有固定的输出目标,都是屏幕。而System.in有固定的输入目标,都是键盘;但是在System类中提供了一系列的输入输出重定向,可以改变System.outSystem.erSystem.in的输入输出位置。

           · System. out重定向:public static void setOut(PrintStream out)

           · System.err重定向:public static void setErr(PrintStream err)

           · System.in重定向:public static void setIn(InputStream in)

     

    BufferedReader

    实际上表示缓冲区读取,可以一次性的将内容全部读取出来

    其构造方法:public BufferedReader(Reader in)

           注意:在Java中提供了两个专门的类,去实现字节流与字符流的转换:

                  · InputStreamReader:将字节的输入流变为字符输入流;

    文件字节流(输入流)字符流(输入流)控制台   

                  · OutputStreamWriter:将字符的输出流变为字节的输出流;

    程序字符流(输出流)字节流(输出流)文件      

    通过public String readLine()throws IOException来读取数据,表示一次性读取一行数据,而且这里需要注意的是如果返回的内容是String是最好的操作;

  • 相关阅读:
    转 Hystrix超时实现机制
    Hystrix实现ThreadLocal上下文的传递 转
    MongoDB里做表间关联
    转载:mongodb的两阶段提交实战
    MongoDB中的读写锁
    Mongodb中的 原子性 隔离性
    web服务优化
    MongoDB分片(Sharding)技术
    MongoDB复制集
    consul分布式集群搭建
  • 原文地址:https://www.cnblogs.com/lexus/p/2370497.html
Copyright © 2011-2022 走看看