`

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。

分享到:
评论

相关推荐

    Java I/O中I/O流的典型使用方式详解

    主要介绍了Java I/O中I/O流的典型使用方式详解,尽管可以通过不同的方式组合IO流类,但我们可能也就只用到其中的几种组合。下面的例子可以作为典型的IO用法的基本参考,,需要的朋友可以参考下

    C和C++串口通讯典型应用实例编程实践

    应用篇通过PC与PC、PC与单片机、PC与智能仪器、PC与PLC、PC与GSM短信模块、PC与远程I/O模块等典型应用实例,详细介绍了C/C++语言利用MSComm控件、API函数实现串口通信的程序设计方法。每个实例的设计任务同时采用C++...

    C/C++串口通信典型应用实例编程实践.(电子工业.曹卫杉)

    应用篇通过PC与PC、PC与单片机、PC与智能仪器、PC与PLC、PC与GSM短信模块、PC与远程I/O模块等典型应用实例,详细介绍了C/C++语言利用MSComm控件、API函数实现串口通信的程序设计方法。每个实例的设计任务同时采用C++...

    C++进阶课程讲义_v1.0.4.pdf

    9.1 I/O流的概念和流类库的结构 51 9.2标准I/O流 53 9.2.1标准输入流 55 9.2.2标准输出流 59 9.3文件I/O 66 9.3.1文件流类和文件流对象 66 9.3.2C++文件的打开与关闭 67 9.3.3C++对ASCII文件的读写操作 69 9.3.4 C++...

    vc6.0 运行库参考手册

    0 的i o s t r e a m 流和运行库, 并用 典型实例说明其用法, 是关于V i s u a l C + + 6 . 0 应用开发的重要参考书。 全书共分成两大个部分:第一部分为i o s t r e a m 类参考,包括i o s t r e a m 编程和i o s...

    Java ppt 教程(精简、易学、易懂、典型例题)

    第一章 Java的基本语法 Java代码的位置 Java 是严格区分大小写的 Java 是一种自由格式语言 注释 标识符 Java中的常量 变量的概念与作用 类型转化 ...1流式I/O基础 2文件 3随机存取文件 4对象输入/输出流

    11AA010串行EEPROM系列数据手册.pdf

    • 单I/O UNI/O®串行接口总线 • 低功耗CMOS技术: - 1 mA工作电流 (典型值) - 1 µA待机电流 (最大值)(工业级温度) • 128 x 8位至2,048 x 8位构成 • 用于抑制噪声的施密特触发器输入 • 用于消除地弹效应...

    面向对象程序设计与Visual C++ 6教程源程序

    并对C++面向对象语言的抽象性、封装性、继承性与多态性进行了全面介绍,内容包括C++语法、函数、类与对象、数组与指针、继承与派生、多态性、模板、I/O流库及异常处理机制。在此基础上,介绍了用Visual C++60开发...

    新编C++习题与解析 3-4章

    本书根据计算机专业C++语言程序设计课程的教学大纲编写,全书共分10章,分别介绍C++语言概述、类和对象、引用、友元、运算符重载、模板、继承和派生、多态性和虚函数、C++的I/O流库和异常处理。每章由基本知识点和...

    linux programming instances网络编程教程 附源代码

    全书由13章组成,内容涉及到Lindx系统编程基础、TCP/UDP协议、套接字编程概念及I/O模型、高级编程中需要用到的进程问通信同步、多路复用、多线程编程和一些高级套接字控制方法、IPv6介绍以及网络安全等。...

    Visual C++/Turbo C串口通信编程实践及源代码-3

    6.1.5 中断i/o通信方式相关设置 171 6.1.6 modem寄存器 172 6.2 comrxtx程序实例 173 6.3 通用实例程序gserial类 175 6.4 用gserial类控制多串口 186 6.5 多串口编程pc机高号中断8259a可编程中断控制器的控制 ...

    JAVA学习笔记2020/4/27——Stream流、方法引用

    说到Stream便容易想到I/O Stream,而实际上,谁规定“流”就一定是“IO流”呢?在Java 8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream概念,用于解决已有集合类库既有的弊端。 1.1 引言 传统集合的...

    Visual C++/Turbo C串口通信编程实践及源代码-2

    6.1.5 中断i/o通信方式相关设置 171 6.1.6 modem寄存器 172 6.2 comrxtx程序实例 173 6.3 通用实例程序gserial类 175 6.4 用gserial类控制多串口 186 6.5 多串口编程pc机高号中断8259a可编程中断控制器的控制 ...

    Visual C++/Turbo C串口通信编程实践 及源代码-1

    6.1.5 中断i/o通信方式相关设置 171 6.1.6 modem寄存器 172 6.2 comrxtx程序实例 173 6.3 通用实例程序gserial类 175 6.4 用gserial类控制多串口 186 6.5 多串口编程pc机高号中断8259a可编程中断控制器的控制 ...

    UNIX 高级教程系统技术内幕

    8.2.5 分散-聚集I/O(Scatter-Garther I/O) 8.2.6 文件加锁 8.3 文件系统 8.3.1 逻辑磁盘 8.4 特殊文件 8.4.1 符号链接 8.4.2 管道和FIFO 8.5 文件系统框架 8.6 vnode/vfs 体系结构 8.6.1 目标 8.6.2 设备 1 门的...

    中国电信DPDK技术白皮书v1.0.pdf

    大量实践表明,通用x86服务器作为NFV基础设施用于高转发业务时,面临着严重的转发性能瓶颈,需要有针对性地从硬件架构、系统I/O、操作系统、虚拟化层、组网与流量调度、VNF功能等层面进行性能优化,才能达到各类NFV...

    Visual C++_Turbo C 串口通信编程实践.(电子工业.龚建伟.熊光明) 第二版 电子版

    6.1.5 中断I/O通信方式相关设置 171 6.1.6 MODEM寄存器 172 6.2 COMRXTX程序实例 173 6.3 通用实例程序GSerial类 175 6.4 用GSerial类控制多串口 186 6.5 多串口编程PC机高号中断8259A可编程中断控制器的控制 195 第...

    visual C++_Turbo C串口通信编程实践

    6.1.5 中断I/O通信方式相关设置 6.1.6 Modem寄存器 6.2 COMRXTX程序实例 6.3 通用实例程序GSerial类 6.4 用GSerial类控制多串口 6.5 多串口编程PC机高号中断8259A可编程中断控制器的控制 第7章 数据...

    2016年电子设计大赛省赛论文

    其中 STM32F103C8T6 是美国意法半导体集团开 发的高性能 32 位微处理器,具有 37 个 I/O 口,集成 64KB 的 Flash,20kB 的 SRAM,主频 72MHz,工作温度 -40 ~ +85℃, 工作电压 2.0 ~ 3.6V,且集成 PWM、IIC、UART...

Global site tag (gtag.js) - Google Analytics