什么是输出流?
程序能向其中写入数据的流
程序 -> 文件
称为输出(output 写文件)
举个例子,就像学生写作业 交给老师
什么叫输入流?
程序可以从中读取数据的流
文件 -> 程序
称为输入(input 读文件)
一样的例子 就像老师改完的作业 拿去给学生阅读
字节输出流
OutputStream
是一个抽象类,是所有输出字节流的父类
因为是抽象类,所以不能直接实例化对象
需要子类来重写
这里我们用FileOutputStream这个子类来操作文件
/*
* 构造方法:
参数: 1.文件(被写入的文件)
2.文件的路径(被写入的路径)
写入文件的流程:
1.绑定要写入的文件 或 文件路径
2.使用write方法写入
3.关闭资源
*/
public class Demo {
public static void main(String[] args) throws IOException {
//绑定数据的目的地(绑定要写入的文件)
//该路径下 没有该文件 会帮你创建这个文件
// 如果已经有了盖文件 文件会被覆盖
File file = new File("/Users/s/Desktop/Test/su.txt");
// 打印出这段代码时 可能会出现编译时异常
// 先将这个异常抛出
FileOutputStream oStream = new FileOutputStream(file);
//写入数据
// 打印出来的值为对应的ASCII上的值
oStream.write(49);
oStream.write(48);
//用字节数组写入
byte[] b = {65,66,67};
oStream.write(b);
// 按字节数组的索引和长度写入
oStream.write(b, 0, 3);
// 简单写法
oStream.write("hello".getBytes());
oStream.write("world".getBytes());
// 关闭资源
oStream.close();
}
}
//打开这个路径的文件 看看其中的变化
文件的续写
public class Demo {
public static void main(String[] args) throws IOException {
File file = new File("/Users/s/Desktop/Test/sudie.txt");
FileOutputStream oStream = new FileOutputStream(file, true);
oStream.write("hello\n".getBytes());
oStream.close();
}
}
异常处理
public class Demo {
public static void main(String[] args) {
// 异常处理
// IO发生了异常 都需要停止程序 修改代码
// 抛出运行时异常
File file = new File("/Users/s/Desktop/Test/sudie.txt");
// 增加作用域
FileOutputStream oStream = null;
try{
// 创建一个流
// 只要是你手动创建的流 你就需要手动关闭它
oStream = new FileOutputStream(file);
//写入
o.Stream.write("hello".getBytes());
} catch (FileNotFoundException e){
// 抛出一个运行时异常(直接停止掉 程序)
throw new RuntimeException("文件找不到");
} catch(IOException e){
// 文件编写失败 直接停止程序
throw new RuntimeException("文件编写失败");
} finally{
// 关闭资源
try{
//非空判断
// 如果是空的 说明流创建失败 就不用关闭
if(oStream != null) {
oStream.close();
}
} catch (IOException e){
// 关闭资源失败 直接停止程序
throw new RuntimeException("关闭失败")
}
}
}
}
字节输入流
InputStream 是所有输入流的父类
注意: 字节流写入的时候 是一个字节一个字节的写
: 读取也是一个字节一个字节的读
读取文件流程
1.绑定数据源文件(要读哪个文件)
2.使用read方法读文件
3.关闭资源
在你想要读的路径下创建一个txt文件 这里我取名为 su.txt
在里面输入 abcde保存一下
public class Demo {
public static void main(String[] args) throws IOException {
File file = new File("/Users/s/Desktop/Test/su.txt");
FileInputStream iStream = new FileInputStream(file);
// 读取
int i1 = iStream.read();
//这里打印的时候强转成了char类型
//如果不强转 输出的就是对应的ASCII表上的值
System.out.println((char)i1);
i1 = iStream.read();
System.out.println((char)i1);
i1 = iStream.read();
System.out.println((char)i1);
i1 = iStream.read();
System.out.println((char)i1);
i1 = iStream.read();
System.out.println((char)i1);
// 当读取到文件末尾的时候 会返回 -1
// 相当于 你读到-1 文件就读完了
i1 = iStream.read();
System.out.println(i1);
//关闭资源
iStream.close();
}
}
如果要读取的文件中元素有很多,像上面一样打,需要大量时间,所以可以使用循环
public class Demo {
public static void main(String[] args) throws IOException {
File file = new File("/Users/s/Desktop/Test/su.txt");
FileInputStream iStream = new FileInputStream(file);
// read方法 没调用一次 就读取一个字节
// 循环的时候 read方法只能出现一次
// 声明一个变量 保存读出来的结果
int num = 0;
while ((num = iStream.read()) != -1) {
//num = iStream.read();
//char c = (char)num;
System.out.println(num);
}
}
文件的复制
/*
* 使用字节的输入输出流 进行文件的复制
* (字节流 不但可以写文本 还可以写图片 音频 视频 等等...)
*/
public class Demo {
public static void main(String[] args) {
long start = System.currentTimeMillis();
// 异常处理的 复制文件
// 读
FileInputStream fis = null;
// 写
FileOutputStream fos = null;
try {
fis = new FileInputStream("/Users/lanou/Desktop/Test/taytay.jpg");
fos = new FileOutputStream("/Users/lanou/Desktop/Test/Taylor.jpg");
//开始读 读一个字节 写一个字节
// int len = 0;
// while ((len = fis.read()) != -1) {
// // 直接把读出来的 写进文件
// fos.write(len);
// }
//用字节数组的方式 读写 利用缓冲数组读写 效率较高
byte[] b = new byte[1024];
int len = 0;
while ((len = fis.read(b)) != -1) {
fos.write(b, 0, len);
}
} catch (FileNotFoundException e) {
throw new RuntimeException("文件未找到");
} catch (IOException e) {
throw new RuntimeException("文件复制失败");
} finally {
// 这时读取和写入都结束了 先关哪个都行
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
throw new RuntimeException("关闭资源失败");
} finally {
// 写一起的话 如果第一个报了异常
// 第二个流会无法关闭
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
throw new RuntimeException("关闭资源失败");
}
}
}
// 获取结束时间
long end = System.currentTimeMillis();
System.out.println(end - start);
}
}
将一个文件夹 复制 另一个文件夹下
public class Demo02 {
public static void main(String[] args) throws IOException {
// 测试
File oldFile = new File("/Users/lanou/Desktop/Test");
File newFile = new File("/Users/lanou/Desktop/XTest");
copyFile(oldFile, newFile);
}
/*
* 复制文件夹方法
* 参数
* oldFile 源文件夹(要被复制的)
* newFile 目标文件夹(要把源文件夹复制进去)
*/
public static void copyFile(File oldFile,File newFile) throws IOException {
// 在目标文件夹下 创建 新的文件夹 名字和 源文件夹一样
File newDir = new File(newFile, oldFile.getName());
newDir.mkdir();
/*
* 复制文件 -> 找到文件 -> 一边读 一边写
* -> 找到文件夹 -> 继续调用本方法
*/
// 遍历源文件夹
File[] listFiles = oldFile.listFiles();
int len = 0;
for (File subFile : listFiles) {
// 判断是文件
if (subFile.isFile()) {
// 进行读写
FileInputStream fis = new FileInputStream(subFile);
// 要在新建的文件夹下写入 newDir + subFile.getName;
File tempFile = new File(newDir, subFile.getName());
FileOutputStream fos = new FileOutputStream(tempFile);
// 循环写入(写入数组)
byte[] b = new byte[1024];
while ((len = fis.read(b)) != -1) {
fos.write(b, 0, len);
}
// 关闭资源
fis.close();
fos.close();
}else {
// 是文件夹 需要创建文件夹 继续遍历读写
copyFile(subFile, newDir);
}
}
}
}
将一个文件夹的所有txt文件 复制 到另一个文件夹下
public class Demo03 {
public static void main(String[] args) throws IOException {
File oldFile = new File("/Users/lanou/Desktop/Test");
File newFile = new File("/Users/lanou/Desktop/XTest");
getOldFlieTxtToNewFile(oldFile, newFile);
}
public static void getOldFlieTxtToNewFile(File oldFile, File newFile) throws IOException {
// 将过滤器直接传到 文件数组中
File[] listFiles = oldFile.listFiles(new TXTFiles());
for (File subFile : listFiles) {
// 创建 输出 输入流
if (subFile.isFile()) {
FileInputStream fis = new FileInputStream(subFile);
File tempFile = new File(newFile, subFile.getName());
FileOutputStream fos = new FileOutputStream(tempFile);
byte[] b = new byte[1024];
int len = 0;
if ((len = fis.read(b)) != -1) {
fos.write(b, 0, len);
}
fis.close();
fos.close();
}else {
getOldFlieTxtToNewFile(subFile, newFile);
}
}
}
}
// 过滤器
class TXTFiles implements FileFilter{
@Override
public boolean accept(File pathname) {
//是文件夹 则返回一个true
if (pathname.isDirectory()) {
return true;
}
// 如果后缀名是txt的 则 返回true
return pathname.getName().endsWith("txt");
}
}
Day.24