1/0流的典型使用方式                                    
 
1.缓冲输入文件
package com.java.io;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException; public class BufferedInputFile {
public static String read(String pathname) throws IOException {
BufferedReader in = new BufferedReader(new FileReader(new File(pathname)));
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.print(read("src/com/java/io/BufferedInputFile.java"));
}
}

console将当前的BufferedInputFile.java文件原封不动的打印出来;

2 从内存输入
package com.java.io;

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/com/java/io/MemoryInput.java"));
int c; //read是以int形式返回下一字节,因此必须类型转换为char才能正确打印。
//read()一个字符一个字符的读的。 Reads a single character.
while((c=in.read()) != -1){
System.out.print((char) c);
}
}
}
3 格式化的内存输入
要读取格式化数据 可以使用DataInputStream 它是一个面向字节的I/O类(不是面向字符的)。
因此我们必须使用InputSteam类而不是Reader类,当然我们可以用InputStream以字节的形式读取任何数据(例如一个文件)
不过,在这里使用的是字符串。
package com.java.io;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
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/com/java/io/FormattedMemoryInput.java").getBytes()));
while(true){
byte b = in.readByte();
System.out.print((char) b);
}
} catch (EOFException e) {
System.err.println("End of stream") ;
}
}
}
使用available方法查看还有多少可供读取的字符:
package com.java.io;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException; public class TestEOF {
public static void main(String[] args) throws IOException{
DataInputStream in = new DataInputStream(
new BufferedInputStream(
new FileInputStream("src/com/java/io/TestEOF.java")));
while(in.available() != 0){
System.out.print((char)in.readByte());
} }
}
注意. available的工作方式会随着所读取的媒介类型的不同而有所不同,学面意思就是"在没有阻塞的情况下所能读取的字节数“。
对于文件,这意味着整个文件,但是对于不问类型的流,可能就不是这样的,因此要谨慎使用。
 

4 基本的文件输出:
FileWriter对象可以向文件写入数据,首先,创建一个与指定文件连接的FileWriter。
实际上,我们通常会用BufferedWriter将其包装起来用以缓冲输出〈尝式移除此包装来感受对性能的影响--缓冲往往能显著的增加IO操作
的性能)。在本例中,为了提供格式化机制,它被装饰成PrintWriter,按照这种方式创建的数据文件可作为普通文本文件读取。
package com.java.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; /**
* 一旦读完输入数据流, readLine()会返回null。
* 我们可以看到要为out显式调用c1ose.如果我们不为所有的输出文件调用close()
* 就会发现缓冲区内容不会被刷新清空 那么它们也就不完整。
*/
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/com/java/io/BasicFileOutput.java")));
PrintWriter out = new PrintWriter(
new BufferedWriter(new FileWriter(file))); int lineCount = 1;
String s;
while((s = in.readLine()) != null ){
out.println(lineCount++ + ": " + s);
}
out.close();
System.out.println(BufferedInputFile.read(file));
}
}
 
文本文件输出的快捷方式
Java SE5在PrintWriter 中添加了-个辅助构造器,使得你不必在每次希望创建文本文件并向其中写入时,都去执行所有的装饰工作。下面是用这种快捷方式重写的BasicFileOutput.java :
package com.java.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader; public class FileOutputShortcut {
static String file = "FileOutputShortcut.out";
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(
new StringReader(BufferedInputFile.read("src/com/java/io/FileOutputShortcut.java")));
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));
}
}

5 存储和恢复数据
PrintWriter可以对数据进行格式化,以便人们的阅读。但是为了输出可供另一个"流"恢
复的数据,我们需要用DataOutputStream写入数据,并用DatalnputStream恢复数据.
package com.java.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 StoringAndRecoveringData {
public static void main(String[] args) throws IOException {
DataOutputStream out = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("Data.txt")));
out.writeDouble(3.14159);
out.writeUTF("That was 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());
// Only readUTF() will recover the
// Java-UTF String properly:
System.out.println(in.readUTF());
System.out.println(in.readDouble());
System.out.println(in.readUTF());
}
}
当我们使用DataOutputStream肘,写字符串并且让DataInputStream能够恢复它的唯一可靠的做法就是使用UTF-8编码
在这个示例中是用writeUTF和readUTF来实现的。
有了writeUTFO 和readUTFO ,我们就可以用DataOutputStream把字符串和其他数据类型相混合,我们知道字符串完全可以作为Unicode来存储,
并且可以很容易地使用DataInputStream来恢复它。
 

