`
afunti
  • 浏览: 103864 次
  • 性别: Icon_minigender_1
  • 来自: 安徽
社区版块
存档分类
最新评论

No.10 输入输出流

阅读更多

Java中的流分为两种分别由四个抽象类来表示:
一、字节流  InputStream  OutputStream
二、字符流   Reader,Writer









在这四个抽象类中,InputStream和Reader定义了完全相同的接口:

int read()
int read(char cbuf[])
int read(char cbuf[], int offset, int length)



  而OutputStream和Writer也是如此:

int write(int c)
int write(char cbuf[])
int write(char cbuf[], int offset, int length)



  这六个方法都是最基本的,read()和write()通过方法的重载来读写一个字节,或者一个字节数组。

import java.io.*;

      public class IOStreamDemo {

            public void samples() throws IOException {

                 //1. 这是从键盘读入一行数据,返回的是一个字符串
                 BufferedReader stdin =new BufferedReader(new InputStreamReader(System.in));
                 System.out.print("Enter a line:");
                 System.out.println(stdin.readLine());

                 //2. 这是从文件中逐行读入数据

                 BufferedReader in = new BufferedReader(new FileReader("IOStreamDemo.java"));
                 String s, s2 = new String();
                 while((s = in.readLine())!= null)
                            s2 += s + "\n";
                 in.close();

                 //3. 这是从一个字符串中逐个读入字节
                 StringReader in1 = new StringReader(s2);
                 int c;
                 while((c = in1.read()) != -1)
                            System.out.print((char)c);

                 //4. 这是将一个字符串写入文件
                 try {
                            BufferedReader in2 = new BufferedReader(new StringReader(s2));
                            PrintWriter out1 = new PrintWriter(new BufferedWriter(new FileWriter("IODemo.out")));
                            int lineCount = 1;
                            while((s = in2.readLine()) != null )
                                       out1.println(lineCount++ + ": " + s);
                            out1.close();
                 } catch(EOFException e) {
                            System.err.println("End of stream");
                 }
            }
      } 


对于上面的例子,需要说明的有以下几点:

  1. BufferedReader是Reader的一个子类,它具有缓冲的作用,避免了频繁的从物理设备中读取信息。它有以下两个构造函数:

BufferedReader(Reader in)
BufferedReader(Reader in, int sz)



  这里的sz是指定缓冲区的大小
 2. InputStreamReader是InputStream和Reader之间的桥梁,由于System.in是字节流,需要用它来包装之后变为字符流供给             BufferedReader使用。

  3. PrintWriter out1 = new PrintWriter(new BufferedWriter(new FileWriter("IODemo.out")));

  这句话体现了Java输入输出系统的一个特点,为了达到某个目的,需要包装好几层。首先,输出目的地是文件IODemo.out,所以最内层包装的是FileWriter,建立一个输出文件流,接下来,我们希望这个流是缓冲的,所以用BufferedWriter来包装它以达到目的,最后,我们需要格式化输出结果,于是将PrintWriter包在最外层。

  Java提供了这样一个功能,将标准的输入输出流转向,也就是说,我们可以将某个其他的流设为标准输入或输出流,看下面这个例子:

引用
import java.io.*;

public class Redirecting {

       public static void main(String[] args) throws IOException {
              PrintStream console = System.out;
              BufferedInputStream in = new BufferedInputStream( new FileInputStream( "Redirecting.java"));
              PrintStream out = new PrintStream( new BufferedOutputStream( new FileOutputStream("test.out")));
              System.setIn(in);
              System.setOut(out);

              BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
              String s;
              while((s = br.readLine()) != null)
                     System.out.println(s);
              out.close();
              System.setOut(console);
      }
}



  在这里java.lang.System的静态方法

static void setIn(InputStream in)
static void setOut(PrintStream out)



  提供了重新定义标准输入输出流的方法,这样做是很方便的,比如一个程序的结果有很多,有时候甚至要翻页显示,这样不便于观看结果,这是你就可以将标准输出流定义为一个文件流,程序运行完之后打开相应的文件观看结果,就直观了许多。

  Java流有着另一个重要的用途,那就是利用对象流对对象进行序列化。下面将开始介绍这方面的问题。

  在一个程序运行的时候,其中的变量数据是保存在内存中的,一旦程序结束这些数据将不会被保存,一种解决的办法是将数据写入文件,而Java中提供了一种机制,它可以将程序中的对象写入文件,之后再从文件中把对象读出来重新建立。这就是所谓的对象序列化Java中引入它主要是为了RMI(Remote Method Invocation)和Java Bean所用,不过在平时应用中,它也是很有用的一种技术。

  所有需要实现对象序列化的对象必须首先实现Serializable接口。下面看一个例子:

import java.io.*;
import java.util.*;

public class Logon implements Serializable {

       private Date date = new Date();
       private String username;
       private transient String password;


       Logon(String name, String pwd) {
              username = name;
              password = pwd;
       }


       public String toString() {
              String pwd = (password == null) ? "(n/a)" : password;
              return "logon info: \n " + "username: " + username + "\n date: " + date + "\n password: " + pwd;
       }


       public static void main(String[] args) throws IOException, ClassNotFoundException {
              Logon a = new Logon("Morgan", "morgan83");
              System.out.println( "logon a = " + a);
              ObjectOutputStream o = new ObjectOutputStream( new FileOutputStream("Logon.out"));
              o.writeObject(a);
              o.close();

              int seconds = 5;
              long t = System.currentTimeMillis() + seconds * 1000;
              while(System.currentTimeMillis() < t) ;

              ObjectInputStream in = new ObjectInputStream( new FileInputStream("Logon.out"));
              System.out.println( "Recovering object at " + new Date());
              a = (Logon)in.readObject();
              System.out.println("logon a = " + a);
       }
}



  类Logon是一个记录登录信息的类,包括用户名和密码。首先它实现了接口Serializable,这就标志着它可以被序列化。之后再main方法里ObjectOutputStream o = new ObjectOutputStream( new FileOutputStream("Logon.out"));新建一个对象输出流包装一个文件流,表示对象序列化的目的地是文件Logon.out。然后用方法writeObject开始写入。想要还原的时候也很简单ObjectInputStream in = new ObjectInputStream( new FileInputStream("Logon.out"));新建一个对象输入流以文件流Logon.out为参数,之后调用readObject方法就可以了。

  需要说明一点,对象序列化有一个神奇之处就是,它建立了一张对象网,将当前要序列化的对象中所持有的引用指向的对象都包含起来一起写入到文件,更为奇妙的是,如果你一次序列化了好几个对象,它们中相同的内容将会被共享写入。这的确是一个非常好的机制。它可以用来实现深层拷贝






 

  • 大小: 7.8 KB
  • 大小: 6 KB
  • 大小: 6.3 KB
  • 大小: 6.4 KB
分享到:
评论

相关推荐

    C++实验:输入输出流

    内容1:标准输入输出流重定向 (1) 新建一个工程demo1,设计一个类Time,成员变量为时(h)、分(m)、秒(s)。 (2) 分别为类Time重载提取运算符(&gt;&gt;)和插入运算符(&gt;&gt;)。 a. 输入格式:14 30 15 b. 输出格式:14.5042 (3) ...

    复旦nois教材01.rar

    2.2 创建 Nios 系统模块......................................................................................................10 2.2.1 创建新的 .bdf ........................................................

    base64转码解密成明文加密成Java密文

    Base64 解密成明文,Base64 加密成Java密文. 参数输入输出流 共三个java文件。

    WorkFlow Specify

    流程监控功能.............................................................................................................................10 37. 可同时监控主/子流程(View Sub-Process Status in Monitor ...

    QTP_8_用户手册中文版

    启动QuickTest .....................................................................................10 QuickTest 窗口.......................................................................................

    视频文件分离合成AVI-MuxGUI1.17.8

    作者是德国人 Alexander Noé. 格式支持: 目前支持如下输入格式: 容器: AVI, MKV... 音频流: WAV, MPA/MP3, AC3, DTS, AAC, OGG/Vorbis... 字幕流: SRT, SSA... 目前支持如下输出格式: 容器: AVI, MKV... Raw...

    idea插件.rar

    10.FindBugs 隐藏BUG 11.restfultookit web开发利器 12.Maven Helper maven依赖管理工具 13.aiXcoderservice 一个人工智能技术的提示。 14.MyBatis Log Plugin mybaits sql输出 15.JRebel Plugin 代码热...

    107个常用javascript语句

    26.关闭文档的输出流:document.close(); 27.字符串追加连接符: = 28.创建一个文档元素:document.createElement(),document.createTextNode() 29.得到元素的方法:document.getElementById() 30.设置表单中所有文本型...

    Linux与unix shell编程指南1.rar

    目 录 译者序 前言 第一部分 shell 第1章 文件安全与权限 1 ...18.7.10 while循环和文件描述符 196 18.8 使用break和continue控制循环 197 18.8.1 break 197 18.8.2 跳出case语句 197 18.8.3 continue 197 18.8.4 ...

    LINUX与UNIX SHELL编程指南.rar

    目 录 译者序 前言 第一部分 shell 第1章 文件安全与权限 1 ...18.7.10 while循环和文件描述符 196 18.8 使用break和continue控制循环 197 18.8.1 break 197 18.8.2 跳出case语句 197 18.8.3 continue 197 18.8.4 ...

    语言程序设计课后习题答案

    (1) (2)10 = (10)2 = (2)16 (2) (9)10 = (1001)2 = (9)16 (3) (93)10 = (1011101)2 = (5D)16 (4) (-32)10 = (11100000)2 = (E0)16 (5) (65535)10 = (11111111 11111111)2 = ...

    linux与unix shell编程指南.rar

    linux/unix shell编程指南,全面介绍了Linu/unix shell编程的常用知识和技巧,是不可多得的编程宝典。 目 录 译者序 ...18.7.10 while循环和文件描述符 196 18.8 使用break和continue控制循环 197 18.8.1 ...

    递归法字符变换、求24点

    现在的问题是:对于给定的A,B 及一组字串变换的规则,若A能在10步内(包含10步)变换成B,则输出所需的最短变换步数,否则输出NO ANSWER。 数据范围: 字串A,B长度小于等于20 规则总数小于等于6 输入格式: ...

    linux shell 编程教程

    linux shell编程 教程大全 目 录 译者序 前言 第一部分 shell 第1章 文件安全与权限 1 ...18.7.10 while循环和文件描述符 196 18.8 使用break和continue控制循环 197 18.8.1 break 197 18.8.2 跳出case语句 197 18.8.3 ...

    LINUX 与 UNIX SHELL编程指南

    18.7.10 while 循环和文件描述符 196 18.8 使用 break 和 continue 控制循环 197 18.8.1 break 197 18.8.2 跳出 case 语句 197 18.8.3 continue 197 18.8.4 浏览文件行 198 18.9 菜单 199 18.10 小结 201 第...

    shell 编程指南pdf

    初学shell 入门好书!!!! 目 录 译者序 前言 第一部分 shell 第1章 文件安全与权限 ...18.7.10 while循环和文件描述符 196 18.8 使用break和continue控制循环 197 18.8.1 break 197 18.8.2 跳出case语句 197 18.8.3 ...

    Linux与unix shell编程指南

    18.7.10 while循环和文件描述符 196 18.8 使用break和continue控制循环 197 18.8.1 break 197 18.8.2 跳出case语句 197 18.8.3 continue 197 18.8.4 浏览文件行 198 18.9 菜单 199 18.10 小结 201 第19章 shell函数 ...

    LINUX与UNIX SHELL编程指南(很全)

    非常的全,绝对不会让你后悔。 目 录 译者序 前言 第一部分 shell ...18.7.10 while循环和文件描述符 196 18.8 使用break和continue控制循环 197 18.8.1 break 197 18.8.2 跳出case语句 197 18.8.3 ...

    linux与unix shell 编程(下)

    目 录 译者序 前言 第一部分 shell 第1章 文件安全与权限 1 ...18.7.10 while循环和文件描述符 196 18.8 使用break和continue控制循环 197 18.8.1 break 197 18.8.2 跳出case语句 197 18.8.3 continue 197 18.8.4 ...

    shell教程-30章,下了之后会让你大吃一惊,相当好

    目 录 译者序 前言 第一部分 shell 第1章 文件安全与权限 1 ...18.7.10 while循环和文件描述符 196 18.8 使用break和continue控制循环 197 18.8.1 break 197 18.8.2 跳出case语句 197 18.8.3 continue 197 18.8.4 ...

Global site tag (gtag.js) - Google Analytics