流 : 流动 、流向 从一端移动到另一端(源头与目的地) 程序 与 文件|数组|网络连接|数据库,以程序为中心
1、流向: 输入流与输出流
2、数据:
字节流:二进制,可以一切文件 包括 纯文本 doc 音频、视频等等 字符流:文本文件,只能处理纯文本
3、功能:
节点:包裹源头 处理:增强功能,提供性能
注意:我们这里学习的是传统 IO 流,并且是阻塞式 IO。
1、字节流
输入流: InputStream read(byte[] b) 、read(byte[] b, int off, int len) +close() FileInputStream()
输出流: OutputStream write(byte[] b) write(byte[] b, int off, int len) +flush() +close() FileOutputStream
2、字符流
输入流:
Reader read(char[] cbuf) read(char[] cbuf, int off, int len) +close() FileReader()
输出流:
Writer write(char[] cbuf) write(char[] cbuf, int off, int len) +flush() +close() write(String str, int off, int len) FileWriter()
1、举例:搬家 -->读取文件
1)、关联房子 --->建立与文件联系
2)、选择搬家 -->选择对应流
3)、搬家 -->读取|写出
4)、打发over -->释放资源
2、操作
1)建立联系
2)选择流
3)操作 数组大小+read 、write
4)释放资源
字节流:可以处理一切文件,包括二进制 音频、视频 、doc等 节点流: InputStream FileInputStream OutputStream FileOutputStream
1、建立联系 File对象 源头
2、选择流 文件输入流 InputStream FileInputStream
3、操作 : byte[] car =new byte[1024]; +read+读取大小 输出
4、释放资源 :关闭
1、建立联系 File对象 目的地
2、选择流 文件输出流 OutputStream FileOutputStream
3、操作 : write() +flush
4、释放资源 :关闭
1、建立联系 File对象 源头 目的地
2、选择流
文件输入流 InputStream FileInputStream
文件输出流 OutputStream FileOutputStream
3、操作 : 拷贝
byte[] flush =new byte[1024];
int len =0;
while(-1!=(len=输入流.read(flush))){
输出流.write(flush,0,len)
}
输出流.flush();
4、释放资源 :关闭 两个流
public class CopyFileDemo {
public static void main(String[] args) {
String srcPath = "E:/others/helloWorld.java";
String destPath = "E:/others/myCopy.java";
try {
copyFile(srcPath,destPath);
} catch (IOException e) {
e.printStackTrace();
System.out.println("拷贝文件失败");
}
}
/**
* 文件的拷贝
* @param srcPath 源文件路径
* @param destPath 目录文件路径
* @throws IOException
*/
public static void copyFile(String srcPath,String destPath) throws IOException {
//1、建立联系源(存在且为文件)+ 目的地(文件可以不存在)
File src = new File(srcPath);
File dest = new File(destPath);
copyFile(src,dest);
}
/**
* 文件的拷贝
* @param src 源文件路径
* @param dest 目录文件路径
* @throws IOException
*/
public static void copyFile(File src,File dest) throws IOException {
if (!src.isFile()){
throw new IOException("只能拷贝文件");
}
if (dest.isDirectory()){
throw new IOException(dest.getAbsolutePath()+"不能建立与文件夹同名的文件");
}
//2、选择流
InputStream is = new FileInputStream(src);
OutputStream os = new FileOutputStream(dest);
//3、文件拷贝 循环+读取+写出
byte[] flush = new byte[1024];
int len = 0;
//读取
while (-1!=(len=is.read(flush))){
//写出
os.write(flush,0,len);
}
//强制刷出
os.flush();
//先打开的流后关闭
os.close();
is.close();
}
}
1、递归查找子孙级文件|文件夹,并创建文件夹
2、文件复制(IO流复制)
3、分析将 A 文件夹 拷贝到 AA 文件夹中 A / \ a.txt b | b.txt
AA
|
A / \ a.txt b | b.txt
4、不能将父目录拷贝到子目录中
/**
* 文件夹的拷贝
* 1、文件 赋值 copyFile
* 2、文件夹 创建 mkdirs()
* 3、递归 查找子孙级
*/
public class CopyDir {
public static void main(String[] args) {
//源目录
String srcPath = "e:/others/study";
//目标目录
String destPath = "e:/others/test";
copyDir(srcPath,destPath);
}
public static void copyDir(String srcPath,String destPath){
File src = new File(srcPath);
File dest = new File(destPath);
copyDir(src,dest);
}
public static void copyDir(File src,File dest){
if (src.isDirectory()){
dest = new File(dest,src.getName());
}
copyDirDetail(src,dest);
}
public static void copyDirDetail(File src,File dest){
if (src.isFile()){
try {
copyFile(src,dest);
} catch (IOException e) {
e.printStackTrace();
}
}else if (src.isDirectory()){
//确保目标文件夹存在
dest.mkdirs();
//获取下一级目录|文件
for (File sub:src.listFiles()){
copyDirDetail(sub,new File(dest,sub.getName()));
}
}
}
}
字符流 : 只能处理纯文本,全部为可见字符 .txt .html 节点流 :
1、建立联系
2、选择流 Reader FileReader
3、读取 char[] flush =new char[1024];
4、关闭
/**
* 纯文本读取
* @author Administrator
*
*/
public class Demo01 {
/**
* @param args
*/
public static void main(String[] args) {
//创建源
File src =new File("E:/xp/test/a.txt");
//选择流
Reader reader =null;
try {
reader =new FileReader(src);
//读取操作
char[] flush =new char[1024];
int len =0;
while(-1!=(len=reader.read(flush))){
//字符数组转成 字符串
String str =new String(flush,0,len);
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("源文件不存在");
} catch (IOException e) {
e.printStackTrace();
System.out.println("文件读取失败");
}finally{
try {
if (null != reader) {
reader.close();
}
} catch (Exception e2) {
}
}
}
}
1、建立联系
2、选择流 Writer FileWriter
3、读取 write(字符数组,0,长度)+flush
4、关闭
/**
* 写出文件
* @author Administrator
*
*/
public class Demo02 {
/**
* @param args
*/
public static void main(String[] args) {
//创建源
File dest =new File("e:/xp/test/char.txt");
//选择流
Writer wr =null;
try {
//默认 false 为覆盖文件。当指定为 true 时,追加文件,而不是覆盖文件。
wr =new FileWriter(dest,true);
//写出
String msg ="追加...锄禾日当午\r\n码农真辛苦\r\n一本小破书\r\n一读一上午";
wr.write(msg);
wr.append("看电视剧 ");
wr.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (null != wr) {
wr.close();
}
} catch (Exception e2) {
}
}
}
}
处理流:增强功能、提供性能,节点流之上
1、字节缓冲流
BufferedInputStream
BufferedOutputStream
2、字符缓冲流
BufferedReader readLine()
BufferedWriter newLine()
1、编码与解码概念
编码 : 字符 ---编码字符集>二进制
解码 : 二进制 ---解码字符集->字符
2、乱码:
1)、编码与解码的字符集不统一
2)、字节缺少,长度丢失
3、文件乱码 InputStreamReader(字节输入流,"解码集") OutputStreamWriter(字符输出流,"编码集")
/**
* 产生乱码的原因
*/
public class ConvertDemo01 {
public static void main(String[] args) throws UnsupportedEncodingException {
reason01();
reason02();
}
public static void reason02() throws UnsupportedEncodingException {
//如果编码解码过程中不指定的话,默认使用平台的字符集,我这里使用的 IDEA,默认字符集为 utf-8
//解码 byte --> char
String str = "中国";
//编码 char --> byte
byte[] data = str.getBytes();
System.out.println(new String(data));
//设定编码字符集
data = str.getBytes("gbk");
//编码解码字符集不统一出现乱码
System.out.println(new String(data));
//编码
byte[] data2 = "中国".getBytes("utf-8");
//解码
str = new String(data2,"utf-8");
System.out.println(str);
}
public static void reason01() {
String str = "中国";
byte[] data = str.getBytes();
//字节数不完整
System.out.println(new String(data,0,4));
}
}
1、字节数组 字节 节点流
输入流:
ByteArrayInputStream read(byte[] b, int off, int len) + close()
输出流:
ByteArrayOutputStream write(byte[] b, int off, int len) +toByteArray() 不要使用多态
/**
* 字节数组 节点流
* 数组的长度有限,数据量不会很大
*/
public class ByteArrayDemo01 {
public static void main(String[] args) throws IOException {
read(write());
}
/**
* 输入流 操作与 文件输入流操作一致
* 读取字节数组
*/
public static void read(byte[] src) throws IOException {
//选择流
InputStream is = new BufferedInputStream(
new ByteArrayInputStream(src)
);
//操作
byte[] flush = new byte[1024];
int len = 0;
while (-1 != (len = is.read(flush))){
System.out.println(new String(flush,0,len));
}
}
public static byte[] write() throws IOException {
//目的地
byte[] dest;
//选择流
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//操作写出
String msg = "我是啦啦啦啦";
byte[] info = msg.getBytes();
bos.write(info,0,info.length);
//获取数据
dest = bos.toByteArray();
//释放资源
bos.close();
return dest;
}
}
1、基本类型+String 保留数据+类型
输入流:DataInputStream readXxx
输出流:DataOutputStream writeXxx
2、引用类型 (对象) 保留数据+类型
反序列化 输入流:ObjectInputStream readObject()
序列化 输出流:ObjectOutputStream writeObject()
注意: 1)、先序列化后反序列化;反序列化顺序必须与序列化一致
2)、不是所有的对象都可以序列化,实现了 java.io.Serializable 这个接口的类才可以被序列化
3)、不是所有的属性都需要序列化,有 transient 关键字的属性就不会被序列化。
3、打印流 PrintStream println() print()
4、三个常量 :
System.in |out|err
System.setIn() |setOut() |setErr()
编写工具类,实现关闭流的功能。
public class FileUtil {
//基于多态实现关闭流的功能
public static void close(Closeable ... io){
for (Closeable temp:io){
try {
if (temp != null) {
temp.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//基于泛型方法实现关闭流的功能
public static <T extends Closeable> void closeAll(T ... io){
for (T temp:io){
try {
if (temp != null) {
temp.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
节点流:离数据源|程序最近的流 1、字节流:可以处理一切(纯文本、音频、视频等) 1)、输入流 InputStream FileInputStream ByteArrayInputStream 操作:read(字节数组) a)、中间容器 byte[] flush=new byte[长度] b)、接收长度 int len =0; c)、循环读取 while(-1!=(len=流.read(flush))){} d)、操作:输出、拷贝 2)、输出流 OutputStream FileOutputStream ByteArrayOutputStream 操作:write(字节数组,0,长度) 输出 2、字符流:只能处理纯文本 1)、输入流:Reader FileReader 操作:read(字符数组) a)、中间容器 char[] flush=new char[长度] b)、接收长度 int len =0; c)、循环读取 while(-1!=(len=流.read(flush))){} d)、操作:输出、拷贝 2)、输出流:Writer FileWriter 操作:write(字符数组,0,长度) 输出 处理流: 装饰模式 提高性能增强功能 1、转换流:解码与编码字符集问题 1)、输入流:InputStreamReader ->解码 2)、输出流:OutputStreamWriter ->编码 2、缓冲流:提高性能 1)、输入流:BufferedInputStream BufferedReader 2)、输出流:BufferedOutputStream BufferedWriter 3、处理数据+类型 1)、基本数据类型 + 字符串:必须存在才能读取,读取与写出顺序必须一致 a)、输入流:DataInputStream readXxx b)、输出流:DataOutputStream writeXxx 2)、引用类型:Serializable transient a)、反序列化:ObjectInputStream readObject b)、序列化:ObjectOutputStream writeObject 4、打印流: PrintStream 5、System.in out err setIn setOut 以下流使用新增方法时不能发生多态 ByteArrayOutputStream: toByteArray() BufferedReader: readLine() BufferedWriter:newLine() DataInputStream DataOutputStream ObjectInputStream ObjectOutputStream PrintStream
0、打印文件|目录
1、文件拷贝
2、关闭流方法
3、文件分割与合并