1、流的分类
(1)输入流和输出流(划分输入/输出流时是从程序运行所在内存的角度来考虑的)
输入流:只能从中读取数据,而不能向其写入数据。
输出流:只能向其写入数据,而不能从中读取数据。
输入流主要由InputStream和Reader作为基类,输出流主要由OutputStream和Writer作为基类。它们都是抽象基类,无法直接创建实例。
(2)字节流和字符流
字节流和字符流的用法几乎完全一样,区别在于字节流和字符流操作的数据单元不同——字节流操作的数据单元是8-bit的字节,而字符流操作的数据单元是16-bit的字符。
字节流主要由InputStream和OutputStream作为基类,而字符流则主要由Reader和Writer作为基类。
(3)节点流和处理流
可以从/向一个特定的IO设备(如磁盘、网络)读/写数据的流,称为节点流,节点流也被称为低级流。
处理流则用于对一个已经存在的流进行连接或封装,通过封装后的流来实现数据读/写功能。处理流也被称为高级流。
2、InputStream和Reader
在InputStream里包含你的方法如下:
Modifier and Type | Method | Description |
---|---|---|
int |
available() |
Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream.
|
void |
close() |
Closes this input stream and releases any system resources associated with the stream.
|
void |
mark(int readlimit) |
Marks the current position in this input stream.(在记录指针当前位置记录一个标记(mark))
|
boolean |
markSupported() |
Tests if this input stream supports the
mark and reset methods. |
abstract int |
read() |
Reads the next byte of data from the input stream.(字节数据可以直接转换为int类型)
|
int |
read(byte[] b) |
Reads some number of bytes from the input stream and stores them into the buffer array
b .(最多读取b.length个字节的数据,并将其存储在字节数组b中,放入数组b中时,返回实际读取的字节数) |
int |
read(byte[] b, int off, int len) |
Reads up to
len bytes of data from the input stream into an array of bytes.(最多读取b.length个字节的数据,并将其存储在字节数组b中,放入数组b中时,并不是从数组起点开始,而是从off位置开始,返回实际读取的字节数) |
byte[] |
readAllBytes() |
Reads all remaining bytes from the input stream.
|
int |
readNBytes(byte[] b, int off, int len) |
Reads the requested number of bytes from the input stream into the given byte array.
|
void |
reset() |
Repositions this stream to the position at the time the
mark method was last called on this input stream.(将此流的记录指针重新定位到上一次记录标记(mark)的位置) |
long |
skip(long n) |
Skips over and discards
n bytes of data from this input stream.(记录指针向前移动n个字节/字符) |
long |
transferTo(OutputStream out) |
Reads all bytes from this input stream and writes the bytes to the given output stream in the order that they are read.
|
在Reader里包含方法如下:
Modifier | Constructor | Description |
---|---|---|
protected |
Reader() |
Creates a new character-stream reader whose critical sections will synchronize on the reader itself.
|
protected |
Reader(Object lock) |
Creates a new character-stream reader whose critical sections will synchronize on the given object.
|
Modifier and Type | Method | Description |
---|---|---|
abstract void |
close() |
Closes the stream and releases any system resources associated with it.
|
void |
mark(int readAheadLimit) |
Marks the present position in the stream.
|
boolean |
markSupported() |
Tells whether this stream supports the mark() operation.
|
int |
read() |
Reads a single character.
|
int |
read(char[] cbuf) |
Reads characters into an array.(最多读取cbuf.length个字符的数据,并将其存储在字符数组cbuf中,返回实际读取的字符数)
|
abstract int |
read(char[] cbuf, int off, int len) |
Reads characters into a portion of an array.
|
int |
read(CharBuffer target) |
Attempts to read characters into the specified character buffer.
|
boolean |
ready() |
Tells whether this stream is ready to be read.
|
void |
reset() |
Resets the stream.
|
long |
skip(long n) |
Skips characters.
|
程序直到read(char[] cbuf)或者read(byte[] b)方法返回-1,即表明到了输入流的结束点。
1 package com.zyjhandsome.io; 2 3 import java.io.*; 4 5 public class FileInputStreamTest { 6 7 public static void main(String[] args){ 8 // 用于 保存呢实际读取的字节数 9 int hasRead = 0; 10 // 创建字节输入流 11 FileInputStream fis = null; 12 try { 13 fis = new FileInputStream("D:\zhaoyingjun\eclipse-workspace\CollectionTest\src\com\zyjhandsome\io\FileInputStreamTest.java"); 14 } catch (Exception e) { 15 // TODO Auto-generated catch block 16 e.printStackTrace(); 17 System.out.println("找不到指定文件"); 18 System.exit(-1); 19 } 20 21 try { 22 long num = 0; 23 while ((hasRead = fis.read()) != -1) 24 { 25 System.out.print(((char)hasRead)); 26 num++; 27 } 28 fis.close(); 29 System.out.println(); 30 System.out.println("共读取了" + num + "个字节"); 31 } catch (Exception e) { 32 // TODO Auto-generated catch block 33 e.printStackTrace(); 34 System.out.print("文件读取错误"); 35 System.exit(-1); 36 } 37 } 38 }
输出内容(因为是按照字节输出,因此对于中文(字符型)会读取时会出现?的现象):
1 package com.zyjhandsome.io; 2 3 import java.io.*; 4 5 public class FileInputStreamTest { 6 7 public static void main(String[] args){ 8 // ???? ±???????????????×????? 9 int hasRead = 0; 10 // ???¨×????????÷ 11 FileInputStream fis = null; 12 try { 13 fis = new FileInputStream("D:\zhaoyingjun\eclipse-workspace\CollectionTest\src\com\zyjhandsome\io\FileInputStreamTest.java"); 14 } catch (Exception e) { 15 // TODO Auto-generated catch block 16 e.printStackTrace(); 17 System.out.println("?????????¨????"); 18 System.exit(-1); 19 } 20 21 try { 22 long num = 0; 23 while ((hasRead = fis.read()) != -1) 24 { 25 System.out.print(((char)hasRead)); 26 num++; 27 } 28 fis.close(); 29 System.out.println(); 30 System.out.println("????????" + num + "??×???"); 31 } catch (Exception e) { 32 // TODO Auto-generated catch block 33 e.printStackTrace(); 34 System.out.print("?????????í?ó"); 35 System.exit(-1); 36 } 37 } 38 } 39 40 共读取了940个字节
1 package com.zyjhandsome.io; 2 3 import java.io.FileInputStream; 4 import java.io.*; 5 6 public class FileReaderTest { 7 8 public static void main(String[] args) { 9 // TODO Auto-generated method stub 10 // 用于保存呢实际读取的字节数 11 int hasRead = 0; 12 // 创建字节输入流 13 FileReader fr = null; 14 try { 15 fr = new FileReader("D:\zhaoyingjun\eclipse-workspace\CollectionTest\src\com\zyjhandsome\io\FileInputStreamTest.java"); 16 } catch (Exception e) { 17 // TODO Auto-generated catch block 18 e.printStackTrace(); 19 System.out.println("找不到指定文件"); 20 System.exit(-1); 21 } 22 23 try { 24 long num = 0; 25 while ((hasRead = fr.read()) != -1) 26 { 27 System.out.print(((char)hasRead)); 28 num++; 29 } 30 fr.close(); 31 System.out.println(); 32 System.out.println("共读取了" + num + "个字符"); 33 } catch (Exception e) { 34 // TODO Auto-generated catch block 35 e.printStackTrace(); 36 System.out.print("文件读取错误"); 37 System.exit(-1); 38 } 39 } 40 41 }
输出内容:
1 package com.zyjhandsome.io; 2 3 import java.io.*; 4 5 public class FileInputStreamTest { 6 7 public static void main(String[] args){ 8 // 用于保存呢实际读取的字节数 9 int hasRead = 0; 10 // 创建字节输入流 11 FileInputStream fis = null; 12 try { 13 fis = new FileInputStream("D:\zhaoyingjun\eclipse-workspace\CollectionTest\src\com\zyjhandsome\io\FileInputStreamTest.java"); 14 } catch (Exception e) { 15 // TODO Auto-generated catch block 16 e.printStackTrace(); 17 System.out.println("找不到指定文件"); 18 System.exit(-1); 19 } 20 21 try { 22 long num = 0; 23 while ((hasRead = fis.read()) != -1) 24 { 25 System.out.print(((char)hasRead)); 26 num++; 27 } 28 fis.close(); 29 System.out.println(); 30 System.out.println("共读取了" + num + "个字节"); 31 } catch (Exception e) { 32 // TODO Auto-generated catch block 33 e.printStackTrace(); 34 System.out.print("文件读取错误"); 35 System.exit(-1); 36 } 37 } 38 } 39 40 共读取了897个字符
1 package com.zyjhandsome.io; 2 3 import java.io.*; 4 5 public class FileReaderTester2 { 6 7 public static void main(String[] args) throws IOException{ 8 // TODO Auto-generated method stub 9 try { 10 // 创建字节输入流 11 FileReader fr = new FileReader("D:\zhaoyingjun\eclipse-workspace\CollectionTest\src\com\zyjhandsome\io\FileInputStreamTest.java"); 12 // 创建一个 长度为32的“竹筒” 13 char[] cbuf = new char[32]; 14 // 用于保存呢实际读取的字节数 15 int hasRead = 0; 16 // 使用循环来重复读取字符数 17 while ((hasRead = fr.read(cbuf)) > 0) 18 { 19 // 取出“竹筒”中的水滴(字符),将字符数组转换成字符串输入 20 System.out.print(new String(cbuf, 0, hasRead)); 21 } 22 fr.close(); 23 } catch (Exception e) { 24 // TODO Auto-generated catch block 25 e.printStackTrace(); 26 System.out.println("找不到指定文件"); 27 System.exit(-1); 28 } 29 } 30 }
输出结果:
1 package com.zyjhandsome.io; 2 3 import java.io.*; 4 5 public class FileInputStreamTest { 6 7 public static void main(String[] args){ 8 // 用于保存呢实际读取的字节数 9 int hasRead = 0; 10 // 创建字节输入流 11 FileInputStream fis = null; 12 try { 13 fis = new FileInputStream("D:\zhaoyingjun\eclipse-workspace\CollectionTest\src\com\zyjhandsome\io\FileInputStreamTest.java"); 14 } catch (Exception e) { 15 // TODO Auto-generated catch block 16 e.printStackTrace(); 17 System.out.println("找不到指定文件"); 18 System.exit(-1); 19 } 20 21 try { 22 long num = 0; 23 while ((hasRead = fis.read()) != -1) 24 { 25 System.out.print(((char)hasRead)); 26 num++; 27 } 28 fis.close(); 29 System.out.println(); 30 System.out.println("共读取了" + num + "个字节"); 31 } catch (Exception e) { 32 // TODO Auto-generated catch block 33 e.printStackTrace(); 34 System.out.print("文件读取错误"); 35 System.exit(-1); 36 } 37 } 38 }
3、OutputStream和Writer
OutputStream里方法包含如下:
Modifier and Type | Method | Description |
---|---|---|
void |
close() |
Closes this output stream and releases any system resources associated with this stream.
|
void |
flush() |
Flushes this output stream and forces any buffered output bytes to be written out.
|
void |
write(byte[] b) |
Writes
b.length bytes from the specified byte array to this output stream. |
void |
write(byte[] b, int off, int len) |
Writes
len bytes from the specified byte array starting at offset off to this output stream. |
abstract void |
write(int b) |
Writes the specified byte to this output stream.
|
Writer里包含方法如下:
Modifier | Constructor | Description |
---|---|---|
protected |
Writer() |
Creates a new character-stream writer whose critical sections will synchronize on the writer itself.
|
protected |
Writer(Object lock) |
Creates a new character-stream writer whose critical sections will synchronize on the given object.
|
Modifier and Type | Method | Description |
---|---|---|
Writer |
append(char c) |
Appends the specified character to this writer.
|
Writer |
append(CharSequence csq) |
Appends the specified character sequence to this writer.
|
Writer |
append(CharSequence csq, int start, int end) |
Appends a subsequence of the specified character sequence to this writer.
|
abstract void |
close() |
Closes the stream, flushing it first.
|
abstract void |
flush() |
Flushes the stream.
|
void |
write(char[] cbuf) |
Writes an array of characters.
|
abstract void |
write(char[] cbuf, int off, int len) |
Writes a portion of an array of characters.
|
void |
write(int c) |
Writes a single character.
|
void |
write(String str) |
Writes a string.
|
void |
write(String str, int off, int len) |
Writes a portion of a string.
|
1 package com.zyjhandsome.io; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 8 public class FileOutputStreamTest2 { 9 10 public static void main(String[] args) { 11 // TODO Auto-generated method stub 12 int hasRead = 0; 13 byte[] bbuf = new byte[32]; 14 FileInputStream fis = null; 15 FileOutputStream fos = null; 16 try { 17 fis = new FileInputStream("D:\zhaoyingjun\eclipse-workspace\CollectionTest\src\com\zyjhandsome\io\FileOutputStreamTest.java"); 18 fos = new FileOutputStream("D:\zhaoyingjun\else\Test\FileOutputStreamTest_copy2.java"); 19 while ((hasRead = fis.read(bbuf)) != -1) 20 { 21 fos.write(bbuf, 0, hasRead); 22 } 23 fis.close(); 24 fos.close(); 25 } catch (FileNotFoundException e2) { 26 // TODO Auto-generated catch block 27 e2.printStackTrace(); 28 System.out.println("系统找不到指定问你件"); 29 System.exit(-1); 30 } 31 catch (IOException e1) { 32 // TODO Auto-generated catch block 33 e1.printStackTrace(); 34 System.out.println("文件复制错误"); 35 System.exit(-1); 36 } 37 System.out.println("文件已复制"); 38 } 39 }
如果希望直接输出字符串内容,则使用Writer会有更好的效果,如下程序所示:
1 package com.zyjhandsome.io; 2 3 import java.io.*; 4 5 public class FileWriterTest { 6 7 public static void main(String[] args) { 8 // TODO Auto-generated method stub 9 try { 10 FileWriter fw = new FileWriter("D:\User_zhaoyingjun\JavaSE\Test\FileWriterTest.txt"); 11 fw.write("锦瑟 - 李商隐 "); 12 fw.write("锦瑟无端五十弦,一弦一柱思华年。 "); 13 fw.write("庄生晓梦迷蝴蝶,望帝春心托杜鹃。 "); 14 fw.write("沧海月明珠有泪,蓝田日暖玉生烟。 "); 15 fw.write("此情可待成追忆,只是当时已惘然。 "); 16 fw.close(); 17 } catch (IOException e) { 18 // TODO Auto-generated catch block 19 e.printStackTrace(); 20 } 21 } 22 }
Windows平台,使用 换行;UNIX/Linux/BSD等平台,则使用 作为换行符号。