IO框架的课程目标
什么是流
- 联系内存中的程序与硬盘中的文件
流的分类(1)
流的分类(2)
字节流的抽象类
FileInputStream的使用
- 第一种:单个字节来读取
//文件字节输入流
//1.创建 FileInputStream,并指定路径
FileInputStream file = new FileInputStream("d:\\aaa.txt");
//2.读取文件-- file.read()只能读取一个字节,读取到最后一个字节返回-1,返回值类型为字符
// 所以需要用一个循环来读取所有的字节
int data=0;
while ((data=file.read())!=-1){
//需要将其转换为char类型,在不输出的位该字符的ASCII值
System.out.print((char) data);
}
//3.关闭IO流
file.close();
System.out.print("执行完毕");
- 第二种:一次读取多个字节
FileInputStream file =new FileInputStream("d:\\aaa.txt");
//使用第二种读取方式,所以先创建一个byte类型的数组,返回值就为读取的个数,读取到最后一个就返回-1
//创建一个字节型数组
byte[] b = new byte[1024];
int count = 0;
while ((count=file.read(b))!=-1) {
System.out.println(new String(b,0,count));
}
file.close();
System.out.println("读取完毕");
/*
abcdefg
读取完毕
*/
FileOuterStream的使用
//文件字节输出流
//1.创建字节输出流对象
FileOutputStream file = new FileOutputStream("d:\\bbb.txt",true); //此处的true是指:不重复覆盖内容了,继续写入文件
//2.写入文件--file.write();只能写入一个字节
String s= "hello,world";
//如果想将s一次写入文件中,则使用s.getBytes();--获取字符串所对应的字节数组
file.write(s.getBytes());
// file.write(97); //a
// file.write('b'); //b
// file.write('d'); //c
//3.关闭
file.close();
System.out.println("执行完毕");
字节流复制文件
//使用文件字节流来进行复制
//1.创建流
//1.1文件字节输入流
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
//1.2文件字节输出流
FileOutputStream fos = new FileOutputStream("d:\\ddd.txt",true); // 此处的true是继续追加
//2.一边读一边写
//创建一个字节数组--一般为1k=1024
byte[] b = new byte[1024];
//count用于保存实际读取字节个数
int count = 0;
while ((count=fis.read(b))!=-1){
fos.write(b,0,count);
}
//3.关闭IO流(2个)
fis.close();
fos.close();
System.out.println("复制完毕");
BufferedInputStream的使用(带缓冲的字节输入流)
//使用字节缓冲流读取
//1.创建BufferedInputStream
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
BufferedInputStream bis = new BufferedInputStream(fis); // 把fis传给他
//2.读取
int data =0;
//此处使用bis来读取,不用fis了
while ((data = bis.read())!=-1){
System.out.print((char)data);
}
//3.关闭--关闭缓冲流就可以
bis.close();
也可以
//使用字节缓冲流读取
//1.创建BufferedInputStream
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
BufferedInputStream bis = new BufferedInputStream(fis); // 把fis传给他
//2.读取
int count =0;
byte[] b = new byte[1024];
while ((count=bis.read(b))!=-1){
System.out.println(new String(b,0,count)); //将数组转为字符串输出
}
//3.关闭--关闭缓冲流就可以
bis.close();
BufferedOuputStream的使用
//使用字节缓冲流写入
FileOutputStream fos = new FileOutputStream("d:\\eee.txt");
//将fos传入进去
BufferedOutputStream bos = new BufferedOutputStream(fos);
//写入文件--用bos
for (int i = 0; i < 5; i++) {
//写入字符串,使用getBytes()来获取字节数组
bos.write("helloworld\r\n".getBytes());//相当于写入一个数组,写入8k的缓冲区
//使用flush--刷新到硬盘
bos.flush();
}
bos.close();
System.out.println("完事了");
对象流
序列化
- 将类对象写入文件中
public class Student implements Serializable {
private String name;
private int age;
//序列化--写入流--ObjectOutputStream
//1.首先先创建一个对象流
FileOutputStream fos = new FileOutputStream("d:\\stu.bin");
//将fos传入ObjectOutputStream中
ObjectOutputStream oos = new ObjectOutputStream(fos);
//2.写入文件--序列化
Student s1 = new Student("张三", 90);
//将类对象写入文件中
oos.writeObject(s1);
//3.关闭--oos
oos.close();
System.out.println("序列化完毕");
需注意:序列化一个类, 该类必须实现Serializable接口,而且该类中的 对象属性 也必须实现Serializable接口!!!
反序列化
- 读取文件中的对象
//序列化--输出流--ObjectInputStream
//1.首先先创建一个对象流
FileInputStream fis = new FileInputStream("d:\\stu.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
//读取对象文件--readObject()
Object o = ois.readObject();
//Object o = ois.readObject(); 会报错---不能读取多次
ois.close();
System.out.println("反序列化完毕");
System.out.println(o.toString()); // Student{name='张三', age=90}
序列化与反序列化的注意事项
- 注意以下事项
常见的字符编码
字符流抽象类
FileReader的使用
- 读取字符
//1.创建一个文件字符输入流
// 因为文件中有中文,如果使用字节流读取的话出现乱码(UTF-8中一个汉字3个字节),所以需要使用字符流来读取
FileReader re = new FileReader("d:\\aaa.txt");
//2.1
int data = 0;
while ((data = re.read()) != -1) {
System.out.print((char) data);
}
//2.2
int count = 0;
char[] c = new char[1024];
while ((count = re.read(c)) != -1) {
System.out.println(new String(c, 0, count));
}
//3.关闭
re.close();
FileWriter使用
- 输出字符
//创建一个FileWriter
FileWriter fw =new FileWriter("d:\\aaa.txt",true);
fw.write("\r\n你好啊程诗雯");
fw.close();
//创建一个FileWriter
FileWriter fw =new FileWriter("d:\\aaa.txt",true);
for (int i = 0; i < 10; i++) {
fw.write("\r\n你好啊程诗雯");
//使用flush进行刷新--存入硬盘中
fw.flush();
}
fw.close();
System.out.println("完毕");
字符流复制文件
注意:使用FileReader和FileWriter只能复制文本文件,不能复制图片,声音,等二进制文件
注意:使用字节流可以复制任意文件
//使用FileReader和FileWriter只能复制文本文件,不能复制图片,声音,等二进制文件
FileReader re = new FileReader("d:\\aaa.txt");
FileWriter fw = new FileWriter("d:\\bbb.txt",true);
int count=0;
char[] c=new char[1024];
while((count=re.read(c))!=-1){
fw.write(c,0,count);
fw.flush();
}
re.close();
fw.close();
System.out.println("复制成功");
BufferedReader的使用
- 新增加一个新的读取方法----readLine() 一行一行的读取,如果读取完事返回Null
// 使用字符缓冲流读取文件
FileReader re = new FileReader("d:\\aaa.txt");
BufferedReader br =new BufferedReader(re);
//1.1
int data = 0;
char[] c= new char[1024];
while((data=br.read(c))!=-1){
System.out.print(new String(c,0,data));
}
//1.2 一行一行的读取---readLine()
String s= null;
while((s=br.readLine())!=null){
System.out.println(s);
}
br.close();
System.out.println("使用字符缓冲流读取文件");
BufferedWriter
- 新增加一个换行方法—newLine();
// 使用字符缓冲流输出文件
FileWriter fw = new FileWriter("d:\\man.bin");
BufferedWriter bw = new BufferedWriter(fw);
for (int i = 0; i < 10; i++) {
bw.write("你真厉害");
//使用newLine()方法进行换行
bw.newLine();
//刷新
bw.flush();
}
bw.close();
System.out.println("使用字符缓冲流输出文件");
PrintWriter(打印流)的使用
- 支持数据原样打印
//1.创建打印流
PrintWriter pw =new PrintWriter("d:\\asf.txt");
//2.打印--print()
pw.println(97);
pw.println(true);
pw.println(3.14);
pw.println('a');
pw.close();
System.out.println("完事");
转换流
转换流的使用
//使用InputStreamReader读取文件,指定使用的编码
//1.创建转换流
//首先创建字节流---将字节流装换为字符流
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
//转换流可以指定编码方式
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
int data=0;
while((data = isr.read())!=-1){
System.out.print((char)data);
}
isr.close();
System.out.println("完成");
//使用OutputStreamReader写入文件,指定使用的编码
//1.创建转换流
//首先创建字节流---将字节流装换为字符流
FileOutputStream fos = new FileOutputStream("d:\\info.txt");
//转换流可以指定编码方式
OutputStreamWriter otw = new OutputStreamWriter(fos,"gbk");
for (int i = 0; i < 10; i++) {
otw.write("我爱北京,我爱故乡\r\n");
otw.flush();
}
otw.close();
System.out.println("完成");
File 类
文件的操作
public static void separator(){
//(1)分隔符
System.out.println("路径分隔符:"+File.pathSeparator); //路径分隔符:;
System.out.println("名称分隔符:"+File.separator);// 名称分隔符:\
}
//(2)文件操作
public static void fileOpen() throws IOException, InterruptedException {
//1.创建文件
File file = new File("d:\\file.txt"); //只是创建了一个文件对象,文件还没有生成 如果不指定哪盘则在当前项目下创建
//使用creatNewFile() 创建文件
if (!file.exists()){// 取反判断
file.createNewFile();
System.out.println("创建成功");
}
// 2.1删除文件---delete()
file.delete();
System.out.println("删除成功");
//2.2删除文件---使用jvm退出时删除 deleteOnExit();
file.deleteOnExit();
Thread.sleep(5000); //休眠5秒
//3.获取文件信息
System.out.println("获取文件的绝对路径"+file.getAbsolutePath());
System.out.println("获取路径"+file.getPath());
System.out.println("获取文件名称"+file.getName());
System.out.println("获取父目录"+file.getParent());
System.out.println("获取文件的长度"+file.length()); //输出字节数,一个汉字3个字节
System.out.println("获取文件的创建时间"+new Date(file.lastModified()).toLocaleString()); //获取文件的创建时间2021-5-12 19:29:47
//4.判断
System.out.println("是否可写:"+file.canWrite());//是否可写:true
System.out.println("是否是文件:"+file.isFile());//是否是文件:true
System.out.println("是否是隐藏的:"+file.isHidden());//是否是隐藏的:false
文件夹的操作
//(3)文件夹的操作
public static void directoryOpe() throws InterruptedException {
//1.创建文件夹 (1)先创建一个dir对象(2)在使用mkdir()进行创建
File dir =new File("d:\\file\\bbb\\ccc");
if (!dir.exists()){
//mkdir()只能创建单级目录 mkdirs()创建多级目录
dir.mkdirs();
}
//2.1删除文件夹
dir.delete(); //注意:只可以删除最里层的目录而且必须为空的!!!
//2.1删除文件夹---jvm进行删除
dir.deleteOnExit(); //也是只能删除最里层的目录
Thread.sleep(5000);
//3.获取文件夹信息
System.out.println("获取文件绝对路径:"+dir.getAbsolutePath()); //获取文件绝对路径:d:\file\bbb\ccc
System.out.println("获取路径:"+dir.getPath()); //获取路径:d:\file\bbb\ccc
System.out.println("获取文件夹名称:"+dir.getName()); //最里层的文件夹名称 获取文件夹名称:ccc
System.out.println("获取文件夹的父目录:"+dir.getParent()); //获取文件夹的父目录:d:\file\bbb
System.out.println("获取文件夹的创建时间:"+new Date(dir.lastModified()).toLocaleString()); //获取文件夹的创建时间:2021-5-12 19:59:20
//4.判断
System.out.println("是否是文件夹:"+dir.isDirectory()); //是否是文件夹:true
System.out.println("文件夹是否是隐藏的:"+dir.isHidden()); //文件夹是否是隐藏的:false
//5.遍历文件夹--list() 返回值为字符串数组
File dir2 = new File("D:\\code");
String[] list = dir2.list();
for (String s : list) {
System.out.println(s);
}
FileFilter 接口
- 使用了匿名内部类
递归遍历和递归删除文件夹
- 递归遍历文件夹(包括子文件夹中的文件)
public static void main(String[] args) throws Exception {
test(new File("D:\\code"));
}
public static void test (File dir) {
//遍历一个文件夹
File[] files = dir.listFiles();
//打印该文件夹的路径
System.out.println(dir.getAbsoluteFile());
if (files!=null&&files.length>0){
for (File file : files) {
if (file.isDirectory()){
test(file);
}else{
System.out.println(file.getAbsoluteFile());
}
}
}
- 递归删除文件夹
public class practice {
public static void main(String[] args) {
test(new File("D:\\新建文件夹"));
}
public static void test(File dir){
File[] files = dir.listFiles();
if (files.length>0&&files!=null){
for (File file : files) {
if (file.isDirectory()){
test(file);
}else{
file.delete();
}
}
}
//上面是删除文件 下面是删除文件夹
dir.delete();
System.out.println("删除成功");
}
}
Properties
Properties的使用
//1.创建一集合
Properties properties = new Properties();
//2.添加数据
properties.setProperty("Usename","lihoa");
properties.setProperty("age", "20");
System.out.println(properties);
//3.遍历
//3.1----keySet
//3.1----entrySet
//3.1----StringPropertyName()
Set<String> strings = properties.stringPropertyNames();
for (String string : strings) {
System.out.println(string+"========="+properties.getProperty(string));
}
//4.和流有关的方法
//---------list方法----------
PrintWriter p =new PrintWriter("d:\\aaa.txt");
properties.list(p);
p.close();
//-----------store保存----------
FileOutputStream fos =new FileOutputStream("d:\\print.properties");//属性集合的扩展名是properties
//properties文件一般不含有中文
//第二个参数是注释
properties.store(fos,"注释");
fos.close();
//-------load方法加载---------
Properties p1 = new Properties();
FileInputStream fis = new FileInputStream("D:\\print.properties");
p1.load(fis);
fis.close();
System.out.println(p1.toString());