6 读写随机访问文件
使用RandomAccessFile , 类似于组合使用了DataInputStream和DataOutputStream (因为
它实现了相同的接曰: DataInput和DataOutput) 。另外我们可以看到,利用seek()可以在文件中
到处移动,并修改文件中的某个值。
package com.java.io;

import java.io.IOException;
import java.io.RandomAccessFile; public class UsingRandomAccessFile {
static String file = "rtest.dat";
static void display() throws IOException {
//我们可指定以"只读"( r ) 方式或"读写" ( rw ) 方式打开一个RandomAccessFile文件。
RandomAccessFile rf = new RandomAccessFile(file, "r");
for(int i = 0; i < 7; i++){
System.out.println("Value " + i + ": " + rf.readDouble());
}
System.out.println(rf.readUTF());
rf.close();
}
public static void main(String[] args) throws IOException {
RandomAccessFile rf = new RandomAccessFile(file, "rw");
for(int i = 0; i < 7; i++){
rf.writeDouble(i*1.414);
}
rf.writeUTF("The end of the file");
rf.close();
display();
rf = new RandomAccessFile(file, "rw"); //因为double总是8字节长,所以为了用Seek查找第5个双精度值,你只需用5*8来产生查找位置。
rf.seek(5*8);
rf.writeDouble(47.0001);
rf.close();
display();
}
}

7 管道流
PipedlnputStream 、PipedOutputStream 、PipedReader及PipedWriter在本章只是简单地提到。但这并不表明它们没有什么用处,它们的价值只有在我们开始理解多钱程之后才会显现,因为管道流用于任务之间的通信。这些在第2l:'!1旨'会用一个示例进行讲述。
 
 
文件读写的实用工具                                
-个很常见的程序化任务就是读取文件到内存,修改,然后再写出。Java 110类库的问题之19361
一就是:它需要编写相当多的代码去执行这些常用操作一一设有任何基本的帮助功能可以为我们
做这一切。更糟糕的是,装饰器会使得要记住如何打开文件变成一件相当困难的事。因此,在
我们的类库中添加帮助类就显得相当有意义,这样就可以很容易地为我们完成这些基本任务。
 
下面的TextFile类在本书前面的示例中就已经被用来简化对文件的读写操作了。它包含的
static方法可以像简单字符串那样读写文本文件,并且我们可以创建一个TextFile对象,它用一
个ArrayList来保存文件的若干行(如此,当我们操纵文件内容时,就可以使用ArrayList的所
有功能)。

// Static functions for reading and writing text files as
// a single string, and treating a file as an ArrayList.
package com.java.io; import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.TreeSet; public class TextFile extends ArrayList<String> {
// Read a file as a single string:
public static String read(String fileName) {
StringBuilder sb = new StringBuilder();
try {
BufferedReader in= new BufferedReader(new FileReader(
new File(fileName).getAbsoluteFile()));
try {
String s;
while((s = in.readLine()) != null) {
sb.append(s);
sb.append("\n");
}
} finally {
in.close();
}
} catch(IOException e) {
throw new RuntimeException(e);
}
return sb.toString();
} // Write a single file in one method call:
public static void write(String fileName, String text) {
try {
PrintWriter out = new PrintWriter(
new File(fileName).getAbsoluteFile());
try {
out.print(text);
} finally {
out.close();
}
} catch(IOException e) {
throw new RuntimeException(e);
}
} public void write(String fileName) {
try {
PrintWriter out = new PrintWriter(
new File(fileName).getAbsoluteFile());
try {
for(String item : this)
out.println(item);
} finally {
out.close();
}
} catch(IOException e) {
throw new RuntimeException(e);
}
} // Read a file, split by any regular expression:
public TextFile(String fileName, String splitter) {
super(Arrays.asList(read(fileName).split(splitter)));
// Regular expression split() often leaves an empty
// String at the first position:
if(get(0).equals("")){
remove(0);
}
} // Normally read by lines:
public TextFile(String fileName) {
this(fileName, "\n");
} public static void main(String[] args) {
String file = read("src/com/java/io/TextFile.java");
write("test.txt", file);
TextFile text = new TextFile("test.txt");
text.write("test2.txt"); // Break into unique sorted list of words:
//TreeSet是有序的set
//\\W+以非单词分割,得到的都是单词list,TextFile本身就是一个ArrayList,组成了TextFile;
//TreeSet的构造函数 TreeSet<集合>
TreeSet<String> words = new TreeSet<String>(new TextFile("src/com/java/io/TextFile.java", "\\W+")); // Display the capitalized words:
//打印出TreeSet中小于'a'的,就是打印出大写字母的
System.out.println(words.headSet("a"));
}
}

