字节流的基类为: InputStream 和 OutputStream ;字符流的基类为:Reader 和 Writer 。他们的子类命名都以这写基类为后缀名,下面为大家具体介绍一下这几种类的使用方法。
一、字节流
字节流分为字节输出流(FileInputStream)和字节输入流(FileInputStream)分别进行读和写的操作。
1、FileOutputStream类
FileOutputStream类提供了文件基本文件的读取能力,FileOutputStream 类常用的构造方法如下:
- FileOutputStream(String name)
- FileOutputStream(File file)
第一个构造方法使用给定的一个文件名 name 创建一个 FileOutputStream 对象,可以指定一个不存在的文件名,系统会自动帮你创建这个文件,第二个构造方法使用 File 对象创建 FileOutputStream 对象。
FileOutputStream 流的三个 Write 方法:
- public void write(int b):写入一个字节 超过一个字节 砍掉前面的字节
- public void write(byte[] b):写入一个字节数组
- public void write(byte[] b,int off,int len):写一个字节数组的一部分
通过这三种写的方法可以对一个文件进行复制,下面用实例代码进行演示:
import java.io.FileOutputStream;
import java.io.IOException;
public class Lxc {
public static void main(String[] args) throws IOException {
FileOutputStream out = new FileOutputStream("lxc.txt");
String s = "长情不仄言";
byte[] bytes = s.getBytes();//把字符串s转换为一个字节数组
out.write(100); //写入一个字节
out.write(bytes); // 写入一个字节数组
out.write(bytes, 0, 9); // 写入一个字节数组的一部分
out.close(); //关闭这个流,等待垃圾回收器对其进行回收
}
}
2、FileInputStream类
FileInputStream 类有与 FileOutputStream 类相同的参数构造,使用给定的文件名 name 创建一个 FileOutputStream 对象,第二个构造方法使用 File 对象创建一个 FileInputStream 对象。FileInputStream 流中也有三个 read 方法,
- public int read() :从此输入流中读取一个数据字节。
- public int read(byte[] b) :从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
- public int read(byte[] b, int off, int len) :从此输入流中将一段字节的数据读入一个 byte 数组中。
实例代码如下:
import java.io.FileInputStream;
import java.io.IOException;
public class Lxc {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("e.txt");
//创建一个字节数组,充当容器
byte[] bytes = new byte[1024];
int len = in.read(bytes); //把文件中的数据,读取到容器中,返回值是,读取到的有效字节个数
System.out.println(len);
String s = new String(bytes, 0, len);
System.out.println(s);
in.close(); //关闭流,让垃圾回收器对其进行回收
}
}
灵活的使用这两个流可以对文件进行复制,实例代码如下:
import java.io.*;
public class Demo3 {
public static void main(String[] args) throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream("E:/picture.jpg"));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("d:/picture.jpg"));
int len = 0;
byte[] bytes = new byte[1024 * 8];
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
}
out.close();
in.close();
}
}
上面的代码就是把 E 盘下的一个文件复制到了 D 盘中,在上面的方法中我们使用了字节数组进行复制,这样会比一个字节一个字节的复制更加的迅速。
上面的两个流在不用字节数组的时候只能进行单个字节的进行复制,Java还提供了高效的字节流就是 BufferedInputStream 和 BufferedOutputStream 这一对流在底层加入了缓冲区,所以比较高效。在BufferedOutputStream 类中有一个 flush() 方法来将缓冲区的数据强制输完他们的构造方法就是传入一个字节流的对象,格式如下:
BufferedInputStream in = new BufferedInputStream(new FileInputStream("月半小夜曲.mp3")); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("月半小夜曲1.mp3"));
其余的操作和上面介绍的两个流一样,在此不做过多解释。
二、字符流
相对于字节流,字符流只能对字符进行操作
1、OutPutStreamWriter 类
OutPutStreamWriter 类是字符流通向字节流的桥梁,他可使用指定的编码表将要写入流中的字符编码成字节。输入流所关联的文件如果不存在的话那么系统会自动创建该文件。它常用构造方法如下:
- OutputStreamWriter(OutputStream out)
创建使用默认字符编码的 OutputStreamWriter。 - OutputStreamWriter(OutputStream out, Charset cs)
创建使用给定字符集的 OutputStreamWriter。 (第二个参数是自己给定编码表)
实例代码如下:
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("a.txt"), "UTF-8");
它里面的write()方法是一个写入一个字符,一次写入一个字符数组或者字符串的一部分,代码如下:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
public class MyTest3 {
public static void main(String[] args) throws IOException {
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("a.txt",true), "UTF-8");//编码格式为UTF-8
out.write('8');
out.write("山河故人");
out.write("\r\n"); //写入换行符
out.write("山河故人",0,2);//写字符串的一部分,从 0开始,写2个字符
out.flush();
out.close();
}
}
2、InPutStreamReader 类
InPutStreamReader 是字节流通向字符流的桥梁,它使用指定的码表读取字节并将其解码为字符,它使用的码表可以由名称指定或显式给定,或者可以接受平台默认的字符集。它的构造方法如下:
InputStreamReader(InputStream in) // 创建一个使用默认字符集的 InputStreamReader。 InputStreamReader(InputStream in, Charset cs) // 创建使用给定字符集的 InputStreamReader。
InPutStreamReader 中的 read() 方法 可以读取单个字符或者一个字符数组,返回值为读取到有效字节的个数,如果读取不到有效字符,那么就会返回 -1,我们可以利用这个 -1 判断文件是否读取完毕。一样使用这两个流我们可以对一个文本文件进行复制,实例代码如下:
import java.io.*;
public class MyTest {
public static void main(String[] args) throws IOException {
InputStreamReader in = new InputStreamReader(new FileInputStream("E:/picture.jpg"));
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("D:/picture.jpg"));
//定义一个字符缓冲区
char[] chars = new char[2000];
int len = 0;//记录每次读取到的有效字符个数
while ((len = in.read(chars)) != -1) {
out.write(chars, 0, len);
out.flush();
}
in.close();
out.close();
}
}
上面的代码使用了字符数组,这样可以提高复制的速度。
3、便捷类
InputStreamReader 类和 OutputStreamWriter 类都有一个子类,如下表,子类的名称较短,使用便捷,但是这两个子类不能自己定义编码表,只能使用平台默认的码表。
父类 | 子类 |
---|---|
InputStreamReader | FileReader |
OutputStreamWriter | FileWriter |
用便捷子类对文件进行复制,代码实例为:
import java.io.*;
public class MyTest {
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("E:/picture,jpg");
FileWriter writer = new FileWriter("D:/picture.jpg");
char[] chars = new char[1000];
int len=0;
while ((len=reader.read(chars))!=-1){
writer.write(chars,0,len);
writer.flush();
}
reader.close();
writer.close();
}
}
4、高效的字符流
A) 高效的字符输出流:BufferedWriter
构造方法: public BufferedWriter(Writer w)
B) 高效的字符输入流: BufferedReader
构造方法: public BufferedReader(Reader e)
这两个流传入的都是相应的字符流对象。,代码如下:
BufferedReader bfr = new BufferedReader(new FileReader("1.txt"));
BufferedWriter bfw = new BufferedWriter(new FileWriter("2.txt"));
上面的两个流除了比较高效外,里面还有几个特殊的功能
- BufferedWriter
public void newLine():根据系统来决定换行符 具有系统兼容性的换行符 - BufferedReader
public String readLine():一次读取一行数据 是以换行符为标记的 读到换行符就换行 没读到数据返回null
实例代码如下:
public class MyTest {
public static void main(String[] args) throws IOException {
BufferedReader bfr = new BufferedReader(new FileReader("E:/MyTest.java"));
BufferedWriter bfw = new BufferedWriter(new FileWriter("D:/MyTest.java"));
String line = null;
while ((line = bfr.readLine()) != null) { //读取不到返回null
bfw.write(line);
bfw.newLine();
bfw.flush();
}
bfr.close();
bfw.close();
}
}
上面代码是一次读取一行数据,然后每次写入一行数据。
注意事项:
无论哪个流使用完后要用 close() 方法关闭该流。