第18章 java I/O系统(2)
18.2 输入和输出
18.2.1 InputStream类型
InputStream的作用是用来表示那些从不同数据源产生输入的类。这些数据源包括:
1)字节数组。2)String对象。3)文件。4)“管道”,工作方式与实际管道相似,即,从一段输入,从另一端输出。5)一个由其他中类的数据流组成的序列,以便我们可以将他们手机合并到一个流内。6)其他数据源。
每种数据源都有相应的InputStream子类。另外,FilterInputStream也属于一种InputStream,为“装饰器”(decorator)类提供基类,其中,“装饰器”类可以把属性或有用的接口与输入流连接在一起。
InputStream类型:
(1)ByteArrayInputStream:功能:允许将内存的缓冲区当做InputStream。用法:缓冲区,直接将从中取出;作为一种数据源:将其与FilterInputStream对象相连以提供有用接口。
(2)StringBufferInputStream:功能:将String转换成InputStream。用法:字符串。底层实现实际使用StringBuffer;作为一种数据源:将其与FilterInputStream对象相连以提供有用接口。
(3)FileInputStream:功能:用于文件中读取信息。用法:字符串,表示文件名,文件或FileDecriptor对象。作为一种数据源:将其与FilterInputStream对象相连以提供有用接口。
(4)PiledInputStream:功能:产生用于写入相关PiledOutputStream的数据。实现“管道化”概念。用法:PileOutputStream;作为多线程中数据源:将其与FilterInputStream对象相连以提供有用接口。
(5)SequenceInputStream:功能:将两个或多个InputStream对象转换成一个InputStream。用法:两个InputStream对象或一个容纳InputStream对象的容器Enumeration;作为一种数据源:将其与FilterInputStream对象相连以提供有用接口。
(6)FIlerInputStream:功能:抽象类,作为“装饰器”的接口。其中,“装饰器”为其他的InputStream类提供有用功能。
18.2.1 OutputStream类型
该类别的类决定了输出所要去往的目标:字节数组,文件或管道。
(1)ByteArrayOutputStream:功能:在内存中创建缓冲区。所有送往“流”的数据都要防止在此缓冲区。用法:缓冲区初始化尺寸(可选);用于指定数据的目的地:将与FilterOutputStream对象相连以提供有用的接口。
(2)FileOutputStream:功能:用于将信息写至文件。用法:字符串,表示文件名,文件或FIleDescriptor对象。用于指定数据的目的地:将与FilterOutputStream对象相连以提供有用的接口。
(3)PipedOutputStream:功能:任何写入其中的信息都会自动作为相关PipledInputStream的输出,实现“管道化”概念。用法:PipledInputStream;指定用于多线程的数据目的地:将其与FilterOutputStream对象相连以提供有用接口。
(4)FilterOutputStream:用法:抽象类,作为“装饰器”的接口,其中,“装饰器”为其他OutputStream提欧共有用功能。
18.3 添加属性和有用的接口
FilterInputStream类型:
(1)DataInputStream:功能:与DataOutputStream搭配使用,因此我们可以按照可移植方式从流读取基本数据类型(int,char,long)。用法:InputStream包含用于读取基本类型数据的去阿奴接口。
(2)BufferedInputStream:功能:使用它可以防止每次读取时都得进行实际写操作。代表“使用缓冲区”。用法:InputStream,可以指定缓冲区大小;本子上不提供接口,只不过是向进程中添加缓冲区所必需的。与接口对象搭配。
(3)LineNumberInputStream:功能:跟中输入流中的行号,可调用getLineNumber()和setLineNumber(int)。用法:InputStream;仅增加了行号,因此可能也要与接口对象搭配使用。
(4)PushbackInputStream:功能:具有“能弹出一个字节的缓冲区”。因此可以将读到的最后一个字符回退。用法:InputStream;通常作为编译器的扫描器,之所以包含在内是因为Java编译器的需求,我们可能永远不会用到。
FilterOutputStream类型:
(1)DataOutStream:功能:与DataInputStream搭配使用,因此可以按照可一直方式向流中些人基本类型数据。用法:OutputStream,包含用于写入基本类型数据的全部接口。
(2)PrintStream:功能:用于产生格式化输出。其中DataOutputStream处理数据的存储,PrintStream处理显示。用法:OutputStream,可以用boolean值只是是否每次换行时清空缓冲区,(可选的)应该是对OutputStream对象的final封装。坑你会经常使用它。
(3)BufferedOutputStream:功能:使用它以避免每次发送数据时都要进行实际的写操作。代表“使用缓冲区”。可以调用flush()清空缓冲区。用法:OutputStream,可以指定缓冲区的大小。本质上并不提供接口,只不过是向进程中添加缓冲区所必需的,与接口对象搭配使用。
18.4 Reader和Writer
有时我们必需把来自与“字节”层次接口中的类和“字符”层次结构中的类结合起来使用。为了实现这个目的,要用到“适配器”(adapter)类:InputStreamReader可以把InputStream转换为Reader,而OutputWriter可以把OutputStream转换成Writer。
18.5 自我独立的类:RandomAccessFile
这是个独立的类:后面再研究
18.6 I/O流的典型使用方式
18.6.1 缓冲输入文件
1 package com.thinkinjava.chapter18.part6; 2 3 import java.io.BufferedReader; 4 import java.io.FileReader; 5 import java.io.IOException; 6 7 public class BufferedInputFile { 8 9 public static void main(String[] args) throws IOException { 10 11 String str = read("src/com/thinkinjava/chapter18/part6/BufferedInputFile.java"); 12 System.out.println(str); 13 } 14 15 /** 16 * @Title: read 17 * @Description: 缓冲输入文件 18 * @param @param filename 19 * @param @return 20 * @param @throws IOException 21 * @return String 22 * @throws 23 */ 24 public static String read(String filename) throws IOException { 25 BufferedReader in = new BufferedReader(new FileReader(filename));//字符缓冲流 26 String s ; 27 StringBuilder sb = new StringBuilder(); 28 while((s = in.readLine()) !=null){ 29 sb.append(s+"\n"); 30 } 31 in.close(); 32 return sb.toString(); 33 34 } 35 36 }
18.6.2 从内存输入
1 package com.thinkinjava.chapter18.part6; 2 3 import java.io.IOException; 4 import java.io.StringReader; 5 6 public class MemoryInput { 7 8 9 /** 10 * @Title: main 11 * @Description: 从内存中输入 12 * @param @param args 13 * @param @throws IOException 14 * @return void 15 * @throws 16 */ 17 public static void main(String[] args) throws IOException { 18 19 20 StringReader in = new StringReader(BufferedInputFile.read("src/com/thinkinjava/chapter18/part6/MemoryInput.java")); 21 int c; 22 while((c = in.read()) != -1){//read()是以int形式返回下一个字节,因此必须类型转换成char才能正确打印 23 System.out.print((char) c); 24 } 25 } 26 27 }
18.6.3 格式化的内存输入
1 package com.thinkinjava.chapter18.part6; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.DataInputStream; 5 import java.io.EOFException; 6 import java.io.IOException; 7 8 public class FormattedMemoryInput { 9 10 11 /** 12 * @Title: main 13 * @Description: 读取格式化数据,使用DataInputStream,他是一个面向字节的I/O类 14 * DataInputStream用readByte()一次一个字节地读取字符,那么任何字节的值都是合法的结果, 15 * 因此返回值不能用啦检测输入是否结束。相反,我们可以使用available方法差看还有多少可供存取的字符。 16 * 17 * @param @param args 18 * @param @throws IOException 19 * @return void 20 * @throws 21 */ 22 public static void main(String[] args) throws IOException { 23 24 25 try { 26 DataInputStream in = new DataInputStream(new ByteArrayInputStream(BufferedInputFile.read("src/com/thinkinjava/chapter18/part6/FormattedMemoryInput.java").getBytes())); 27 while(true){ 28 System.out.print((char)in.readByte()); 29 } 30 } catch (EOFException e) { 31 e.printStackTrace(); 32 System.out.println("End of stream"); 33 } 34 } 35 36 37 }
18.6.4 基本文件输出
1 package com.thinkinjava.chapter18.part6; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedReader; 5 import java.io.BufferedWriter; 6 import java.io.FileWriter; 7 import java.io.IOException; 8 import java.io.PrintWriter; 9 import java.io.StringReader; 10 11 public class BasicFileOutput { 12 13 /** 14 * @Title: main 15 * @Description: 16 * 首先:创建一个与指定文件链接的FileWriter。实际上,我们通常会用BufferedWriter将其包装起来用以缓冲输出。 17 * @param @param args 18 * @param @throws IOException 19 * @return void 20 * @throws 21 */ 22 public static void main(String[] args) throws IOException { 23 24 String file = "src/com/thinkinjava/chapter18/part6/BasicFileOutput.txt"; 25 26 BufferedReader in = new BufferedReader(new StringReader(BufferedInputFile.read("src/com/thinkinjava/chapter18/part6/BasicFileOutput.java"))); 27 28 PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file))); 29 30 int lineCount = 1; 31 String s; 32 while((s = in.readLine()) != null){ 33 out.println(lineCount++ +":"+s); 34 } 35 out.close(); 36 System.out.println(BufferedInputFile.read(file)); 37 } 38 39 }
文本文件输出的快捷方式
1 package com.thinkinjava.chapter18.part6; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.PrintWriter; 6 import java.io.StringReader; 7 8 public class FileOutputShortcut { 9 10 public static void main(String[] args) throws IOException { 11 12 String file = "src/com/thinkinjava/chapter18/part6/FileOutputShortcut.txt"; 13 BufferedReader in = new BufferedReader(new StringReader(BufferedInputFile.read("src/com/thinkinjava/chapter18/part6/FileOutputShortcut.java"))); 14 PrintWriter out = new PrintWriter(file); 15 int lineCount = 1; 16 String s ; 17 while((s = in.readLine()) != null) 18 out.println(lineCount++ +":"+s); 19 out.close(); 20 System.out.println(BufferedInputFile.read(file)); 21 22 } 23 24 }
18.6.5 存储和恢复数据
1 package com.thinkinjava.chapter18.part6; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.DataInputStream; 6 import java.io.DataOutputStream; 7 import java.io.FileInputStream; 8 import java.io.FileNotFoundException; 9 import java.io.FileOutputStream; 10 import java.io.IOException; 11 12 public class StoringAndRecoveringData { 13 14 public static void main(String[] args) throws IOException { 15 16 String file = "src/com/thinkinjava/chapter18/part6/StoringAndRecoveringData.txt"; 17 18 DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))); 19 20 out.writeDouble(3.141592); 21 out.writeUTF("Htat was pi"); 22 out.writeDouble(1.41413); 23 out.writeUTF("Square root of 2"); 24 out.close(); 25 26 DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(file))); 27 28 System.out.println(in.readDouble()); 29 System.out.println(in.readUTF()); 30 System.out.println(in.readDouble()); 31 System.out.println(in.readUTF()); 32 33 34 35 36 37 38 39 40 } 41 42 }
18.6.6 存储和恢复数据
1 package com.thinkinjava.chapter18.part6; 2 3 import java.io.FileNotFoundException; 4 import java.io.IOException; 5 import java.io.RandomAccessFile; 6 7 public class UsingRandomAccessFile { 8 9 public static void main(String[] args) throws IOException { 10 11 String file= "src/com/thinkinjava/chapter18/part6/UsingRandomAccessFile.txt"; 12 RandomAccessFile rf = new RandomAccessFile(file, "rw"); 13 14 for (int i = 0; i < 7; i++) { 15 rf.writeDouble(i*1.414); 16 } 17 rf.writeUTF("The end of the file"); 18 rf.close(); 19 20 rf = new RandomAccessFile(file, "rw"); 21 22 rf.seek(5*8); 23 rf.writeDouble(47.0001); 24 rf.close(); 25 display(); 26 } 27 28 public static void display() throws IOException { 29 30 String file= "src/com/thinkinjava/chapter18/part6/UsingRandomAccessFile.txt"; 31 RandomAccessFile rf = new RandomAccessFile(file, "r"); 32 33 for (int i = 0; i < 7; i++) { 34 System.out.println("Value"+i+":"+rf.readDouble()); 35 } 36 System.out.println(rf.readUTF()); 37 rf.close(); 38 } 39 40 41 }
18.7 文件读写的使用工具
1 package com.thinkinjava.chapter18.part7; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileReader; 6 import java.io.IOException; 7 import java.io.PrintWriter; 8 import java.util.ArrayList; 9 import java.util.Arrays; 10 import java.util.TreeSet; 11 12 @SuppressWarnings("serial") 13 public class TextFile extends ArrayList<String>{ 14 15 /** 16 * @Title: read 17 * @Description: 将文件的内容通过字符缓冲流读取到字符串中 18 * @param @param fileName 19 * @param @return 20 * @return String 21 * @throws 22 */ 23 public static String read(String fileName){ 24 25 StringBuilder sb = new StringBuilder(); 26 27 try { 28 29 BufferedReader in = new BufferedReader(new FileReader(new File(fileName).getAbsoluteFile())); 30 try{ 31 String s; 32 while((s = in.readLine()) != null){ 33 sb.append(s); 34 sb.append("\n"); 35 } 36 }finally{ 37 in.close(); 38 } 39 40 } catch (IOException e) { 41 throw new RuntimeException(e); 42 } 43 return sb.toString(); 44 } 45 46 47 48 /** 49 * @Title: write 50 * @Description: 将字符输出到指定文件中 51 * @param @param fileName 52 * @param @param text 53 * @return void 54 * @throws 55 */ 56 public static void write(String fileName,String text){ 57 58 try { 59 PrintWriter out = new PrintWriter(new File(fileName).getAbsoluteFile()); 60 61 try{ 62 out.print(text); 63 }finally{ 64 out.close(); 65 } 66 67 } catch (IOException e) { 68 throw new RuntimeException(e); 69 } 70 71 } 72 73 public TextFile(String fileName,String splitter) { 74 super(Arrays.asList(read(fileName).split(splitter))); 75 if(get(0).equals("")) 76 remove(0); 77 } 78 79 public TextFile(String fileName){ 80 this(fileName,"\n"); 81 } 82 83 /** 84 * @Title: write 85 * @Description: 将list的字符输出到指定文件中 86 * @param @param fileName 87 * @return void 88 * @throws 89 */ 90 public void write(String fileName){ 91 92 try { 93 PrintWriter out = new PrintWriter(new File(fileName).getAbsoluteFile()); 94 try{ 95 for(String item : this) 96 out.println(item); 97 }finally{ 98 out.close(); 99 } 100 } catch (IOException e) { 101 throw new RuntimeException(e); 102 } 103 } 104 105 106 107 public static void main(String[] args) { 108 109 // String file = read("src/com/thinkinjava/chapter18/part7/TextFile.java"); 110 // String outFile = "src/com/thinkinjava/chapter18/part7/text.txt"; 111 // write(outFile , file); 112 113 // String outFile2 = "src/com/thinkinjava/chapter18/part7/text2.txt"; 114 // TextFile text = new TextFile(outFile); 115 // text.write(outFile2); 116 117 TreeSet<String> words = new TreeSet<String>(new TextFile("src/com/thinkinjava/chapter18/part7/TextFile.java","\\W+")); 118 119 System.out.println(words.headSet("a")); 120 121 122 } 123 124 125 126 }
将文件读入到字节数组中
1 package com.thinkinjava.chapter18.part7; 2 3 import java.io.BufferedInputStream; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.IOException; 7 8 public class BinaryFile { 9 10 11 /** 12 * @Title: read 13 * @Description: 14 * 将文件读入到字节数组中 15 * @param @param bFile 16 * @param @return 17 * @param @throws IOException 18 * @return byte[] 19 * @throws 20 */ 21 public static byte[] read(File bFile) throws IOException{ 22 23 BufferedInputStream bf = new BufferedInputStream(new FileInputStream(bFile)); 24 try{ 25 byte[] data =new byte[bf.available()]; 26 bf.read(data); 27 return data; 28 }finally{ 29 bf.close(); 30 } 31 } 32 33 34 /** 35 * @Title: read 36 * @Description: 根据文件路径 将文件读入字节数组中 37 * @param @param bFile 38 * @param @return 39 * @param @throws IOException 40 * @return byte[] 41 * @throws 42 */ 43 public static byte[] read(String bFile) throws IOException{ 44 return read(new File(bFile).getAbsoluteFile()); 45 } 46 47 public static void main(String[] args) throws IOException { 48 byte[] read = read("src/com/thinkinjava/chapter18/part7/text.txt"); 49 System.out.println(read); 50 for (byte b : read) { 51 System.out.print((char)b); 52 } 53 54 } 55 56 }
18.8 标准I/O
1 package com.thinkinjava.chapter18.part8; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 7 /** 8 * @ClassName: Echo 9 * @Description:从标准输入中读取 10 * @author 11 * @date 2018年3月24日 下午2:46:57 12 * @version 1.0 13 */ 14 public class Echo { 15 16 /** 17 * @Title: main 18 * @Description:标准I/O 19 * 从控制台输入然后输出 20 * @param @param args 21 * @param @throws IOException 22 * @return void 23 * @throws 24 */ 25 public static void main(String[] args) throws IOException{ 26 27 BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); 28 String s; 29 while((s = stdin.readLine()) != null && s.length() != 0) 30 System.out.println(s); 31 32 33 } 34 35 36 }
1 package com.thinkinjava.chapter18.part8; 2 3 import java.io.PrintWriter; 4 5 public class ChangeSystemOut { 6 7 /** 8 * @Title: main 9 * @Description:将System.out转换成PrintWriter 10 * @param @param args 11 * @return void 12 * @throws 13 */ 14 public static void main(String[] args) { 15 16 //第二个参数设为true,以便开启自动清空功能,否则,你可能看不到输出 17 PrintWriter out = new PrintWriter(System.out,true); 18 out.println("hello, world"); 19 } 20 21 }
1 package com.thinkinjava.chapter18.part8; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.BufferedReader; 6 import java.io.FileInputStream; 7 import java.io.FileOutputStream; 8 import java.io.IOException; 9 import java.io.InputStreamReader; 10 import java.io.PrintStream; 11 12 public class Redirecting { 13 14 /** 15 * @Title: main 16 * @Description: 17 * 将标准输入附接到文件上,并将标准输出和标准错误重定向到另一个文件。 18 * @param @param args 19 * @param @throws IOException 20 * @return void 21 * @throws 22 */ 23 public static void main(String[] args) throws IOException { 24 25 PrintStream console = System.out; 26 27 BufferedInputStream in = new BufferedInputStream(new FileInputStream("src/com/thinkinjava/chapter18/part8/Redirecting.java")); 28 29 PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream("src/com/thinkinjava/chapter18/part8/test.txt"))); 30 31 System.setIn(in); 32 System.setOut(out); 33 System.setErr(out); 34 35 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 36 37 String s; 38 39 while((s = br.readLine()) != null) 40 System.out.println(s); 41 42 out.close(); 43 System.setOut(console); 44 45 46 } 47 48 }