输出:

[0, ArrayList, Arrays, Break, BufferedReader, Display, File, FileReader, IOException, List, Normally, PrintWriter, Read, Regular, RuntimeException, Static, String, StringBuilder, System, TextFile, TreeSet, W, Write]
注意
在任何打开文件的代码在finaUy子句中,作为防卫措施都添加了对文件的closeO调用,以保证文件将会被正确关闭。
因为这个类希望将读取和写入文件的过程简单化,因此所有的IOException都被转型为RuntimeException ,
因此用户不必使用try-catch语句块。但是,你可能需要创建另一种版本将IOException传递给调用者。
另一种解决读取文件问题的方法是使用在Java SE5中引入的java.util.scanner类.但是,这
只能用于读取文件,而不能用于写入文件,并且这个工具(你会注意到它不在java.io包中)主
要是设计用来创建编程语言的扫描器或"小语言"的。
 

读取二进制文件                                
这个工具与TextFile类似,因为它简化了读取二进制文件的过程:
package com.java.io;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; public class BinaryFile {
public static byte[] read(File bFile) throws IOException{
BufferedInputStream bf = new BufferedInputStream(
new FileInputStream(bFile));
try {
byte[] data = new byte[bf.available()];
bf.read(data);
return data;
} finally {
bf.close();
}
}
public static byte[] read(String bFile) throws IOException {
return read(new File(bFile).getAbsoluteFile());
}
}
其中一个重载方法接受File参数,第二个重毒草方法接受表示文件名的String参数。这两个方
法都返回产生的byte数组。availableO方法被用来产生恰当的数组尺寸,井且readO方法的特定
的重载版本填充了这个数组。
 
read() :  从输入流中读取数据的下一个字节,返回0到255范围内的int字节值。如果因为已经到达流末尾而没有可用的字节,则返回-1。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
read(byte[] b) : 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。在输入数据可用、检测到文件末尾或者抛出异常前,此方法一直阻塞。
如果 b 的长度为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1;否则,至少读取一个字节并将其存储在 b 中。
将读取的第一个字节存储在元素 b[0] 中,下一个存储在 b[1] 中,依次类推。读取的字节数最多等于b 的长度。设 k 为实际读取的字节数;这些字节将存储在 b[0] 到 b[k-1] 的元素中,不影响 b[k] 到b[b.length-1] 的元素。 由帮助文档中的解释可知,read()方法每次只能读取一个字节,所以也只能读取由ASCII码范围内的一些字符。这些字符主要用于显示现代英语和其他西欧语言。而对于汉字等unicode中的字符则不能正常读取。只能以乱码的形式显示。
对于read()方法的上述缺点,在read(byte[] b)中则得到了解决,就拿汉字来举例,一个汉字占有两个字节,则可以把参数数组b定义为大小为2的数组即可正常读取汉字了。当然b也可以定义为更大,比如如果b=new byte[4]的话,则每次可以读取两个汉字字符了,但是需要注意的是,如果此处定义b 的大小为3或7等奇数,则对于全是汉字的一篇文档则不能全部正常读写了。
 
--------------

