`

Java的输入输出流

    博客分类:
  • Java
阅读更多

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

 

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

浅谈Java的输入输出流 - zhlhzc@126 - zhlhzc@126的博客

浅谈Java的输入输出流 - zhlhzc@126 - zhlhzc@126的博客

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

浅谈Java的输入输出流 - zhlhzc@126 - zhlhzc@126的博客

浅谈Java的输入输出流 - zhlhzc@126 - zhlhzc@126的博客

浅谈Java的输入输出流 - zhlhzc@126 - zhlhzc@126的博客

浅谈Java的输入输出流 - zhlhzc@126 - zhlhzc@126的博客

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

BufferedReader(Reader in)

 

BufferedReader(Reader 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. 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方法就可以了。

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

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

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

分享到:
评论

相关推荐

    实验9 Java输入输出流.doc

    Java输入输出流是Java编程中一个非常重要的概念,主要用于数据的读取和写入操作,包括文本文件和二进制文件。在实验9中,主要目的是理解和掌握I/O流的分类,以及如何进行文本和二进制文件的读写。 I/O流在Java中被...

    java输入输出流与文件处理

    ### Java输入输出流与文件处理 #### 重要概念与基础知识 **输入输出流与文件处理**在编程领域占据着核心地位,特别是在Java中,通过`java.io`包提供了丰富的类和接口来支持输入输出操作。这包括从键盘读取用户输入...

    java输入输出流,电子课件

    Java输入输出流是Java编程中不可或缺的部分,它用于应用程序与外部设备之间进行数据交换,比如磁盘、网络、键盘和显示器。I/O流是Java中处理输入和输出的基础框架,它提供了一种抽象的方式来处理不同类型的输入源和...

    Java 输入输出流 源码

    Java输入输出流是Java编程语言中的核心概念,用于在程序之间、程序与系统资源之间传输数据。这个主题包括了从磁盘、网络、内存到控制台等不同源和目标的数据读写操作。在这个Java作业中,你将深入理解并实践这一关键...

    java输入输出流的代码示例

    Java输入输出流是Java编程语言中的核心概念,用于在程序之间、程序与文件系统、网络连接等不同数据源之间传输数据。在这个主题中,我们将深入探讨Java输入输出流的使用,通过具体的代码示例帮助你理解和掌握这个关键...

    JAVa输入输出流程序

    Java输入输出流(IO流)是Java编程语言中处理数据传输的核心部分,它允许程序进行数据的读取和写入操作。在Java中,一切皆为流,输入流用于读取数据,而输出流用于写入数据。这些流可以处理各种类型的数据,包括文本...

    java输入输出流.ppt

    Java输入输出流(I/O流)是Java编程中不可或缺的一部分,它主要用于程序与外部资源之间的数据传输。在Java中,I/O流的概念被用来抽象各种输入源和输出目标,包括键盘、显示器、文件、网络连接等。I/O流的设计遵循...

    JAVA输入输出流

    计算机编程语言概述 JAVA的一些基本概念还有变成规则

    java输入输出流

    java输入输出流.ppt,详细介绍java的输入输出流,帮助你快速掌握java

    JAVA输入输出流实验报告

    Java中的输入输出流是程序与外部数据交互的重要方式,它允许我们读取和写入数据到各种来源,如键盘、文件、网络等。在Java中,输入输出流分为两大类:字节流(Byte Stream)和字符流(Character Stream)。本次实验...

    java输入输出流的简单例子

    Java输入输出流是Java IO(Input/Output)体系的基础,它是Java处理数据传输的核心机制。在Java中,一切皆为对象,输入输出流也不例外。Java的输入输出流分为字节流和字符流两大类,每类又分别有输入流和输出流四种...

    java输入输出流的两种写法

    以下是两种常见的Java输入输出流的写法及其详细解释: 1. 字节流: - **FileInputStream** 和 **FileOutputStream**:这是处理文件输入输出的基本字节流类。`FileInputStream` 用于从文件读取字节,而 `...

    java输入输出流和文件操作.pdf

    java输入输出流和文件操作.pdf

    java 输入输出流

    Java中的输入输出流是Java I/O(Input/Output)系统的核心组成部分,允许程序与外部数据源进行交互。在Java中,所有的I/O操作都基于流的概念,流是数据的序列,可以是字节流或字符流。Java I/O库提供了一系列的类来...

    java输入输出流学生成绩管理

    对于"java输入输出流学生成绩管理"这个项目,我们可以推断它是一个使用Java I/O流实现的学生分数管理系统。下面我们将详细探讨Java I/O流的概念、在成绩管理中的应用以及可能的实现方式。 Java I/O流分为四大类:...

    java 输入输出流 实例

    Java输入输出流(I/O流)是Java编程语言中用于处理数据输入和输出的重要机制。在Java中,I/O流允许程序与外部源(如键盘、显示器、文件、网络连接等)交换数据。本实例将深入讲解如何使用Java I/O流进行文件的读取和...

    Java 输入输出流

    Java 输入输出流是Java编程语言中的一个重要组成部分,它允许程序进行数据传输,无论是从本地文件系统、网络连接还是内存中的对象。在Java中,输入输出流(I/O Stream)是处理数据流的一种机制,用于读取和写入数据...

Global site tag (gtag.js) - Google Analytics