IO流(十八)
IO流(十八)
简介
IO流的IO的意思是指Input和Output, Input指的是从某处读取到程序中来,意为输入;Output指的是从程序写入或传输到某个地方去,意为输出。
IO流中分为字节流和字符流,字节流可以处理图像,视频,文本等内容,而字符流只能处理字符串类型的内容,这个需要在实际使用的时候视情况进行选择。
IO流中有很多的类,我们无法一次全部都记住,但是有一些常用的类,我们需要做到掌握。
File类
File类顾名思义是文件处理类,我们可以使用File类来获取文件名称、长度、路径等,还可以用来创建文件和目录,部分用法见下面的代码。
package com.io;
import java.io.File;
import java.io.IOException;
public class FileDemo {
public static void main(String[] args) {
File file = new File("src/com/io/demo.txt");
String name = file.getName();
long length = file.length();
String path = file.getPath();
System.out.println("文件名是: "+name);
System.out.println("文件长度是: "+length);
System.out.println("文件的路径是: "+path);
File f2 = new File("src/com/io/d2.txt");
if (!f2.exists()) {
try {
f2.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("文件d2.txt已存在.");
}
File f3d = new File("src/com/io/f3/pd");
f3d.mkdir();
f3d.mkdirs();
}
}
字节流
FileInputStream
从这两个类的名字可以看出,这两个是操作字节流的类,一个是输入一个是输出。
先看FileInputStream类,比如,我想读取demo.txt文件中的内容,就可以使用它的read()方法,read()可以一个一个返回内容的字节信息,如果没有内容了,就会返回-1。下面的例子,我使用while循环来遍历文件中的内容。
package com.io;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamDemo1 {
public static void main(String[] args) throws IOException {
FileInputStream input = new FileInputStream("src/com/io/demo.txt");
int i;
while ((i=input.read()) != -1) {
System.out.print((char) i);
}
input.close();
}
}
用上面的方法我们可以将文件内容一个个输出,但是这样做呢效率很低,所以我们稍作修改,使用一个byte[]数组来接收读取到的内容(将byte数组作为read方法的参数,就会将读取的内容存放在这个数组中),再统一打印出来,如下:
package com.io;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamDemo2 {
public static void main(String[] args) throws IOException {
FileInputStream f2 = new FileInputStream("src/com/io/demo.txt");
byte[] bytes = new byte[1024];
int read = f2.read(bytes);
String s = new String(bytes);
System.out.println(read);
System.out.println("===============");
System.out.println(s);
f2.close();
}
}
FileOutputStream
再看FileOutputStream类,看名字就知道是与FileInputStream相对应的功能,它可以用来往文件中写入数据,用法十分简单,看下面:
package com.io;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo1 {
public static void main(String[] args) throws IOException {
//增加append: true表示追加内容
FileOutputStream fileOutputStream = new FileOutputStream("src/com/io/d2.txt", true);
fileOutputStream.write("Hellooooo".getBytes("UTF-8"));
}
}
直接使用write方法将内容转换为byte类型写入即可;在这里有一个需要注意的点,看到实例化FileOutputStream类时传入了一个true参数吗?如果不传这个true默认是false,会将文件中的内容覆盖写入新的内容,而true的意思就是在原本的内容上追加新的内容。
字符流
字节流看完了,我们来看看字符流,首先来看FileReader类,它可以直接将文件中的内容读取存入到一个char[]数组中,然后将char数组转换为String类型即可,看下面例子:
package com.io;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fileReader = new FileReader("src/com/io/d2.txt");
char[] chars = new char[64];
int read = fileReader.read(chars);
System.out.println(new String(chars));
fileReader.close();
}
}
InputStreamReader
从InputStreamReader这个类的名字中可以看出,这是一个字符流类(以reader结尾),另一点,它是用来处理Stream字符流的,我们直接看例子:
package com.io;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("src/com/io/d2.txt");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
char[] chars = new char[64];
int read = inputStreamReader.read(chars);
String s = new String(chars);
System.out.println(s);
System.out.println(read);
inputStreamReader.close();
fileInputStream.close();
}
}
可以看到,我们先是用FileInputStream生成了一个字节流的实例,然后将这个字节流实例作为参数,创建了一个InputStreamReader实例,剩下的步骤与上面的一样,使用一个char数组收集读取到的内容再转化为String即可。
BufferReader和BufferWriter
BufferReader
重点来了,使用字节和数组来读取文件中的内容步骤都相对繁琐,并且效率不高;因此,在实际使用中我们多用Buffer的方式来实现,下面的代码请务必学会使用:
package com.io;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class BufferReaderDemo {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("src/com/io/d2.txt");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line;
while ((line=bufferedReader.readLine())!=null) {
System.out.println(line);
}
bufferedReader.close();
inputStreamReader.close();
fileInputStream.close();
}
}
这里总共实例化了三个类,是不是有点多?我们来看下逻辑关系:
- 使用FileInputStream实例化一个字节流实例
- 然后再把字节流实例作为参数,实例化出一个InputStreamReader的字符流实例
- 在使用这个字符流实例作为参数,实例化出一个BufferReader缓存实例
- 使用缓存实例的readLine()方法将内容一行行读出来
- 最后按顺序将流关闭
BufferWriter
同样的,与BufferReader
的流程相同,我们来试下下BufferWriter的实现:
package com.io;
import java.io.*;
public class BufferWriterDemo {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("src/com/io/d2.txt");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
FileOutputStream fileOutputStream = new FileOutputStream("src/com/io/demo.txt");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
String line;
while ((line=bufferedReader.readLine())!=null) {
System.out.println(line);
bufferedWriter.write(line);
bufferedWriter.newLine();
}
bufferedReader.close();
inputStreamReader.close();
fileInputStream.close();
bufferedWriter.close();
outputStreamWriter.close();
fileInputStream.close();
}
}
上面的代码,我们使用BufferReader和BufferWriter将文件中的内容逐行读取,再逐行写入到另一个文件中,实现一个类似复制的效果。