ThinkJava-输入和输出的更多相关文章

  1. 了解一下C++输入和输出的概念

    我们经常用到的输入和输出,都是以终端为对象的,即从键盘输入数据,运行结果输出到显示器屏幕上.从操作系统的角度看,每一个与主机相连的输入输出设备都被看作一个文件.除了以终端为对象进行输入和输出外,还经常 ...

  2. [总结] I/O输入,输出

    I/O输入,输出第一:先判断到底是输入还是输出,站在程序的立场第二:判断是传递字节,还是字符,决定管道粗细,字节流是最基本的数据输出管道.字符类型管道专门用来传送文本数据.Java流的四大父类:1.字 ...

  3. C#语言基础— 输入与输出

    C#语言基础— 输入与输出 1.1函数的四要素:名称.输入.输出.加工 1.2主函数:输出语句.输入语句: Static viod Main(string[] stgs)//下划线部分可以自己指定 { ...

  4. Shell编程基础教程3--Shell输入与输出

    3.Shell输入与输出    3.1.echo        echo命令可以显示文本行或变量,或者把字符串输出到文件        echo [option] string             ...

  5. 不可或缺 Windows Native (4) - C 语言: 预处理命令,输入,输出

    [源码下载] 不可或缺 Windows Native (4) - C 语言: 预处理命令,输入,输出 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 预处理命令 输入 ...

  6. 输入和输出的总结(c语言)

    c语言中有多种的输入和输出方式,下面就简单总结一下: 一.输入的三种方式 (1)scanf scanf 函数可以在变量中使用,也可以在数组中使用,当然指针上也能用到,是一个很好的输入函数.scanf是 ...

  7. C++——输入、输出和文件

    一.C++输入和输出概述 1.1.流和缓冲区 C++程序把输入和输出看作字节流.输入时,程序从输入流中抽取字节:输出时,程序将字节插入到输出流中.对于面相文本的程序,每个字节代表一个字符,更通俗地说, ...

  8. C++学习42 输入和输出的概念

    我们经常用到的输入和输出,都是以终端为对象的,即从键盘输入数据,运行结果输出到显示器屏幕上.从操作系统的角度看,每一个与主机相连的输入输出设备都被看作一个文件.除了以终端为对象进行输入和输出外,还经常 ...

  9. C++:文件的输入和输出

    1.共同的打开文件方式: fin.open("test.txt",ios::binary) fout.open("test.txt",ios::binary) ...

  10. YTU 2609: A改错题--学生信息的输入和输出

    2609: A改错题--学生信息的输入和输出 时间限制: 1 Sec  内存限制: 128 MB 提交: 238  解决: 157 题目描述 注:本题只需要提交标记为修改部分之间的代码,请按照C++方 ...

随机推荐

  1. 使用git一张图就够了

    现在,版本控制工具中,git逐步成为主流.他的分散式的特性是它超越svn渐渐独霸江湖.如果你还不熟悉git,通过本文,你有个最基本最实用的理解:如果你熟悉git,温故而知新,为你加深对git的理解 g ...

  2. 51nod 1225 余数的和 数学

    1225 余数之和 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 F(n) = (n % 1) + (n % 2) + (n % 3) + ... ...

  3. c++ 判断容器是否为空

    #include <iostream> #include <vector> #include <string> using namespace std; int m ...

  4. Rails-Treasure chest3 嵌套表单; Ransack(3900✨)用于模糊查询, ranked-model(800🌟)自订列表顺序; PaperTrail(5000✨)跟踪model's data,auditing and versioning.

    自订列表顺序, gem 'ranked-model' 多步骤表单 显示资料验证错误讯息 资料筛选和搜寻, gem 'ransack' (3900✨); 软删除和版本控制 数据汇出(csv), 自订列表 ...

  5. Android下移植tcpflow

    tcpflow是linux平台下的开源抓包工具,它能监听网络url,获取http请求的各种数据.tcpflow可以说是tcpdump的简约版.要想将tcpflow移植到Android平台中,就需要通过 ...

  6. windows配置Scrapy爬虫框架

    一.环境 Windows10 64位 Python2.7.13 64位 下面的安装步骤最好配置代理,可能会遇到被墙的情况. 二.Python的安装 可以去参考这篇文章:http://blog.csdn ...

  7. fcntl 改变描述符属性

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  8. 根据马甲、应用商店、统计每天的注册量,要求可以根据选择马甲和app,马甲和appstrore和user_login不同表问题

    这个马甲属于一个表,appStore另一张表,用户登录表,主要操作的就是这三个表. 我这里的马甲和app的id都与用户登录表中的channel对应,在channel存放的是majiaId + “|” ...

  9. Python基础学习----拆包

    拆包,多用在多值参数种. 1.多值参数. 有时候,在函数的参数转递时,不单只传输单个字符的参数,比如有元组和字典的参数,这时候我们就使用多值参数. *args 代表元组的多值参数 *kwargs 代表 ...

  10. 基于tiny4412的u-boot移植(一)

    作者信息 作者:彭东林 邮箱:pengdonglin137@163.com QQ: 405728433 平台介绍 开发环境:win7 64位 + VMware11 + Ubuntu14.04 64位 ...