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. 百度语音识别vs科大讯飞语音识别

    一.结果 从笔者试验的结果来看,科大讯飞的语音识别技术远超百度语音识别 二.横向对比   科大讯飞语音识别 百度语音识别 费用 各功能的前5小时免费 全程免费 转换精准率 非常高 比较低 linux ...

  2. 1406 data too long for column 'content' at row 1

    很奇怪,很邪门. content字段用的是text格式,按理说不会出现数据太长的问题. 后来搜索了一下,需要设置sql_mode.或者设为, mysql> SET @@global.sql_mo ...

  3. C++getline使用

    C++getline使用 一.心得 getline(cin,s);多去看函数的使用默认说明 二.使用 getline(istream &in, string &s) 从输入流读入一行到 ...

  4. localStorage(本地存储)使用总结

    1.https://www.cnblogs.com/st-leslie/p/5617130.html (localStorage使用总结)

  5. OleDbCommand使用参数应该注意的地方

    最近写程序用到OleDbCommand的Parameter写数据库,遇到很多问题: 1.OLE DB .NET Framework 数据提供程序和 ODBC .NET Framework 数据提供程序 ...

  6. vue spn如何做seo优化

    vue spn如何做seo优化 突然来了一个需求,对已有的项目做SEO优化,WHAT? 总所周知,spn对seo不够优化,因而官方考虑到直接使用ssr 一个不算解决办法的办法prerender-spa ...

  7. 在Spring Boot中使用 @ConfigurationProperties 注解 (二十六)

    @ConfigurationProperties主要作用:就是绑定application.properties中的属性 java代码 @Configuration public class DataS ...

  8. 网路防火墙iptables

    linux操作系统自身可以充当交换机,还可以当路由器,也就是说linux多网卡之间拥有互相转发数据包的能力,这种能力的实现主要依靠的是防火墙的功能进行数据包的转发和入站. 路由选择点,就是在一个点分辨 ...

  9. bzoj2631

    题解: lct+链上修改 每一次修改的时候记录lazy标记 如果有了乘法,加法的lazy标记也要相应的随之变化 代码: #pragma GCC optimize(2) #include<bits ...

  10. 【LeetCode 144_二叉树_遍历】Binary Tree Preorder Traversal

    解法一:非递归 vector<int> preorderTraversal(TreeNode* root) { vector<int> res; if (root == NUL ...