IO流的综述
**1.概念**
流:流动、流向,从一端移动到另一端,有源头和目的地
程序 与 文件或数组或网络连接或数据库,以程序为中心
**2.IO流分类**
a.流向:输入流与输出流
b.数据:字节流:二进制,可以处理一切文件,包括纯文本、doc、音频、视频等等
字符流:文本文件,只能处理纯文本
c.功能:节点流:包裹源头(上图中最后一个文件传到程序中,靠近文件的)
处理流:增强功能,提供性能(靠近程序的)
**3.字节流与字符流(重点)与文件**
a.字节流
1)输入流:InputStream 类FileInputStream
read(byte[] b)
从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
read(byte[] b, int off, int len)
将输入流中最多 len 个数据字节读入 byte 数组。
close()
关闭此输入流并释放与该流关联的所有系统资源。
2)输出流:OutputStream 类FileOutputStream
write(byte[] b)
将 b.length 个字节从指定的 byte 数组写入此输出流。
write(byte[] b, int off, int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
flush()
刷新此输出流并强制写出所有缓冲的输出字节。
close()
关闭此输出流并释放与此流有关的所有系统资源。
b.字符流
1)输入流:Reader 类FileReader
read(char[] cbuf)
将字符读入数组。
read(char[] cbuf, int off, int len)
将字符读入数组的某一部分。
close()
关闭该流并释放与之关联的所有资源
2)输出流:Writer 类FileWriter
write(char[] cbuf)
写入字符数组。
write(char[] cbuf, int off, int len)
写入字符数组的某一部分。
flush()
刷新该流的缓冲。
close()
关闭此流,但要先刷新它。
write(String str, int off, int len)
写入字符串的某一部分。
**4.操作**
a.举例:搬家 -->>读取文件
1)关联房子 -->>建立与文件联系
2)选择搬家公司 -->>选择对应流
3)搬家 -->>读取
a)卡车大小 -->>数组大小
b)运输 -->>读取
4)打发over -->>释放资源
b.操作
1)建立联系
2)选择流
3)操作 数组大小 + read
4)释放资源
字节流
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* 文件的读取
* 1.建立联系-> File对象(源头)
* 2.选择流-> 文件输入流 InputStream FileInputStream
* 3.操作 : byte[] car =new byte[1024]; + read + 读取大小
输出
* 4.释放资源 :关闭
* @author Administrator
*
*/
public class Demo01 {
public static void main(String[] args) {
//建立联系也就是创建File对象
File src = new File("D:/安装包/aa/bb/a.txt");
//选择流
InputStream io = null; //提升作用域
try {
io = new FileInputStream(src);
//操作,不断读取,缓冲数组
byte[] car = new byte[100];
int len = 0; //定义实际读取的大小
//循环读取,就是不断的运输货物
while(-1!=(len=io.read(car))){
String str = new String(car, 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 != io) {
io.close();
}
} catch (Exception e2) {
System.out.println("关闭文件输入流失败");
}
}
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* 写出文件
* 1.建立联系->File对象(目的地)
* 2.选择流->文件输出流 OutputStream FileOutputStream
* 3.操作 : write() +flush
* 4.释放资源 :关闭
*
*/
public class Demo02 {
public static void main(String[] args) {
//1.建立联系->File对象(目的地)
File src = new File("D:/安装包/aa/bb/a.txt");
OutputStream os = null;
//2.选择流->文件输出流 OutputStream FileOutputStream
try {
//下面false表示将字节写入文件开始处,直接覆盖原来的文件,
//true表示将字节写入文件末尾处,在文件字节后面添加内容 ,默认为false
os = new FileOutputStream(src,true);
int len = 0;
//3.操作 : write() +flush
String str = "上面说的都是对的!!\r\n";
byte b[] = str.getBytes();
os.write(b,0,b.length);
//这是强制刷出的意思,一般情况下,只有流慢了的时候才会把内容刷出,
//或者最后close的时候也会自动刷出,但是最好自己实现刷出
os.flush();
} catch (FileNotFoundException e) {
System.out.println("其实就算没有a.txt这个文件,还是会在文件夹中创建这样一个文件");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
//4.释放资源 :关闭
if (null != os) {
os.close();
}
} catch (Exception e2) {
System.out.println("关闭输出流文件失败");
}
}
}
}
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 3.文件和文件夹的拷贝,程序为桥梁
a.建立联系:File对象 源头和目的地
b.选择流:文件输入流 InputStream FileInputStream
文件输出流 OutputStream FileOutputStream
c.操作:拷贝
byte[] flush = new byte[1024];
int len = 0;
while(-1 != (len = 输入流.read(flush))){
输出流.write(flush,0,len)
}
输出流.flush
d.释放资源:关闭两个流
*/
public class FileUtils {
public static void main(String[] args) {
// String src = "D:/安装包/aa/bb/a.txt";
// String dest = "D:/安装包/aa/bb/cc/a3.txt";
// try {
// copyFile(src, dest);
// } catch (IOException e) {
// e.printStackTrace();
// }
System.out.println("===========测试拷贝文件夹===========");
String srcPath = "D:/安装包/aa/bb/cc";
String destPath = "D:/安装包/aa/bb/dd";
File src = new File(srcPath);
File dest = new File(destPath);
copyDir(srcPath, destPath);
}
//必须要有下面这个,如果没有话,那么拷贝的是文件夹里面的内容,不会将文件夹拷贝出来
public static void copyDir(String srcPathName, String destDestName){
//1、建立联系,建立对象
File src = new File(srcPathName);
File dest = new File(destDestName);
if(src.isDirectory()){
dest = new File(destDestName,src.getName());
}
copyDirsonfile(src, dest);
}
public static void copyDirsonfile(File src, File dest){
if(src.isFile()){
try {
copyFile(src,dest);
} catch (IOException e) {
e.printStackTrace();
}
}else if(src.isDirectory()){
dest.mkdirs();
for(File temp:src.listFiles()){
copyDirsonfile(temp, new File(dest,temp.getName()));
}
}
}
public static void copyFile(File src, File dest) throws FileNotFoundException,IOException{
InputStream is = new FileInputStream(src);
OutputStream os = new FileOutputStream(dest);
int len = 0;
byte[] b = new byte[1024];
//3、处理,也就是读取出来之后,写入
while(-1!=(len=is.read(b))){
os.write(b, 0, len);
}
os.flush();
//4、关闭流,先打开的后关闭,后打开的先关闭
os.close();
is.close();
}
public static void copyFile(String srcPathName, String destDestName) throws FileNotFoundException,IOException{
//1、建立联系,建立对象
File src = new File(srcPathName);
File dest = new File(destDestName);
copyFile(src,dest);
}
}
但是上面的拷贝文件夹的程序还是有问题,正常情况下,文件夹不能拷贝到子文件夹中,但是现在程序的实现却是可以的。所以需要对这里出现的错误进行处理:解决:不能将父目录拷贝到子目录中(解决方法:程序中if(des.getAbsolutePath().contains(src.getAbsolutePath())))。
如下所示:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* 文件夹的拷贝
* 1.文件 赋值 copyFile()
* 2.文件夹 创建 mkdirs()
* 3.递归查找子孙级
*/
public class CopyFolder {
public static void main(String[] args) {
//源目录
String srcPath = "G:/java/test/src";//如果写错为文件,因不能建立与文件夹des同名的文件,所以会抛出异常
//目标目录
String desPath = "G:/java/test/des";
if(srcPath.equals(desPath)){//拒绝自己拷贝给自己
System.out.println("拒绝自己拷贝给自己");
return;
}
File src = new File(srcPath);
File des = new File(desPath);
if(src.isDirectory()){//文件夹
des = new File(desPath,src.getName());
if(des.getAbsolutePath().contains(src.getAbsolutePath())){
System.out.println("父目录不能拷贝到子目录中");
return;
}
}
copyFolder(src,des);
}
/**
* 拷贝文件夹
* @param src
* @param des
*/
public static void copyFolder(File src,File des){
if(src.isFile()){//文件
try {
CopyFile.copyFile(src, des);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else if(src.isDirectory()){//文件夹
//确保目标文件夹存在
des.mkdirs();
//获取下一级目录或文件
for(File sub : src.listFiles()){
copyFolder(sub,new File(des,sub.getName()));
}
}
}
}
字符流
字符流:只能处理纯文本,全部为可见字符 .txt .html
其中的节点流:Reader FileReader
Writer FileWriter
一、纯文本读取
1、建立联系
2、选择流 Reader FileReader
3、读取 char[] flush = new char[1024]
4、关闭
二、纯文本写出
1、建立联系
2、选择流 Writer FileWriter
3、写出 write(字符数组,0,长度) + flush
4、关闭
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
/**
* 一、纯文本读取
1、建立联系
2、选择流 Reader FileReader
3、读取 char[] flush = new char[1024]
4、关闭
*/
public class FileRead {
public static void main(String[] args) {
File src = new File("G:/JAVA/test/src/test.txt");
Reader charStreamR = null;
try {
charStreamR = new FileReader(src);
char[] flush = new char[10];
int len = 0;
while(-1 != (len=charStreamR.read(flush))){
System.out.print(new String(flush,0,len));
}
} catch (FileNotFoundException e){
e.printStackTrace();
System.out.println("文件不存在");
} catch (Exception e){
e.printStackTrace();
System.out.println("读取文件失败");
} finally {
try {
charStreamR.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("关闭文件输入流失败");
}
}
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
/**
* 二、纯文本写出
1、建立联系
2、选择流 Writer FileWriter
3、写出 write(字符数组,0,长度) + flush
4、关闭
*/
public class FileWrite {
public static void main(String[] args) {
File des = new File("G:/java/test/writed.txt");
String src = "床前明月光,\r\n疑是地上霜,\r\n举头望明月,\r\n低头思故乡。\r\n";
Writer charStreamW = null;
try {
charStreamW = new FileWriter(des,true);
char[] flush = src.toCharArray();
charStreamW.write(flush,0,flush.length);
charStreamW.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("找不到指定路径或拒绝访问");//FileWriter:文件不存在会自动创建,但父路径要存在;子路径为文件夹则拒绝访问
} catch (IOException e) {
e.printStackTrace();
System.out.println("写入文件失败");
} finally {
try {
charStreamW.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("关闭流失败");
}
}
}
}
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
/**
* 纯文本文件的拷贝
*/
public class CopyFile {
public static void main(String[] args) {
File src = new File("G:/java/test/forcopy.txt");
File des = new File("G:/java/test/alreadycopy.txt");
Reader charStreamR = null;
Writer charStreamW = null;
try {
charStreamR = new FileReader(src);
charStreamW = new FileWriter(des,true);
char[] flush = new char[2];
int len = 0;
while(-1 != (len=charStreamR.read(flush))){
charStreamW.write(flush, 0, len);
charStreamW.flush();
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("文件夹或不可创建或不可打开");
} finally {
try {
charStreamW.close();
charStreamR.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("关闭流失败");
}
}
}
}