文章目录
Java IO流 常用类
文件流
- FileInputStream / FileOutputStream 字节流
- FileReader/FileWriter 字符流
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class TestIO {
public static void FileInputStreamTest() {
FileInputStream fis = null;
try{
//注意:本地需先有一个tmp2.txt文件
fis = new FileInputStream("tmp2.txt");
byte[] buf = new byte[1024];
int hasRead = 0;
//fis.read()返回的是单个字节数据(字节数据可以直接转为int类型),
//而fis.read(buf)返回读取的字节数,数据保存在buf中
while ((hasRead = fis.read(buf)) > 0) {
//每次最多将1024个字节转换成字符串,这里tmp2.txt中的字符小于1024,所以一次就读完了
//循环次数 = 文件字符数 除以 buf长度
System.out.println(new String(buf, 0 ,hasRead));
/*
将字节强制转换成字符后逐个输出,能实现和上面一样的效果。
但是如果源文件是中文的话可能会乱码
【这里是多次循环,把buf的每个值赋值给b,然后将字节b转为字符】
for (byte b : buf) {
char ch = (char)b;
if (ch != '\r')
System.out.print(ch);
}
*/
}
}
catch(IOException e){
e.printStackTrace();
}
finally{
try {
if (ifs != null)
ifs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void FileReaderTest() throws IOException {
try (
// 在try() 中打开的文件, JVM会自动关闭
FileReader fr = new FileReader("tmp2.txt")) {
char[] buf = new char[32];
int hasRead = 0;
// 每个char都占两个字节,每个字符或者汉字都是占2个字节,
//因此无论buf长度为多少,总是能读取中文字符长度的整数倍,不会乱码
while ((hasRead = fr.read(buf)) > 0) {
// 如果buf的长度大于文件每行的长度,就可以完整输出每行,否则会断行。
// 循环次数 = 文件字符数 除以 buf长度
System.out.println(new String(buf, 0, hasRead));
// 跟上面效果一样
// System.out.println(buf);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void FileOutputStreamTest() throws FileNotFoundException, IOException {
try (
//在try()中打开文件会在结尾自动关闭
FileInputStream fis = new FileInputStream("tmp2.txt");
FileOutputStream fos = new FileOutputStream("tmp3.txt");
) {
byte[] buf = new byte[4];
int hasRead = 0;
while ((hasRead = fis.read(buf)) > 0) {
//每读取一次就写一次,读多少就写多少
fos.write(buf, 0, hasRead);
}
System.out.println("write success");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void FileWriterTest() throws IOException {
try (FileWriter fw = new FileWriter("tmp4.txt")) {
fw.write("天王盖地虎\r\n");
fw.write("宝塔镇河妖\r\n");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
//FileInputStreamTest();
//FileReaderTest();
//FileOutputStreamTest();
FileWriterTest();
}
}
缓冲流
- BufferedReader / BufferedWriter 针对字符
- BufferedInputStream / BufferedOutputStream 针对字节
-
没有经过Buffered处理的IO,意味着每一次读和写的请求都会由OS底层直接处理,这会导致非常低效的问题。
-
经过Buffered处理过的输入流将会从一个buffer内存区域读取数据,本地API只会在buffer空了之后才会被调用(可能一次调用会填充很多数据进buffer)。
-
经过Buffered处理过的输出流将会把数据写入到buffer中,本地API只会在buffer满了之后才会被调用。
BufferedReader/BufferedWriter可以将字符流(Reader)包装成缓冲流,这是最常见用的做法。
另外,BufferedReader提供一个readLine()可以方便地读取一行,而FileInputStream和FileReader只能读取一个字节或者一个字符,
因此BufferedReader也被称为行读取器。
转换流
- InputStreamReader
- OutputStreamReader
这两个类可以将字节流转换成字符流,被称为字节流与字符流之间的桥梁。我们经常在读取键盘输入(System.in)或网络通信的时候,需要使用这两个类。
下面演示上面上面常见类
package io;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PushbackReader;
import java.io.StringReader;
import java.io.StringWriter;
public class TestIO {
public static void keyIn() throws IOException {
try {
//InputStreamReader是从byte转成char的桥梁
InputStreamReader reader = new InputStreamReader(System.in);
//BufferedReader(Reader in)是字符类型输入的包装类
BufferedReader br = new BufferedReader(reader);
String line = null;
while ((line = br.readLine()) != null) {
if (line.equals("exit")) {
//System.exit(1);
break;
}
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
keyIn();
}
}
字节数组输出流
ByteArrayOutputStream 在内存中创建一个字节缓冲区, 所有发送到输出流的数据保存在该字节数组缓冲区中,缓冲区会随着不断写入而增长,可使用toByteArray()和toString()获取数据。主要用来接受数据,然后再一次性将数据输出。
下面有两种方式创建对象:
ByteArrayOutputStream bOut = new ByteArrayOutputStream();//默认32字节的缓冲区
ByteArrayOutputStream bOut = new ByteArrayOutputStream(int a);//a字节的缓冲区
演示
public static void main(String[] args) throws IOException {
FileInputStream fos = new FileInputStream("D:" + File.separator + "temp.out");
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
//从文件里读取的临时数据存入buffer中
while((len = fos.read(buffer))!=-1){
//len是每次读取文件后,buffer的长度
baos.wraite(buffer, 0, len);//每次读取后都将buffer中的数据写入baos中
}
System.out.println(baos.toString());//将baos中的数据一次性打印出来
baos.close();
fos.close();
}