字节流和字符流的操作方式几乎是一样的.只是操作的数据单元不同而已.字节流是字节,字符流是字符.
1.InputStream和Reader
InputStream和Reader是所有输入流的抽象基类.本身并不能创建实例来执行输入.但它们是所有输入流的模板.它们的方法是所有输入流可使用的方法.
在InputStream里包含3个方法.
int read():从输入流中读取单个直接.返回所读取的字节数据,字节数据可直接转换为int类型.
int read(byte[] b):从输入流最多读取b.length个字节的数据,并将其存储在字节数组b中,返回实际读取字节数.
int read(byte[] b,int off,int len):从输入流中最多读取len个字节的数据,并将其存储在数组b中,放入数据b中时,并不是从数据起点开始,而是从off位置开始,返回实际读取的字节数.
Reader里也同样包含3个方法,也都是read方法.int read(),int read(char[] cbuf),int read(char[] cubf,int off,int len),使用方法一致.
因为他们2个都是抽象类,所以是无法创建实例的,但他们分别有一个用于读取文件的输入流:FileInputStream和FileReader,它们都是节点流----会直接和指定文件关联.
package org.credo.io;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamTest {
public static void main(String[] args) throws IOException {
// 创建字节输入流
FileInputStream fis = new FileInputStream("D://test.txt");
// 创建一个长度为1024的竹筒,放字节流
byte[] bbuf = new byte[1024];
// 用于保存实际读取的字节数
int hasRead = 0;
while ((hasRead = fis.read(bbuf)) > 0) {
// 取出竹筒中的字节,将字节数组转换为字符串输入.
System.out.println(new String(bbuf, 0, hasRead));
}
// 如果bbuf是全部的字节,而非1024这么的,可以这样字节输出windows系统下的文件内容,win7默认中文GBK.
System.out.println(new String(bbuf, "GBK"));
fis.close();
}
}
上面的程序创建的是长度1024的字节数组来读取文件,实际文件可能不到1024字节,但是文件有中文会出现乱码,是因为文本保存在win下是用的GBK,每个中文字符2个字节,如果read()这样读,都只读到了半个中文字符必然乱码.
package org.credo.io;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderTest {
public static void main(String[] args) throws IOException {
FileReader fr=new FileReader("D://test.txt");
//创建一个长度为32的字符数组
char[] cbuf=new char[32];
int hasRead=0;
while((hasRead=fr.read(cbuf))>0){
System.out.println(new String(cbuf,0,hasRead));
}
fr.close();
//这些也只是适合英文了.
}
} 他们2个还支持如下几个方法来移动记录指针.
boolean markSupported();判断输入流是否支持mark()操作,即是否支持记录标记.因为输入流被读取后,除非再回到未读状态,否则再读取是错误的.
void mark(int readAheadLimit); 在记录指针当前位置记录一个mark,0为初始位置.markSupported必须为true才能使用.
void reset(); 将此输入流重新定位到mark位置.markSupported必须为true才能使用.
long skip(long n); 记录指针向前移动n个字节/字符.
2.OutputStream和Write
这两个也是相似的.
OutputStream有如下3个方法:
void write(int c):将指定的字节/字符输出到输出流中,其中c可以代表字节/字符.
void write(byte[]/char[] buf):将buf中的数据输出到指定输出流中.
void write(byte[]/char[] buf,int off,int len):将字节数组/字符数组中从off位置开始,长度为len的字节/字符输出到输出流中.
因为字符流字节以字符作为操作单位,所以Writer可以用字符串来代替字符数组,所以以String作为参数.包含2个方法:
void write(String str):将str字符串里包含的字符输出到指定输出流中.
void write(String str,int off,int len):将str字符串里从off位置开始,长度为len的字符输出到指定输出流中.
注意:使用java的IO流执行输出,请务必关闭输出流,因为这样做除了可以保证流的物力资源被回收外,还可以将输出流缓冲区的数据flush到物理节点里,因为在执行close()方法前,自动执行输出流的flush()方法,java里很多输出流都默认使用了缓冲功能,没必要去记.只要正常关闭就可以保证程序的正常.
下面这个是FileOutputStream的示例代码:
package org.credo.io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamTest {
public static void main(String[] args) throws IOException {
//创建字节输入流
@SuppressWarnings("resource")
FileInputStream fis=new FileInputStream("D://test.txt");
FileOutputStream fos=new FileOutputStream("D://test2.txt");
byte[] bytes=new byte[32];
int hasRead=0;
while ((hasRead=fis.read(bytes))>0) {
fos.write(bytes, 0, hasRead);
}
fos.close();
}
} 下面是FileWriter的
package org.credo.io;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterTest {
public static void main(String[] args) throws IOException {
FileWriter fw=new FileWriter("D://test3.txt");
//windows下使用\r\n换行.Linux下使用\n.
fw.write("你是谁?你是谁?你是那当初的傻妹妹!哦啦啦~~~\r\n");
fw.write("我去.....太2了吧也!");
fw.close();
}
} 注:使用字节流文件自然是系统默认的,如果是使用String的话就是你的编程环境,如我使用的是UTF-8,使用fw.write("你是谁?你是谁?你是那当初的傻妹妹!哦啦啦~~~\r\n");输出到txt,txt最后也是UTF-8.这点需要注意.实际工作会遇到.好吧,我承认我刚碰到过这个问题,解决方法是下面这个:
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("1.txt"), "GB2312"));
pw.print(message); 具体这个东西怎么用的话,等下篇了,IO东西很杂.