常用的IO流API有:
【InputStream、OutputStream】
【FileInputStream、FileOutputStream】
【BufferedInputStream、BufferedOutputStream】
【BufferedReader、BufferedWriter】
流分为两种:字节流、字符流。
字节流:字节可以处理的数据类型多,读取单位为byte,处理某些文件时可能会出现乱码。
字符流:字符可以处理的数据类型少,可以逐个字符读取,也可逐行读取,在处理文本时优先使用字符流,其他数据类型使用字节流。
一、InputStream、OutputStream的实现类的使用
InputStream下的继承关系:
java.lang.Object
继承者 java.io.InputStream
继承者 java.io.FilterInputStream
继承者 java.io.BufferedInputStream
java.lang.Object
继承者 java.io.OutputStream
继承者 java.io.FilterOutputStream
继承者 java.io.BufferedOutputStream
①看以下代码是否觉得费解?他们有什么不同呢?
InputStream is = new FileInputStream();
FileInputStream fis = new FileInputStream();
前者使用了多态,InputStream不能读取文件,抽象类不能被实例化,通过它的实现类FileInputStream可以实例化对象,进行文件的读取。
后者可以单独new一个对象,FileInputStream可以直接读取二进制文件,比如文本、音频、视频。
②使用InputStream、FileInputStream、FileOutputStream进行文件的读写
src目录下的a.txt文件,键入内容【This is a demo.】做测试用。
public class CopyDemo {
public static void main(String[] args) {
/**
* 1、获取源文件
* 2、将文件写入到某处
* 3、开始读取源文件
* 4、写入数据流到新文件
* 5、关闭流操作
*/
try {
System.out.println("开始读取...");
//1、获取源文件
InputStream inputStream = new FileInputStream("src/a.txt");
//2、将文件写入到src目录下,命名为b.txt
OutputStream outputStream = new FileOutputStream("src/b.txt");
int len;
byte myArray[] = new byte[1024*1024];
//3、开始读取源文件
while((len = inputStream.read(myArray))!=-1){
//len接收一个int类型的数据,表示本轮共读取多少个字节,就只循环多少次取出正确数据
byte array[] = new byte[len];
for (int i = 0; i < array.length; i++) {
array[i] = myArray[i];
}
//4、写入数据流到新文件
outputStream.write(myArray);
}
System.out.println("写入完成!");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
③FileInputStream、BufferedInputStream的差异在哪?
继承关系如下:
FileInputStream、FileOutputStream:
public class FileInputStreamDemo {
public static void main(String[] args) {
try {
System.out.println("开始读取...");
//记录程序运行的开始时间
long beginTime = System.currentTimeMillis();
InputStream inputStream = new FileInputStream("src/a.txt");
OutputStream outputStream = new FileOutputStream("src/b.txt");
int len;
byte myArray[] = new byte[1024*1024];
while((len = inputStream.read(myArray))!=-1){
byte array[] = new byte[len];
for (int i = 0; i < array.length; i++) {
array[i] = myArray[i];
}
outputStream.write(myArray);
}
inputStream.close();
outputStream.close();
System.out.println("写入完成!");
记录程序运行的结束时间
long endTime = System.currentTimeMillis();
System.out.println("运行时间:"+(endTime-beginTime)+"ms");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class BufferedInputStreamDemo {
public static void main(String[] args) {
try {
System.out.println("开始读取...");
long beginTime = System.currentTimeMillis();
InputStream inputStream = new FileInputStream("src/Papi酱.mp4");
BufferedInputStream bis = new BufferedInputStream(inputStream);
OutputStream outputStream = new FileOutputStream("src/Papi酱BufferedInput.mp4");
BufferedOutputStream bos = new BufferedOutputStream(outputStream);
int len;
byte myArray[] = new byte[1024*1024];
while((len = bis.read(myArray))!=-1){
bos.write(myArray,0,len);
}
bis.close();
bos.close();
inputStream.close();
outputStream.close();
System.out.println("写入完成!");
long endTime = System.currentTimeMillis();
System.out.println("运行时间:"+(endTime-beginTime)+"ms");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
小结:经过BufferedInputStream包装的流,其传输速度更快,FileInputStream的速度略输一筹。如果传输更大的文件,显然用BufferedInputStream更好。
二、如果读写的不是文件数据,该如何解决?ByteArrayInputStream可读取非文件数据
这时候就要用到【ByteArrayInputStream、ByteArrayOutputStream】
他们继承关系如下:
java.lang.Object
继承者 java.io.InputStream
继承者 java.io.ByteArrayInputStream
java.lang.Object
继承者 java.io.OutputStream
继承者 java.io.ByteArrayOutputStream
示例:
public class ByteArrayInputStream {
public static void main(String[] args) {
String content = "Welcome to GuangZhou";
java.io.ByteArrayInputStream is = new java.io.ByteArrayInputStream(content.getBytes());
int len;
byte myArray[] = new byte[2];
try {
while((len = is.read(myArray))!=-1){
for (int i = 0; i < len; i++) {
System.out.print((char)myArray[i]);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
如果读取的数据中有中文,会出现乱码问题
这时候就要用到 字符流BufferedReader来解决乱码问题了。
三、读写出现乱码,该如何解决?使用BufferedReader解决
【BufferedReader、BufferedWriter】的继承关系:
java.lang.Object
继承者 java.io.Reader
继承者 java.io.BufferedReader
java.lang.Object
继承者 java.io.Writer
继承者 java.io.BufferedWriter
示例:读取a.txt文件里的中文
public class BufferedReaderDemo {
public static void main(String[] args) {
try {
BufferedReader bReader = new BufferedReader(new InputStreamReader(new FileInputStream("src/a.txt")));
while(bReader.ready()){
System.out.println(bReader.readLine());
}
bReader.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
结果:文本输出正常,没有出现乱码