I/O流
I/O流概述
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
流按流向划分: 输入流,输出流
流按读写数据类型划分: 字节流,字符流
字节流:
可以读写任意类型的文件
输出流
例:创建并写入一个数据的文件
public class Mydemo3 {
public static void main(String[] args) throws IOException {
// 1)创建一个向指定 File 对象表示的文件中写入数据的文件输出流
File file = new File("a.txt");
FileOutputStream out1 = new FileOutputStream(file);
// 2)直接传入一个文件路径,如果该文件不存在则创建
FileOutputStream out2 = new FileOutputStream("D:\\b.txt");
//若下次写入时数据不被覆盖,则添加参数true
FileOutputStream out3 = new FileOutputStream("D:\\c.txt",true);
out1.write(98);
out1.write("Hello World!".getBytes());
//注意:一个汉字占三个字节(平台默认UTF-8编码)
out1.write("爱生活,爱Java".getBytes(),0,9);
out1.close();
}
}
不同系统下换行注意:
out1.write("\r\n".getBytes()); //Windows系统换行
out1.write("\n".getBytes()); //Linux系统换行
out1.write("\r".getBytes()); //Mac系统换行
例:流的异常处理
方式一:捕获处理异常
public class MyDemo4 {
public static void main(String[] args) {
FileOutputStream out = null;
try {
out = new FileOutputStream("a.txt");
out.write("java".getBytes());
} catch (IOException e) {
e.printStackTrace();
}finally {
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
方式一:向上抛出异常
public class MyDemo5 {
public static void main(String[] args) throws IOException {
FileOutputStream out = new FileOutputStream("a.txt");
out.write("java".getBytes());
out.close();
}
}
输入流
从文件系统中的某个文件中获得输入字节
public class MyDemo6 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("a.txt");
//读取数据方式一: 一次读一个字节,如果读超了则返回-1
in.read();
//读取数据方式二: 一次读一个字节数组 字节数组相当于一个缓冲区
byte[] bytes = new byte[1024];
int len=in.read(bytes);//len返回有效读取长度
//遍历读出的数据
String s = new String(bytes, 0, len);
System.out.println(s);
}
}
例:复制文件
public class MyDemo7 {
public static void main(String[] args) throws IOException {
//方式一:一次读取一个字节,写一个字节来复制,效率低
//方式二:一次读取一个字节数组,写一个字节数组(以下代码采用此种方式)
FileInputStream in = new FileInputStream("a.txt");
FileOutputStream out = new FileOutputStream("b.txt");
//创建一个字节缓冲区
byte[] bytes = new byte[1024];
int len=0;
while ((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
out.flush();
}
in.close();
out.close();
}
}
例:高效的输入、出流
BufferedInputStream与BufferedOutputStream
public class MyDemo8 {
public static void main(String[] args) throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("c.txt"));
byte[] bytes = new byte[1024];
int len = 0;
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
in.close();
out.close();
}
}
对时间效率差异的解释:
BufferedInputStream比FileInputStream多了一个缓冲区,执行read时先从缓冲区读取,当缓冲区数据读完时再把缓冲区填满。
因此,当每次读取的数据量很小时,FileInputStream每次都是从硬盘读入,而BufferedInputStream大部分是从缓冲区读入。读取内存速度比读取硬盘速度快得多,因此BufferedInputStream效率高。
BufferedInputStream的默认缓冲区大小是8192字节。当每次读取数据量接近或远超这个值时,两者效率就没有明显差别了
字符流:
Writer与Reader
只能读写文本文件
字符流=字节流+编码表
编码:文本=》字节
解码:字节=》文本
public class MyDemo9 {
public static void main(String[] args) {
//编码:
byte[] bytes = "爱生活,爱Java".getBytes();//平台默认编码
for (byte aByte : bytes) {
System.out.println(aByte);
}
//解码:
String str = new String(bytes);
System.out.println(str);
}
}
public class MyDemo9 {
public static void main(String[] args) throws UnsupportedEncodingException {
//指定编码形式,注意编解码要一致
byte[] bytes = "爱生活,爱Java".getBytes("gbk");
String str = new String(bytes, "gbk");
System.out.println(str);
}
}
例:字符流的文件复制
public class MyDemo1 {
public static void main(String[] args) throws IOException {
//字符流复制
InputStreamReader in = new InputStreamReader(new FileInputStream("a.txt"));
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("d.txt"));
char[] chars = new char[100];
int len = 0;
while ((len = in.read(chars)) != -1) {
out.write(chars, 0, len);
out.flush();
}
in.close();
out.close();
}
}
例:高效的字符流
BufferedReader与BufferedWriter
public class MyDemo2 {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new FileReader("a.txt"));
BufferedWriter out = new BufferedWriter(new FileWriter("e.txt"));
String line=null;//记录每次读取一行文本
while ((line=in.readLine())!=null){
out.write(line);
out.newLine();//换行
out.flush();
}
in.close();
out.close();
}
}
注意
父类:InputStreamReader 与OutputStreamWriter
||
子类(不能指定编码):FileReader与FileWriter