您的位置:首页 > 编程语言 > Java开发

Java IO流的那些爱恨情仇

2014-12-19 14:40 267 查看
又开始回头重新补Java基础了,以前也是去网上直接下代码,这样导致自己只会用,对Java IO流内部机制并不熟悉,实实在在的一个代码搬运工。痛定思痛,觉得自己不能这么干了。基础最为重要,回头重新研究。好了,废话不多说,开扯。一开始我也是只是去网上搜搜看看别人怎么讲。哎,听的糊里糊涂的,不过看的多了,也就慢慢懂了一些。现在就把我理解的总结下。

1.字节流

1)输入字节流 InputStream

基本方法:

InputStream in = new InputStream(file) / /file是文件名

int b = in.read(); 读取一个byte无符号填充到int底八位,-1是EOF

int.read(byte[] buf) 读取数据填充到buf中

int.read(byte[] buf,int start,int size) 读取数据填充到buf中

in.close 关闭输入流

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class FileInputStream_Test {

public static void main(String[] args) throws IOException {

//方式一
InputStream in =new FileInputStream("D:/test.txt");
byte b[] = new byte[in.available()];
in.read(b);					//直接把所有字节读入byte数组
System.out.println(new String(b));		//要把byte数组打印出来得转成String

//方式二
File file = new File("D:/test.txt");
InputStream is =new FileInputStream(file);  //这是FileInputStream另一种实例化方式
int a;
while((a=is.read())!=-1){		    //这是一个个读取,每一次read都是读一个字节
System.out.print((char)a);
}

}
}

注意,如果test.txt里有中文,方式二是会乱码的,因为 is.read() 每一次是读一个字节,但是一个汉字是两个字节(得看本地编码GBK下两个字节,UTF-8下3个字节),它一下只读一个字节就相当于读了半个汉字,那打印出来必定是乱码,哈哈,一个字母是一个字节,所以换成字母打印正常。

2)输出字节流 OutputStream

这个是所有输出字节流的父类。

基本方法:

OutputStream out = new OutputStream(file) / /file是文件名

out.write(int b) 写出一个byte 到流 b 的底八位写出

out.write(byte[] buf) 将buf的一部分写入流中

out.write(byte[] buf, int start, int size) 将buf的一部分写入流中

out.flush() 清理缓存

out.close

package IO;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class FileOutputStream_Test {

public static void main(String[] args) throws IOException {

//方式一
InputStream is =new FileInputStream("D:/test.txt");//先从一个文件里读些数据
byte b[] = new byte[is.available()];
is.read(b);
OutputStream os = new FileOutputStream("D:/test1.txt"); //实例化一个输出流,如果文件不存在会自动创建
os.write(b);//直接把一个byte数组写入到文件中

//方式二
InputStream is1 =new FileInputStream("D:/test.txt");
OutputStream os1 = new FileOutputStream("D:/test1.txt");
int a;
while((a=is1.read())!=-1){		//读一个字节,写一个字节
os1.write(a);
}
is.close();
is1.close();
os.close();
os1.close();
}
}</span><span style="color:#0000ff;font-size: 13px;">
</span>


2.字符流

字符流又是 Reader 和 Writer了,顾名思义,它们处理的是字符数据,但是最底层的还是靠字节流实现的,所以Reader每次的 read()读的也是一个字节,只不过它有个转换器:InputStreamReader,他会把Reader读得的字节流转成字符流,这样每次处理的就是一个字符。 所以重头戏还是 InputStreamReader。

1) 字符的处理,一次处理一个字符(unicode编码)

2) 字符的底层仍然是基本的字节流

3) 字符流的基本实现

InputStreamReader 完成byte流解析为char流,按照编码解析

OutputStreamWriter 提供char流到byte流,按照编码处理

4) 字符流的过滤器

是字符读写的功能扩展,极大的方便了文本的读写操作

BufferedReader : readLine() 一次读取一行

PrintWriter : println() 一次打印一行

5)读取一个文本文件

InputStream is = new FileInputStream("test.txt");

Reader in = new InputStreamReader(is);

BufferedReader reader = new BufferedReader(in);

或者

BufferedReader in = new BufferedReader(new FileReader(filename));

1)Reader

下面是例子

package IO;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

public class Reader_Test {

/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
InputStream is = new FileInputStream("D:/test.txt");
Reader r = new InputStreamReader(is);  //InputStreamReader是一个转换器,把字节流转成字符流
BufferedReader bf = new BufferedReader(r);
int a;
while((a=bf.read())!=-1){
System.out.println((char)a);
}
}

}
其实大部分时候都是用 字节流的,字符流都字节流给转成的。InputStreamReader 的 read() 方法之一的每次调用,可能促使从基本字节输入流中读取一个或多个字节。所以当test.txt中都是字母(一个字节)时,bf.read()会只读到一个字节,当test.txt中是汉字时,会读到两个字节。直接打印汉字。

2)Writer

writer实在没啥好讲的,用的多是是 FileWriter 和 BufferedWriter

package IO;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class Writer_Test {

public static void main(String[] args) throws IOException {

Writer fw = new FileWriter("D:/test1.txt");
fw.write("我们");   //可以直接写入内容
fw.flush();	    // 字符流采用缓存区,如果没把数据刷到文件里,文件是没有数据的。fw.close()也可以把流刷入文件
}
}


最后总结下流程:

1.实例化流对象 InputStream is = new FileInputStream(“xxxx”);

2.读取
is.read();

3.后续自由操作

4.关闭流 is.close();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: