字节流操作类和字符流操作类组成了Java IO体系,整个Java IO体系都是基于字节流(InputStream/OutputStream) 和 字符流(Reader/Writer)作为基类,根据不同的数据载体或功能派生出来的。(参考网站:https://www.cnblogs.com/fysola/p/6123947.html)
影响应用程序执行效率的限定性因素,往往并非处理速率,而是I/O。程序员热衷于调试代码,I/O性能的调试往往被摆在第二位,甚至完全忽略。殊不知,在I/O性能上的小小投入就可换来可观的回报。下图展示了IO继承关系。
常用的几个流为:
文件型(File):字节流(FileInputStream, FileOutputStream) 字符流(FileReader,FileWriter)
内存数组(Memory Array): 字节流(ByteArrayInputStream,ByteArrayOutputStream)
缓冲(Buffering): 字节流(BufferedInputStream, BufferedOutputStream) 字符流(BufferedWriter,BufferedReader)
字节流转为字符流:InputStreamReader/OutputStreamWriter
标准输入与输出:
System.in, System.out, System.err
对于文件流:FileInputStream/FileOutputStream, FileReader/FileWriter,直接贴代码演示
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.FileReader;
/**
*
* @author XiaoguniangAnn
* @version 2018.04.08
*
*/
public class IOtest {
static byte[] tes = new byte[20];
public IOtest() {
for(int i=0;i<20;i++) {
tes[i]=(byte) ('a'+i);
}
}
//测试写文件FileWriter方法
public void testFileWriter() throws IOException {
try(FileWriter fw=new FileWriter("fileWriter_0.txt")){
fw.write(56);
fw.write('b');
fw.write("Hello World!\r");
fw.write("My name is\n");
fw.write("shangguan\r\n");
fw.write("insertTest",6,4);
}catch (IOException e) {
e.printStackTrace();
}
}
//测试写文件FileOutputStream方法
public void testOutputStream() throws IOException{
try(FileOutputStream fos=new FileOutputStream("fileOutput_0.txt")){
fos.write(65);
fos.write('a');
fos.write(tes);
fos.write("\r\nabc".getBytes()); //getBytes()将字符转为byte字节型,可以用这个写入换行符等
fos.write(tes,2,18);
}catch(IOException e) {
e.printStackTrace();
}
}
//测试读文件FileReader方法
public void testFileReader() throws IOException,FileNotFoundException{
//List<String> read = new ArrayList<>();
char [] tmp = new char[30];
int hasread =0;
try(FileReader fr = new FileReader("fileOutput_0.txt")){
while((hasread = fr.read(tmp))>0) {
System.out.print(new String(tmp,0,hasread)+"hasread = "+hasread);
//for(char t :tmp) {System.out.println(t);}
}
}catch(FileNotFoundException e) { //注意FileNotFoundException 写在IOException前
System.err.println("File not found!" );
}catch(IOException e) {
e.printStackTrace();
}
}
//测试读文件FileInputStream方法
public void testFileInputStream() throws IOException{
byte [] fin = new byte [20];
int hasread =0;
try(FileInputStream fis = new FileInputStream("fileOutput_0.txt")){
while((hasread = fis.read(fin)) >0) {
System.out.print(new String(fin)+"\nhasread = "+hasread+'\n');
}
}catch (FileNotFoundException e) {
System.err.println("File not found!" );
}catch(IOException e) {
e.printStackTrace();
}
}
//测试方法输出
public static void main(String [] args) throws IOException {
IOtest test = new IOtest();
test.testFileWriter();
test.testOutputStream();
test.testFileReader();
test.testFileInputStream();
}
}
为了区分字符流与字节流,在构造函数中添加了byte型数组。
先说明下其中的主要函数:
对于写操作:
public void write (int b);// 将参数b的低位字节写入到输出流
public void write (byte b[]);// 将字节数组b[]中的全部字节顺序写入到输出流
public void write(byte[] b, int off, int len);// 将字节数组b[]中从off开始的len个字节写入到流中
public void flush ();// 刷新流
public void close();// 关闭流
对于字符型写入一样,有
public void write (int b);// 将参数b的低两字节写入到输出流
public void write (char b[]);// 将字符数组b[]中的全部字节顺序写入到输出流
public void write(char[] b, int off, int len);// 将字节数组b[]中从off开始的len个字节写入到流中public void write( String s);// 将字符串写入流中
public void write( String s, int off, int len);// 将字符串写入流中, off为位置,len为长度
public void flush ();// 刷新流
public void close();// 关闭流
对读操作:
FileInputStream
public int read(); 读入一个字节,-1表示无
public int read(byte b[]); 返回读入的字节数
public int read(byte[] b, int off, int len);
FileReader
public int read(); //需要将int转成char
public int read(char b[]);
public int read(char[] b, int off, int len);
可以看出,无论是读操作还是写操作的代码都比较类似,区别仅在于参数为字符还是字节。
需要说明的几点是:
1. 在FileWriter中加入\r\n等转义符,但在文件中只有\r\n成功换行,不过在读取时\r, \n依旧可以读出。
2.使用try()catch Exception,由于jvm会自动关闭try中打开的文件,所以可以不用close()流。
3.在字节流时,使用fos.write("content")是不对的,括号内应为单个字符,或者Int型数字(此时输出的是ASCII码代表的值),或字节型数组,可以使用getBytes()将字符转为byte字节型,用这个写入换行符等。
4.在读文件时,FileNotFoundException 要写在IOException前,否则会报错。
5.byte [] fin = new byte [20];char [] tmp = new char[30];中20,30是一次能读取的字节/字符长度。对于整个文件的目标没有影响,仅对while循环的次数造成影响,可能影响程序效率。
6.catch (IOException e) {e.printStackTrace();}中printStackTrace()方法的意思是:在命令行打印异常信息在程序中出错的位置及原因。
下一篇学习缓冲流(BufferedWriter&BufferedReader)