IO流
- 流:一连串流动的数据
- 流的分类:
1、按流向分:
输入流
输出流
2、按操作单元分:
字节流
字符流
3、按功能分:
节点流:直接从数据源到目的地
功能流:经过包装
注意:
1、分清数据源于目的地
2、IO流以程序为中心 - 字节流:万能流
字节输入流:InputStream:抽象类,是所有字节输入流的超类
按流向分:输入流
按操作单元分:字节流
按功能分:节点流
read()方法,每次从输入流中读入一个字节的内容想要输入多个数据需重复输入。
public static void main(String[] args) throws IOException {
//1.建立联系
File src=new File("D:/test.txt");
//2.选择流
InputStream is=new FileInputStream(src);
//3.操作 读入
int num=-1;
while((num=is.read())!=-1){
System.out.println((char)num);
}
//4.关闭
is.close();
}
}
字节输出流:OutputStream:抽象类,所有字节输出流的超类
注意:使用字节输出流时,若目的地文件不存在,系统会自动创建。若目的地文件夹不存在,则不会自动创建并报出异常。
文件拷贝:
从数据源输入到程序,再从程序输出到目的地
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
public class CopyFile03 {
public static void main(String[] args) {
//1.选择流
Reader read=null;
Writer write=null;
try {
read=new FileReader(new File("D:/test.txt"));
write=new FileWriter(new File("D:/dest.txt"),true);
//2.准备卡车 字符数组
char[] car=new char[1024];
int len=-1;
while(-1!=(len=read.read(car))){
write.write(car, 0, len);
}
//3.刷出
write.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
//关闭
if(write!=null){
try {
write.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(read!=null){
try {
read.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- 文件夹拷贝
public class CopyDir {
public static void main(String[] args) throws IOException {
copyDir("D:/AAA","D:/");
}
/*
* 1.不能把文件拷贝到文件所在路径下
*/
public static void copyDir(String src,String dest) throws IOException{
//判断/最后一次出现的位置索引
int index=src.lastIndexOf("/");
String str=src.substring(0, index);
if(str.equals(dest) || (str+"/").equals(dest)){
throw new IOException("不能把文件拷贝到文件所在路径下");
}
copyDir(new File(src),new File(dest));
}
/*
* 2.目标路径不能为源文件路径的子路径下
*/
private static void copyDir(File src,File dest) throws IOException{
if(dest.getAbsolutePath().contains(src.getAbsolutePath())){
throw new IOException("目标路径不能为源文件路径的子路径下");
}
//目标路径:完整路径
copyDirDetails(src,new File(dest,src.getName()));
}
private static void copyDirDetails(File src,File dest){ // D:/AAA/haha.txt //E:/AAA/
if(src.isFile()){
//如果目标文件所在路径文件存在不存在的情况,就创建多个不存在的文件夹
if(!dest.getParentFile().exists()){
dest.getParentFile().mkdirs();
}
CopyUtil.copyFile(src, dest);
}else if(src.isDirectory()){
//创建目标路径所有不存在的文件夹
dest.mkdirs();
File[] files=src.listFiles();
for(File srcFile:files){
copyDirDetails(srcFile,new File(dest,srcFile.getName()));//D:/AAA/BBB/hehe.txt //E:/AAA/BBB/hehe.txt
}
}
}
}
- 字符流
字符输入流 :InputReader:抽象类
字符输出流:outputWriter:抽象类
操作步骤与字节流一致 - 功能流
1、缓冲流:增强功能,提高性能
使用:缓冲流(节点流)
字节缓冲流:
1)字节输入缓冲流:BufferedInputStream
2)字节输出缓冲流:BufferedOutputStream
无新增方法,可以发生多态
字符缓冲流:
1)字符输入缓冲流:BufferedReader 新增方法 readLine();
2)字符输出缓冲流:BufferedWriter 新增方法 newLine();
有新增方法,无法使用多态
2、转换流:将字节流转换为字符流
1)InputStreamReader(InputStream)
2) OutputStreamWriter(OutputStream)
使用时可能会出现的乱码情况:
1)字符编码格式不统一
2)缺少字节个数
不同编码格式汉字所占字节大小:
ISO-8859-1 1个字节
GBK 2个字节
GB2312 2个字节
UTF-8 3个字节
3、基本数据类型流:读写带有基本数据类型或String类型的数据
使用:基本数据类型流(字节节点流)
DataInputStream(InputStream) 新增方法:readXXX();
DataOutputStream(OutputStream)新增方法: writeXXX();
有新增方法,无法使用多态
注意:读入和输出顺序要保持一致
4、对象流
序列化:将对象信息转换为可存储或可传输的信息格式
序列化输出流:ObjectOutputStream 新增方法:readXXX();
反序列化输入流:ObjectInputStream 新增方法: writeXXX();
有新增方法,无法使用多态
注意:
1)使用时先序列化后反序列化
2)不是所有类都能序列化,必须要实现空接口java.io.Serializable
3)不是所有属性都需要序列化,被transient修饰的属性不需要
4)静态的内容不能被序列化
5)若父类实现了空接口java.io.Serializable,子类所有内容都可序列化