I/O流典型的使用方式

1、缓冲输入文件

     如果想打开一个文件用于字符输入,可以使用String或者File对象为参数的FileReader。为了提高速度,我们希望对那个文件进行缓冲,那么我们将产生的引用传给一个BufferedReader构造器。由于BufferedReader也提供了readLine()方法,所以这是我们最终对象和进行读取的接口。当readLine()将返回null时,也就达到了文件的末尾。

package io;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedInputFile {
 public static String read(String fileName) throws IOException{
  //BufferedReader的readLine方法每次读取一个字符串
  BufferedReader in = new BufferedReader(new FileReader(fileName));
  String s;
  StringBuilder sb = new StringBuilder();
  while((s = in.readLine()) != null)
   sb.append(s + "\n");
  in.close();
  return sb.toString();
 }
 public static void main(String[] args) throws IOException{
  System.out.println(BufferedInputFile.read("src/io/BufferedInputFile.java"));
 }
}

字符串sb用来累计文件的全部内容(包括必须添加的换行符,因为readLine()已将它们删掉)。

 

2、从内存输入

import java.io.IOException;
import java.io.StringReader;

public class MemoryInput {
 public static void main(String[] args) throws IOException {
  StringReader in = new StringReader(BufferedInputFile
    .read("src/io/MemoryInput.java"));
  int c;
  while ((c = in.read()) != -1)
   System.out.print((char) c);
 }
}

3、格式化的内存输入

要读取格式化数据,可以使用DataInputStream,它是一个面向字节的I/O类(不是面向字符)。因此我们必须使用InputStream类而不是Reader类。

package io;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;

public class FormattedMemoryInput {
 public static void main(String[] args) throws IOException{
  try {
   DataInputStream in = new DataInputStream(new ByteArrayInputStream(
     BufferedInputFile.read("src/io/FormattedMemoryInput.java")
       .getBytes()));
   while(true)
    System.out.print((char)in.readByte());
  } catch (IOException e) {
   System.err.println("End of Stream");
  }
 }
}
    必须为ByteArrayInputStream提供字节数组。

    如果我们从DataInputStream用readByte()一次一个字节的读取字符,那么任何字节的值都是合法的结果,因为返回值不能用来检测输入是否结束。相反,我们可以使用available()方法检查看还有多少可供存取的字符。

package io;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;

public class TestEOF {
 public static void main(String[] args) throws IOException {
  DataInputStream in = new DataInputStream(new ByteArrayInputStream(
    BufferedInputFile.read("src/io/TestEOF.java").getBytes()));
  //available方法來自FilterInputStream,返回的是下一次对此输入流调用的方法
  //可以不受阻塞(或跳过)的估计剩余字节数
  while ((in.available()) != 0)
   System.out.print((char) in.readByte());
 }
}

 

4、基本的文件输出

FileWriter对象可以向文件写入数据。首先,创建一个与指定文件链接的FileWriter。实际上,我们通常会用BufferedWriter将其包装起来用以缓冲输出。

package io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;

public class BasicFileOutput {
 static String file = "BasicFileOutput.out";
 public static void main(String[] args) throws IOException{
  BufferedReader in = new BufferedReader(new StringReader(BufferedInputFile.read("src/io/BasicFileOutput.java")));
  PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file)));

  //也可以用下面的快捷方式

  //PrintWriter out = new PrintWriter(file);
  int lineCount = 1;
  String s;
  while((s = in.readLine()) != null){
   out.println(lineCount++ + ": " + s);
  }
  out.close();
  System.out.println(BufferedInputFile.read(file));
 }
}

一旦读完输入数据流,readLine()就返回null。要为out显示的调用close()。如果我们不为所有的输出文件调用close(),就会发现缓冲区内容不会被刷新清空,那么它们也就不完整。

 

5、存储和恢复数据

PrintWriter可以对数据进行格式化,以便人们阅读。但是为了输出一个可供另一个“流”恢复的数据,我们需要用DataOutputStream写入数据,并用DataInputStream恢复数据。

package io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class StroringAndRecoveringData {
 public static void main(String[] args) throws IOException{
  DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("Data.txt")));
  out.writeDouble(3.14159);
  out.writeUTF("This is PI");
  out.writeDouble(1.41413);
  out.writeUTF("Square root of 2");
  out.close();
  
  DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream("Data.txt")));
  System.out.println(in.readDouble());
  System.out.println(in.readUTF());
  System.out.println(in.readDouble());
  System.out.println(in.readUTF());
 }
}

    如果我们使用DataOutputStream写入数据,Java保证我们可以使用DataInputStream准确读取数据--无论读和写数据的平台多么不同。

     当我们使用DataOutputStream时,写字符串并且让DataInputStream能够恢复它的唯一可靠做法就是使用UTF-8编码,在这里用writeUTF()和readUTF()来实现。UTF-8是一种多字节格式,其编码长度根据实际使用的字符集会有变化。如果我们使用的只是ASCII或者几乎都是ASCII字符(只占7位),那么就显得极其浪费空间和带宽,所以UTF-8将ASCII字符编码成单一字节的形式,而非ASCII字符则编码成两到三个字节的形式。

 

6、从标准输入中读取

    按照标准的I/O模型,Java提供了System.in System.out和System.err。其中System.out已经事先被包装成了printStream对象,System.err也同样如此,但是System.in确实一个没有被包装过的未经加工的InputStream。这意味尽管我们可以立即使用System.out和System.err,但是在读取System.in之前必须对其进行包装。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Echo {
 public static void main(String[] args) throws IOException{
  BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
  String s;
  while((s = reader.readLine()) != null && s.length() != 0)
   System.out.println(s);
 }
}

 

7、标准I/O的重定向

    Java的System类提供了一些简单的静态方法调用,以允许我们对标准输入、输出和错误I/O流进行重定向:

    setIn(InputStream);

    setOut(PrintStream);

    setErr(PrintStream);

   

    如果我们突然开始在显示器上创建大量输出,而这些输出滚动得太快以为无法阅读时,重定向输出就显得极为有用。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;

public class Redirecting {
 public static void main(String[] args) throws IOException{
  PrintStream console = System.out;
  BufferedInputStream in = new BufferedInputStream(new FileInputStream("src/io/Redirecting.java"));
  PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream("redirect.out")));
  System.setIn(in);
  System.setOut(out);
  System.setErr(out);
  BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
  String s;
  while((s = bReader.readLine()) != null)
   System.out.println(s);
  out.close();
  System.setOut(console);
 }
}

    I/O重定向操纵的是字节流,而不是字符流;因此我们使用的是InputStream和OutputStream,而不是Reader和Writer。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值