第九章 文件处理IO 代码
1.课前测试
做题之前一定要先 “画结构图”:
文件路径如下:
代码如下:
package com.yzh70706.test1;
public interface INut {
String effect();
}
package com.yzh70706.test1;
/**
* @author: XYT
* @create-date: 2022/7/6 9:01
*/
public class Walnut implements INut{
@Override
public String effect() {
return "吃核桃补脑";
}
}
package com.yzh70706.test1;
/**
* @author: XYT
* @create-date: 2022/7/6 9:02
*/
public class Almond implements INut{
@Override
public String effect() {
return "吃杏仁止咳润肺";
}
}
package com.yzh70706.test1;
public interface ITool {
public void knock(INut iNut);
}
package com.yzh70706.test1;
/**
* @author: XYT
* @create-date: 2022/7/6 9:06
*/
public class Stone implements ITool{
@Override
public void knock(INut iNut) {
System.out.println("用石头敲开坚果");
String s=iNut.effect();
System.out.println(s);
}
}
package com.yzh70706.test1;
/**
* @author: XYT
* @create-date: 2022/7/6 9:08
*/
public class Hammer implements ITool{
@Override
public void knock(INut iNut) {
System.out.println("用锤子敲开坚果");
String s=iNut.effect();
System.out.println(s);
}
}
package com.yzh70706.test1;
/**
* @author: XYT
* @create-date: 2022/7/6 9:08
*/
public class People {
ITool iTool;
public void eat(INut iNut){
this.iTool.knock(iNut);
//iNut.effect(); //这句多余了
}
public void setiTool(ITool iTool){
this.iTool=iTool;
}
}
public class Test {
public static void main(String[] args) {
People p=new People();
Walnut walnut=new Walnut();
Almond almond=new Almond();
ITool it1=new Stone();
ITool it2=new Hammer();
p.setiTool(it1);
p.eat(walnut);
p.setiTool(it2);
p.eat(almond);
}
}
运行结果如下:
2.异常捕获 try{}-catch{}
package com.yzh7.test1;
import java.io.File;
import java.util.Scanner;
/**
* @author: hy
* @create: 2022-07-06 09:47:00
*/
public class Test {
public static int he(int start,int end){
int sum = 0;
for(int i=start;i<=end;i++){
sum+=i;
}
return sum;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
try {
System.out.println("请输入第一个数:");
int num1 = sc.nextInt();
System.out.println("请输入第二个数:");
int num2 = sc.nextInt();
int res = num1 / num2;
System.out.println("结果:" + res);
int sum = he(1, 5);
System.out.println("和:" + sum);
}catch (Exception ex){
System.out.println("出错了:"+ex.getMessage());
}
System.out.println("运行结束");
}
}
3.创建目录/文件 File
//创建目录
directory.mkdirs();
//创建数据文件
file.createNewFile();
package com.yzh7.test1;
import java.io.File;
import java.io.IOException;
/**
* @author: hy
* @create: 2022-07-06 10:10:55
*/
public class Test2 {
public static void main(String[] args) throws IOException {
//File:表示文件对象(目录文件,数据文件)
//通过File对象可以在磁盘上创建文件,也可以访问磁盘上的文件,也可以删除磁盘文件
//File file = new File("d:\\na.txt"); //捺斜杠,要写两个,进行转义
//File file2 = new File("d:/aaa.txt");//撇斜杠(linux主要用这种)
//File.separator:根据系统平台返回对应的路径分隔符
//File file3 = new File("d:"+File.separator+"bbb.txt");
//System.out.println(File.separator);
File directory = new File("d:/xxx/yyy/");
//创建目录
directory.mkdirs();
//使用File创建文件对象
File file =new File("d:/xxx/yyy/aaa.txt");
//判断文件是否存在
System.out.println(file.exists());
//文件不存在则创建文件
if(!file.exists()){
//创建数据文件
file.createNewFile();
}
if(file.exists()) {
//判断文件对象是否是数据文件
System.out.println("是否是数据文件:"+file.isFile());
//判断文件对象是否是目录文件
System.out.println("是否是目录文件:"+file.isDirectory());
//输出文件名字
System.out.println("文件名字:"+file.getName());
//输出文件路径
System.out.println("文件路径:"+file.getPath());
//输出文件大小
System.out.println("文件大小:"+file.length());
//删除文件
//file.delete();
}
}
}
文件的基本操作
4.获取目录所有子文件名/子级文件对象数组
package com.yzh7.test1;
import java.io.File;
import java.lang.reflect.Field;
/**
* @author: hy
* @create: 2022-07-06 10:26:36
*/
public class Test3 {
public static void main(String[] args) {
//创建目录文件
File file = new File("d:/iotest");
//获取目录下的所有子文件名
//String[] names = file.list();
//遍历
// for (String s:names){
// System.out.println(s);
// }
//返回子级文件对象数组
File[] fs = file.listFiles();
for (File f : fs){
System.out.println(f.getPath());
System.out.println(f.getName());
System.out.println(f.canExecute());
System.out.println(f.canWrite());
System.out.println(f.canRead());
System.out.println(f.isDirectory());
System.out.println(f.isFile());
System.out.println(f.length());
System.out.println("=============");
}
}
}
5.遍历目录下的文件
package com.yzh7.test1;
import java.io.File;
/**
* @author: hy
* @create: 2022-07-06 11:06:35
*/
public class Test4 {
public static void main(String[] args) {
//遍历目录下的文件
showFile("d:/iotest");
}
/**
* //遍历目录下的文件
* @param path
*/
public static void showFile(String path){
//构建文件对象
File file = new File(path);
//判断文件是否存在
if(!file.exists()){
System.out.println("文件不存在");
return;
}
//判断文件对象是一个目录还是一个数据文件
if(file.isFile()){
//如果是一个数据文件,则直接返回,不做遍历
System.out.println(file.getPath());
return;
}
//如果是目录,则进行遍历
File[] fs = file.listFiles();
//遍历目录下的子级文件
for (File f: fs){
//如果是数据文件,则输出文件路径和文件大小
if(f.isFile()){
System.out.println(f.getPath()+" "+f.length());
}else if(f.isDirectory()){
System.out.println(f.getPath()+" <DIR>");
//进入子级目录,继续遍历它内部的文件
showFile(f.getPath());
}
}
}
}
6.输入输出字节流的使用
将程序中(内存)的数据写到文件中/将文件中的数据读取到程序中(内存)
package com.yzh7.test2;
import java.io.*;
/**
* @author: hy
* @create: 2022-07-06 11:27:43
*/
public class Test {
//将程序中(内存)的数据写到文件中
public static void w() throws IOException {
//定义文件对象,关联到一个磁盘文件
File file =new File("d:/yzh7.txt");
//创建文件字节输出流对象:可以配置一个追加方式的boolean值
OutputStream os = new FileOutputStream(file,true);
//通过文件输出流对象,写数据到文件中
String s = "abcdef";
os.write(s.getBytes());
//关闭流对象
os.close();
}
//将文件中的数据读取到程序中(内存)
public static void r() throws IOException {
//创建文件对象,关联一个磁盘文件
File file = new File("d:/yzh7.txt");
//创建文件输入字节流对象
//InputStream is = new FileInputStream("d:/yzh7.txt");
InputStream is = new FileInputStream(file);
//通过输入流对象,读取文件内容
//定义字节数组,用于存储读入的内容
byte[] bs = new byte[10];
//读取数据,并返回读取个数。如果读取不到数据时,会返回-1
int count = is.read(bs);
System.out.println("读取的数据长度:"+count);
//读取的内容
/*for (byte b : bs){
System.out.println(b);
}*/
//将读取的内容构建成字符串
String s = new String(bs,0,count);
System.out.println(s);
//关闭流对象
is.close();
}
public static void main(String[] args) throws IOException {
//调用写文件的方法
w();
//r();
}
}
7.将字节数组,转为字符串
package com.yzh7.test2;
/**
* @author: hy
* @create: 2022-07-06 11:36:13
*/
public class Test2 {
public static void main(String[] args) {
//String s = "abcdef";
//通过字符串获取字符串中字符对应的字节数组
/*byte[] bs = s.getBytes();
for (byte b : bs){
System.out.println(b);
}*/
//将字节数组,转为字符串
byte[] bs = {101,102,103,104,105,106};
//将字节数组中,从指定位置开始,指定长度的内容,转为字符串
String str = new String(bs,2,2);
System.out.println(str);
}
}
8.缓冲字节流(处理流/包装流)
package com.yzh7.test3;
import jdk.internal.util.xml.impl.Input;
import java.io.*;
/**
* @author: hy
* @create: 2022-07-07 09:40:09
*/
public class Test{
//缓冲写字节流
public void bw() throws IOException {
//创建文件输出字节流
OutputStream os = new FileOutputStream("d:/0707.txt");
//创建缓冲字节输出流(处理流/包装流)
BufferedOutputStream bos = new BufferedOutputStream(os);
//使用缓冲流对象,写数据
bos.write("hello world".getBytes());
//清空缓冲区
bos.flush();
//关闭流对象
bos.close();
os.close();
}
//缓冲读字节流
public void br() throws IOException {
//创建文件输入字节流
InputStream is = new FileInputStream("d:/0707.txt");
//创建缓冲输入流对象
BufferedInputStream bis = new BufferedInputStream(is);
//使用缓冲输入流读取数据
byte[] bs = new byte[1024];
//将数据读取到字节数组中,并返回读取数据的个数
int count = bis.read(bs);
System.out.println("读取的字节个数:"+count);
//将字节数组构建成字符串
String s = new String(bs,0,count);
System.out.println(s);
//关闭流对象,清空缓冲区
bis.close();
is.close();
}
public static void main(String[] args) throws IOException {
//创建实例对象
Test test = new Test();
//调用实例方法
//test.bw();
test.br();
}
}
9.案例演练 图片复制
package com.yzh7.test3;
import java.io.*;
/**
* @author: hy
* @create: 2022-07-07 09:56:42
*/
public class Test2 {
/**
* 复制文件
* @param srcPath 源文件路径
* @param destPath 目标路径
*/
public static void copyFile(String srcPath,String destPath) throws IOException {
//如何实现文件复制
//创建缓冲输入流,用于读取源文件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcPath));
//创建缓冲输入流,用于写数据到目标文件
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destPath));
//创建字节数组,用于存储每次读取的内容
byte[] bs = new byte[1024];
int count = 0;
//循环读取
while ((count=bis.read(bs))!=-1){
bos.write(bs,0,count);
}
// while (true){
// int count = bis.read(bs);
// //如果读取到的字节个数是-1,则表示读取结束
// if(count==-1){
// //读取结束,退出循环
// break;
// }
// //将读取的数据,写到目标文件中
// bos.write(bs,0,count);
// }
//清空缓冲区
bos.flush();
//关闭流对象:先使用的后关闭,后使用的先关闭
bos.close();
bis.close();
}
public static void main(String[] args) throws IOException {
//文件复制
copyFile("d:/3.jpg","f:/5.jpg");
}
}
10. 对象流 (处理流/包装流)
package com.yzh7.test4;
import java.io.Serializable;
/**
* @author: hy
* @create: 2022-07-07 10:52:45
*/
//注意:1.如果要将一个对象序列化到磁盘上,那么该对象必须实现Serializable接口
// 2.为了保证类的一致性,需要在类中定义版本序列号serialVersionUID
//3.如果类中某个属性不需要序列化,则可以给该字段标记transient
//需要序列化的对象必须实现序列化接口
public class Game implements Serializable {
//定义类的序列化版本号:用于标记当前类,确保类的唯一性
private static final long serialVersionUID=123123123;
//游戏名称
//transient:不进行序列化
private transient String name;
//游戏关卡
private int level;
private int num;
public Game(String name, int level) {
this.name = name;
this.level = level;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
@Override
public String toString() {
return "Game{" +
"name='" + name + '\'' +
", level=" + level +
'}';
}
}
package com.yzh7.test4;
import java.io.*;
/**
* @author: hy
* @create: 2022-07-07 10:53:45
*/
public class Test {
//序列化对象:将内存中的对象数据,写到磁盘上
public static void writeObj() throws IOException {
//创建游戏对象
Game game =new Game("1942重返德军总部",5);
//序列化对象
//创建对象字节输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:/game.obj"));
//使用对象输出流写对象数据
oos.writeObject(game);
//关闭流对象
oos.close();
}
//反序列化:将磁盘上的数据,读取到内存中
public static void readObj() throws IOException, ClassNotFoundException {
//创建对象输入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/game.obj"));
//使用对象流,读取磁盘的对象数据,还原到内存中
Game game = (Game)ois.readObject();
System.out.println(game);
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
//writeObj();
readObj();
}
}
11. 字符流 (输入/输出字符流)
package com.yzh7.test5;
import java.io.*;
/**
* @author: hy
* @create: 2022-07-07 11:14:21
*/
public class Test {
public static final String MY_PATH="d:/aaa.txt";
//写/输出字符流
public static void w() throws IOException {
//创建输入字符流
Writer writer = new FileWriter(MY_PATH);
//写出数据
//char[] cs = new char[]{'我','爱','北','京'};
writer.write("我爱北京天安门");
//关闭流对象
writer.close();
}
//读取/输入字符流
public static void r() throws IOException {
//创建字符输入流
Reader reader = new FileReader(MY_PATH);
//定义字符数组,用于存储读取字符内容
char[] cs = new char[1024];
//读取字符串内容,返回读取的个数
int count = reader.read(cs);
System.out.println("读取的字符个数:"+count);
String s = new String(cs,0,count);
System.out.println(s);
//关闭字符输入流
reader.close();
}
public static void main(String[] args) throws IOException {
//w();
r();
}
}
12.缓冲字符流 (缓冲字符输入流/输出流)
BufferedReader: 缓冲字符输入流
BufferedWriter: 缓冲字符输出流
package com.yzh7.test5;
import java.io.*;
/**
* @author: hy
* @create: 2022-07-07 11:21:34
*/
public class Test2 {
//缓冲读取
public static void r() throws IOException {
//创建字符缓冲流输入流对象
BufferedReader br = new BufferedReader(new FileReader("d:/aaa.txt"));
//直接读取一行数据
String res = br.readLine();
System.out.println(res);
//循环读取,如果读取结果为null,则读取结束
//关闭缓冲流
br.close();
}
//缓冲写出
public static void w() throws IOException {
//创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("d:/aaa.txt"));
//直接写出一行字符串
bw.write("齐天大圣孙悟空");
//换行
bw.newLine();
bw.write("保护唐僧去取经");
//清空缓冲区
bw.flush();
//关闭流对象
bw.close();
}
public static void main(String[] args) throws IOException {
//w();
r();
}
}
13. 字节字符转换流 (处理流/包装流)
InputStreamReader 将字节输入流转换成字符输入流
OutputStreamWriter 将字符输出流转为字节输出流
package com.yzh7.test6;
import java.io.*;
/**
* @author: hy
* @create: 2022-07-07 11:49:22
*/
public class Test {
public static void main(String[] args) throws IOException {
//输入字节字符流
//用字节流读取数据,然后字符流处理
//InputStreamReader isr = new InputStreamReader(new FileInputStream("d:/0707.txt"));
//使用缓冲字符流读取数据
// BufferedReader br =new BufferedReader(new InputStreamReader(new FileInputStream("d:/0707.txt")));
// String res = br.readLine();
// System.out.println(res);
// br.close();
//输出字符字节流
//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:/0707.txt"));
//缓冲字符输出流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:/0707.txt")));
bw.write("这是第一行");
bw.newLine();
bw.write("这是第二行");
bw.close();
}
}
14. 格式化打印流(对于输出流的功能进行增强)
PrintWriter: 是Writer的子类,其作用是将格式化对象打印到一个文本输出流, 主要方
法:print()、println()、write()
package com.yzh7.test6;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
/**
* @author: hy
* @create: 2022-07-07 11:55:50
*/
public class Test2 {
public static void main(String[] args) throws FileNotFoundException {
//打印输出(文件)字符流
//System.out.println("1123123123");
PrintWriter pw = new PrintWriter("d:/bbb.txt");
pw.write("这是一个内容");
pw.println("这是另外一个内容");
//参数占位符:%s 字符串 %d 整数 %f小数
pw.printf("姓名:%s 性别:%s 年龄:%d 身高:%f","张三","男",18,1.7);
//清空缓冲
pw.flush();
//关闭流对象
pw.close();
}
}
15. IO流中的异常处理
package com.yzh7.test1;
import java.io.*;
/**
* @author: hy
* @create: 2022-07-08 09:26:23
*/
public class Test {
public static void main(String[] args) {
//定义文件路径
String srcFilePath = "d:/0707.txt";
String destFilePath="d:/0808.txt";
//创建文件对象
File srcFile = new File(srcFilePath);
File destFile = new File(destFilePath);
//声明流对象变量
InputStream is=null;
OutputStream os=null;
try {
//创建流对象
is = new FileInputStream(srcFile);
os = new FileOutputStream(destFile);
//循环读取并写出实现复制功能
int count = -1;
byte[] bs = new byte[1024];
while (true){
count = is.read(bs);
if(count==-1){
break;
}
//使用输出流写文件
os.write(bs,0,count);
}
} catch (FileNotFoundException e) {
//FileNotFoundException:文件找不到
e.printStackTrace();
} catch (IOException e) {
//IOException:进行io操作出现问题 input ouput
e.printStackTrace();
}finally {
//关闭流对象
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
16.Properties文件的使用
package com.yzh7.test1;
import jdk.internal.util.xml.impl.Input;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.ResourceBundle;
/**
* @author: hy
* @create: 2022-07-08 09:45:23
*/
public class Test2 {
public static void main(String[] args) throws IOException {
//用当前类的类加载器加载属性文件,返回输入流
InputStream is = Test2.class.getClassLoader().getResourceAsStream("stu.properties");
System.out.println(is);
//创建Properties对象(可以存储键值对数据),处理properties文件
Properties properties = new Properties();
//加载数据流
properties.load(is);
//输出学生信息
//properties.getProperty(键):根据键获取值
System.out.println(properties.getProperty("name"));
System.out.println(properties.getProperty("sex"));
System.out.println(properties.getProperty("age"));
System.out.println(properties.getProperty("tall"));
}
}
name=tom
sex=man
age=18
tall=1.7
// An highlighted block
var foo = 'bar';