`
ss1
  • 浏览: 80375 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

完全精通java输入输出流

阅读更多

  Java语言的输入输出功能是十分强大而灵活的,美中不足的是看上去输入输出的代码并不是很简洁,因为你往往需要包装许多不同的对象。在Java类库 中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流....本文的目的 是为大家做一个简要的介绍。

  流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据好像在这其中“流”动一样,如下图:

  Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包括输入和输出两种所以一共四个):InputStream,OutputStream,Reader,Writer。Java中其他多种多样变化的流均是由它们派生出来的:



  在这其中InputStream和OutputStream在早期的Java版本中就已经存在了,它们是基于字节流的,而基于字符流的Reader和Writer是后来加入作为补充的。以上的层次图是Java类库中的一个基本的层次体系。

  在这四个抽象类中,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()通过方法的重载来读写一个字节,或者一个字节数组。

  更多灵活多变的功能是由它们的子类来扩充完成的。知道了Java输入输出的基本层次结构以后,本文在这里想给大家一些以后可以反复应用例子,对于所有子类的细节及其功能并不详细讨论。

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. BufferedReaderReader 的一个子类,它具有缓冲的作用,避免了频繁的从物理设备中读取信息。它有以下两个构造函数:

BufferedReader Reader in)
BufferedReaderReader in, int sz)

  这里的sz是指定缓冲区的大小。

  它的基本方法:

void close(//关闭流

           void mark(int readAheadLimit) //标记当前位置

           boolean markSupported() //是否支持标记

           int read() //继承自Reader的基本方法

           int read(char [] cbuf, int off, int len) //继承自Reader的基本方法

           String readLine() //读取一行内容并以字符串形式返回

           boolean ready() //判断流是否已经做好读入的准备

           void reset() //重设到最近的一个标记

           long skip(long n) //跳过指定个数的字符读取

  2. InputStreamReaderInputStreamReader 之间的桥梁,由于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 BufferedInputStreamnew FileInputStream"Redirecting.java" ));
              PrintStream out = new PrintStream ( new BufferedOutputStream new FileOutputStream"test.out" )));
              System.setIn(in);
              System.setOut(out);

              BufferedReader br = new BufferedReadernew 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 ObjectOutputStreamnew FileOutputStream"Logon.out" ));
              o.writeObject(a);
              o.close();

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

              ObjectInputStream in = new ObjectInputStreamnew 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 ObjectOutputStreamnew FileOutputStream"Logon.out" ));新建一个对象输出流包装一个文件流,表示对象序列化的目的地是文件Logon.out。然后用方法writeObject 开始写入。想要还原的时候也很简单ObjectInputStream in = new ObjectInputStreamnew FileInputStream"Logon.out" ));新建一个对象输入流以文件流Logon.out为参数,之后调用readObject方法就可以了。

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

  关键字transient在这里表示当前内容将不被序列化,比如例子中的密码,需要保密,所以没有被写入文件。

  对Java的输入输出功能,就浅浅的介绍到这里,本文的目的只是开一个好头,希望能让大家对Java输入输出流有个基本的认识。

分享到:
评论
1 楼 markxing 2010-08-27  
不错不错,较详细。我一直搞不明白java的输入输出流,看了楼主的文章后感觉思路清晰多了。 收藏,拜谢!

相关推荐

    精通JAVA_SOCKET编程技术

    精通JAVA_SOCKET编程技术 在深入理解JAVA_SOCKET编程技术之前,我们首先需要明确Socket的基本概念及其在Java中的应用。Socket,即套接字,是网络通信的基础,它提供了一种在网络中进行数据交换的方式,使不同计算机...

    精通java核心技术

    《精通Java核心技术》会讲解文件操作、流的概念、套接字通信等内容,使读者能够编写处理数据输入输出和网络通信的程序。 最后,Java的反射机制和注解处理为程序提供了强大的动态特性和元数据功能。书中会介绍如何...

    精通JavaJDK、数据库系统开发Web开发程序源文件

    掌握JavaJDK意味着理解如何配置环境变量,使用命令行工具进行编译和运行,以及了解Java语言的核心特性,如面向对象编程、异常处理、多线程、输入输出流等。 2. **数据库系统开发**: 数据库是存储和管理数据的重要...

    21天精通java.rar

    6. **输入输出流**:讲解文件操作和IO流的概念,包括字节流、字符流、对象流以及NIO(New IO)框架。 7. **线程编程**:介绍并发编程基础,如线程的创建、同步机制(synchronized关键字、wait/notify、Lock接口)、...

    《精通JAVA核心技术》及源代码

    I/O流处理是Java中处理输入输出的重要部分,包括文件操作、网络通信等。Java的流模型允许数据以统一的方式进行读写,无论是磁盘文件还是网络连接。 最后,Java还包含丰富的标准库,如 Swing 和 JavaFX 用于构建图形...

    精通java网络编程

    Java网络编程是开发分布式应用程序的关键技术,它涵盖了网络通信的所有...在"精通Java网络编程"的学习过程中,可能涉及的光盘资料可能包括源代码示例、实战项目、讲解视频等,这些都是加深理解和提升技能的有效资源。

    魔乐科技:从入门到精通Java全部源码

    4. **输入输出流**:IO流的基本概念,字符流和字节流,缓冲流,以及NIO(非阻塞I/O)的概念。 5. **线程编程**:线程的创建方式,同步机制(synchronized,wait(),notify(),锁),线程池的使用。 6. **反射机制*...

    精通Java:JDK、数据库系统开发Web开发(实例代码)

    Java高级技术 第15章 字符串处理 第16章 I/O输入输出流 第17章 线程 第18章 网络程序设计 第19章 国际化和本地化 第20章 泛型程序设计 第21章 访问数据库 第22章 获取XML数据 第23章 ...

    JAVA基础入门到精通pdf

    9. **IO流**:Java的输入/输出(IO)库支持对文件、网络和内存数据的读写操作。流的概念贯穿其中,分为字节流和字符流。 10. **多线程**:Java内置对多线程的支持,通过Thread类或Runnable接口实现并发执行。同步...

    Java入门到精通pdf

    在输入/输出(I/O)和文件操作方面,书籍会教授如何读写文件,使用流进行数据传输,这对于处理文件和网络通信至关重要。同时,读者还将接触到线程和并发编程,理解多线程环境下程序的执行方式,学会如何实现同步和...

    精通Java开发

    8. **输入/输出流**:讨论Java I/O系统,包括文件操作、字节流和字符流,以及缓冲区的概念。同时,还会涵盖File类、InputStream和OutputStream类,以及Reader和Writer类的使用。 9. **附录部分**:通常会包含Java...

    从入门到精通 java编程经典实例

    9. **IO流**:Java的输入/输出系统基于流的概念,提供了处理文件、网络通信等各种数据传输的能力。 10. **多线程**:Java内置了对多线程的支持,通过Thread类或Runnable接口,可以编写并发运行的代码,提高程序效率...

    java学习从入门到精通教程(pdf)

    8. **输入/输出(I/O)**:学习使用Java的I/O流进行文件读写,网络通信等操作,包括FileInputStream、FileOutputStream、BufferedReader、PrintWriter等类的使用。 9. **多线程**:Java支持多线程编程,讲解Thread类...

    Java实例精通源代码

    在IO和网络编程部分,读者将学习到如何使用Java的输入输出流进行文件操作,以及如何构建客户端和服务端的网络通信。这部分内容对于开发需要读写文件或实现网络功能的应用至关重要。 另外,本书的源代码涵盖了GUI...

    JAVA实例精通源代码

    5. **输入输出流**:Java的I/O流用于读写文件、网络通信等。源代码中会涵盖FileInputStream、FileOutputStream、BufferedReader、PrintWriter等类的使用,帮助读者掌握数据的输入输出操作。 6. **多线程**:Java...

    21天精通java

    5. **输入输出流**:掌握I/O流的概念,包括文件操作、对象序列化、网络通信等。 6. **多线程**:理解并发编程,创建和管理线程,同步机制(如synchronized关键字、wait()、notify()方法)以及线程池的使用。 7. **...

    21天精通java源代码

    5. **输入/输出流**:理解I/O流的概念,学习如何进行文件读写,网络通信等操作。 6. **多线程**:Java提供了对多线程的支持,理解线程的创建、同步和通信,可以实现高效的并发处理。 7. **反射机制**:反射是Java...

    精通Java教程

    ### 精通Java教程知识点总结 #### 1. Java 概述 - **定义**:Java 是一种广泛使用的编程语言,提供了从程序开发到部署的一整套解决方案。该语言特别强调网络编程能力,以便更好地利用网络资源。 - **发展历程**:自...

    精通Java核心技术

    7. **输入/输出流**:Java的I/O流系统用于读写文件、网络通信等,包括字节流和字符流,以及缓冲区、转换流等高级特性。 8. **网络编程**:Java提供了丰富的网络编程API,如Socket和ServerSocket,可用于创建客户端...

Global site tag (gtag.js) - Google Analytics