java笔记——IO框架

目录

1.流的概念

 2.流的分类

 3.字节流

 3.1文件字节流

3.2案例进行图片复制

3.3字节缓冲流

4.对象流

5序列化和反序列化

5.1序列化

5.2反序列化

注意:

 6.字符编码

 7.字符流

7.1字符流的父类(抽象类)

 7.2文件字符流

案例:使用FileReader和FileWriter复制文本文件

7.3字符缓冲流

7.4PrintWriter

7.5转换流

8.File类

 文件操作:

文件夹操作:

8.1FileFilter接口 

 案例1:遍历文件夹

案例2:递归删除文件夹


学习目标:

 1.流的概念 4.编码方式
2.流的分类 5.字符流
3.字节流 6.File类

1.流的概念

内存与存储设备之间传输数据的通道

java笔记——IO框架_第1张图片

 2.流的分类

按方向【重点】

  1. 输入流:将<存储设备>中的内容读到<内存>
  2. 输出流:将<内存>中的内容写到<存储设备>

java笔记——IO框架_第2张图片

按单位

  1. 字节流:以字节为单位,可以读写所有数据
  2. 字符流:以字符为单位,只能读写文本数据

按功能

  1. 节点流:具有实际传输数据的读写功能
  2. 过滤流:在节点流的基础之上增强功能

 3.字节流

 字节流的父类(抽象类)

  1. InputStream:字节输入流
    1. 此抽象类是表示字节输入流的所有类的超类

//InputStream 字节输入流
public int read(){}
public int read(byte[] b){}
public int read(byte[] b, int off, int len){}

​
  1. OutputStream:字节输出流 
    1. 此抽象类是表示字节输出流的所有类的超类
// OutputStream 字节输出流
public void write(int n){}
public void write(byte[] b){}
public void write(byte[] b, int off, int len){}

 3.1文件字节流

  • FileInputStream:
    • . public int read (byte[] b)//从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。
psvm(String[] args) throws Exception{
  // 1 创建FileInputStream 并指定文件路径
  FileInputStream fis = new FileInputStream("d:\\abc.txt");
  // 2 读取文件
  // fis.read();
  // 2.1单字节读取
  int data = 0;
  while((data = fis.read()) != -1){
    sout((char)data);
  }
  // 2.2 一次读取多个字节
  byte[] buf = new byte[3]; // 大小为3的缓存区
  int count = fis.read(buf); // 一次读3个
  sout(new String(buf));
  sout(count);
  int count2 = fis.read(buf); // 再读3个
  sout(new String(buf));
  sout(count2);
  
  // 上述优化后
  int count = 0;
  while((count = fis.read(buf)) != -1){
    sout(new String(buf, 0, count));
  }
  
  // 3 关闭
  fis.close();
}

  • FileOutputStream: 
    •  public void write(byte[] b)//一次写多个字节将b数组中所有字节,写入输出流。
package com.study.BytesMessage;

import java.io.FileOutputStream;

/*
 * FileOutputStream使用
 * 文件字节输出流
 * */
public class FileOutputStreamDemo {
	public static void main(String[] args) throws Exception{
		//创建FileOutputStream文件字节输出流
		FileOutputStream fos=new FileOutputStream("d:\\fos.txt");
        //加上,true可以在同一个文件重复写
		//写入文件
		fos.write(97);
		fos.write('b');
		fos.write('c');
		//多字节输入
		String string="\n"+"Hello Word!";
		fos.write(string.getBytes());
		fos.close();
		System.out.println("工作完成");
	}
}

3.2案例进行图片复制

package com.study.BytesMessage;

import java.io.FileInputStream;
import java.io.FileOutputStream;

/*
 * 使用文件字节流实现文件的复制
 * */
public class demo {
	public static void main(String[] args) throws Exception {
		//创建文件输入流
		FileInputStream fis=new FileInputStream("d:\\001.png");
		//创建输出流
		FileOutputStream fos=new FileOutputStream("d:\\002.png");
		byte[] buf=new byte[512];
		int count=0;
		while ((count=fis.read(buf))!=-1) {
			fos.write(buf, 0, count);
		}
		fis.close();
		fos.close();
		System.out.println("复制完成");
	}
}

3.3字节缓冲流

缓冲流:BufferedInputStream/ BufferedOutputStream

  • 提高IO效率,减少访问磁盘次数
  • 数据存储在缓冲区中,flush是将缓冲区的内容写入文件中,也可以直接close

 BufferedInputStream:

package com.study.BytesMessage;

import java.io.BufferedInputStream;
import java.io.FileInputStream;

/*
 * 字节缓冲流
 * BufferedInputStream的使用
 * */
public class BufferedInputStreamDemo {
	public static void main(String[] args) throws Exception {
		FileInputStream fil=new FileInputStream("d:\\file.txt");
		BufferedInputStream bis=new BufferedInputStream(fil);
		//BufferedInputStream存在是为了FileInputStream服务的
		//要使用BufferedInputStream就要有一个节点流
		//BufferedInputStream自带的缓冲去大小8k
//		int data=0;
//		while ((data=bis.read())!=-1) {
//			System.out.println((char)data);
//		}
		//也可以自定义缓冲区
		byte[] buf=new byte[1024];
		int count=0;
		while ((count=bis.read(buf))!=-1) {
			System.out.println(new String(buf, 0, count));
		}
		bis.close();//关闭缓冲流,节点流也会关闭
		System.out.println("工作完成");
	}
}

BufferedOutputStream:

package com.study.BytesMessage;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;

/*
 * 字节缓冲流
 * BufferedOutputStream的使用
 * */
public class BufferedOutputStreamDemo {
	public static void main(String[] args) throws Exception {
		FileOutputStream fileOutputStream=new FileOutputStream("d:\\bos.txt");
		BufferedOutputStream bos=new BufferedOutputStream(fileOutputStream);
		//BufferedOutputStream同理
		for(int i=0;i<10;i++) {
			bos.write("Hello Word!\n".getBytes());//此时只是把字节存入8k缓冲区中
			bos.flush();//要不断刷新
		}
	}
}

4.对象流

ObjectOutputStream / ObjectInputStream

  1. 增强了缓冲区功能
  2. 增强了读写8种基本数据类型和字符串的功能
  3. 增强了读写对象的功能
    1. readObject() 从流中读取一个对象
    2. writeObject(Object obj) 向流中写入一个对象

使用流传输对象的过程称为序列化、反序列化

5序列化和反序列化

5.1序列化

/*
 * 使用ObjectOutputStream实现对象的序列化
 *要求序列化的类要实现Serializable接口
 * */
public class ObjectOutputStreamDemo {
	public static void main(String[] args) throws Exception {
		//创建对象流与缓冲流同理
		FileOutputStream fos=new FileOutputStream("d:\\stu.bin");
		ObjectOutputStream oos=new ObjectOutputStream(fos);
		//序列化(写入操作)
		Student hcq=new Student("hcq", 22);
		oos.writeObject(hcq);
		oos.close();
		System.out.println("工作完成");
		//首次运行会出现报错
		//要对student类里标记一个接口Serializable
	}
}

5.2反序列化

/*
 * 使用ObjectInputStream实现反序列化(读取重构对象)
 * */
public class ObjectInputStreamDemo {
	public static void main(String[] args) throws Exception{
		//创建对象流
		FileInputStream fis=new FileInputStream("d:\\stu.bin");
		ObjectInputStream ois=new ObjectInputStream(fis);
		//读取文件(反序列化)
		Student s=(Student)ois.readObject();
		//关闭
		ois.close();
		System.out.println("工作wc");
		System.out.println(s.toString());
	}
}

注意:

  1. 某个类要想序列化必须实现Serializable接口
  2. 序列化类中对象属性要求实现Serializable接口
  3. 序列化版本号ID,保证序列化的类和反序列化的类是同一个类
  4. 使用transient修饰属性,这个属性就不能序列化
  5. 静态属性不能序列化
  6. 序列化多个对象,可以借助集合来实现

 6.字符编码

  1. ISO-8859-1收录除ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。
  2. UTF-8        针对Unicode码表的可变长度字符编码
  3. GB2312        简体中文(95年前使用)
  4. GBK        简体中文、扩充(是GB2312的升级)
  5. BIG5台湾,繁体中文
  6. 当编码方式和解码方式不一致时, 会出现乱码。

 7.字符流

public static void main(String[] args) throws Exception{
		//传统字节流读取
		FileInputStream fis=new FileInputStream("d:\\hello.txt");
		int data=0;
		while ((data=fis.read())!=-1) {
			System.out.print((char)data);
		}
		fis.close();
		/*第一次文本内容:helloword
		 * 输出:helloword
		 * 第二次文本内容:好好学习
		 * 输出:????????????乱码
		 * 因为文本使用utf_8编码4个汉字12字节,一个汉字3字节
		 * 而FileInputStream是一个字节一个字节的读
		 * 无法凑成一个汉字所需的3个字节,所以乱码
		 * */
	}

7.1字符流的父类(抽象类)

reader 字符输入流:

  1. public int read(){}
  2. public int read(char[] c){}
  3. public int read(char[] b, int off, int len){}

Writer 字符输出流:

  1. public void write(int n){}
  2. public void write(String str){}
  3. public void write(char[] c){}

 7.2文件字符流

FileReader:

public int read(char[] c)//从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果达到文件的尾部,则返回-1。

package com.study.Characterstream;

import java.io.FileReader;
import java.io.FileWriter;
import java.nio.charset.Charset;

public class FileReaderDemo {
	public static void main(String[] args) throws Exception {
		//创建
		FileReader fr=new FileReader("d:\\hello.txt");
		//2.1单个字符写入
//		int data=0;
//		while ((data=fr.read())!=-1) {
//			System.out.print((char)data);
//		}
		//2.2自定义数组读
		char[] buf=new char[1024];
		int count=0;
		while ((count=fr.read(buf))!=-1) {
			System.out.println(new String(buf, 0, count));
		}
		fr.close();
		
	}
}

FileWriter:

public void write(String str)//一次写多个字符,将b数组中所有字符,写入输出流。

package com.study.Characterstream;

import java.io.FileWriter;

public class FileWriterDemo {
	public static void main(String[] args) throws Exception{
		//创建FileWriter对象
		FileWriter fw=new FileWriter("d:\\FileWriter.txt");
		//写入
		for (int i = 0; i < 10; i++) {
			fw.write("好好学java"+"\n");
			fw.flush();
		}
		fw.close();
		System.out.println("工作完成");
	}
}

案例:使用FileReader和FileWriter复制文本文件

注意:二者只可以复制文本文件,无法复制图片和其他二进制文件

package com.study.Characterstream;

import java.io.FileReader;
import java.io.FileWriter;

/*
 * 使用FileReader和FileWriter复制文本文件
 * 注意:二者只可以复制文本文件,无法复制图片和其他二进制文件
 * */
public class Demo2 {
	public static void main(String[] args) throws Exception{
		FileReader fr=new FileReader("d:\\FileWriter.txt");
		FileWriter fw=new FileWriter("d:\\FileWriter2.txt");
		int data=0;
		while ((data=fr.read())!=-1) {
			fw.write(data);
			fw.flush();
		}
		fr.close();
		fw.close();
		System.out.println("工作完成");
	}
}

7.3字符缓冲流

BufferedReader / BufferedWriter

  1. 高效读写
  2. 支持输入换行符
  3. 可一次写一行读一行

 bufferedReader:

package com.study.Characterbufferstream;

import java.io.BufferedReader;
import java.io.FileReader;

/*
 * 字符缓冲流
 * */
public class bufferedReaderDemo {
	public static void main(String[] args) throws Exception {
		//创建字符缓冲流,要配合字符流使用
		FileReader fr=new FileReader("d:\\FileWriter.txt");
		BufferedReader br=new BufferedReader(fr);
		//读取
		//自定义区间读取
//		char[] buf=new char[1024];
//		int count=0;
//		while ((count=br.read(buf))!=-1) {
//			System.out.println(new String(buf, 0, count));
//		}
		//一行一行读
		String line=null;
		while ((line=br.readLine())!=null) {
			System.out.println(line);
		}
		br.close();
	}
}

BufferedWriter:

package com.study.Characterbufferstream;

import java.io.BufferedWriter;
import java.io.FileWriter;

public class bufferedWriterDemo {
	public static void main(String[] args) throws Exception {
		//创建,同理
		FileWriter fw=new FileWriter("d:\\buff.txt");
		BufferedWriter bw=new BufferedWriter(fw);
		//写入
		for (int i = 0; i < 10; i++) {
			bw.write("好好学习,天天向上");
			bw.newLine();//插入一个换行符,兼容性更好
			bw.flush();
		}
		bw.close();
		System.out.println("工作完成");
	}
}

7.4PrintWriter

封装了print() / println() 方法 支持写入后换行

支持数据原样打印

package com.study.Characterstream;

import java.io.PrintWriter;

/*
 * PrintWriter的使用
 * 封装了print() / println() 方法 支持写入后换行
 * 支持数据原样打印
 * */
public class PrintWriterDemo {
	public static void main(String[] args)  throws Exception {
		//创建
		PrintWriter pw=new PrintWriter("d:\\println.txt");
		//打印
		pw.println(true);
		pw.println(3.14);
		pw.println("hcq");
		pw.println(97);
		pw.println('a');
		char[] arr={'a','b','c'};
		pw.println(arr);
		pw.close();
		System.out.println("工作完成");
	}
}

7.5转换流

  1. 桥转换流 InputStreamReader / OutputStreamWriter
  2. 可将字节流转换为字符流
  3. 可设置字符的编码方式

 InputStreamReader:

package com.study.Characterstream;

import java.io.FileInputStream;
import java.io.InputStreamReader;

/*
 * InputStreamReader的使用,可以指定编码形式
 * */
public class InputStreamReaderDemo {
	public static void main(String[] args) throws Exception{
		//创建流
		FileInputStream fis=new FileInputStream("d:\\buff.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("工作完成");
	}
}

OutputStreamWriter:

package com.study.Characterstream;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

/*
 * OutputStreamWriter的使用
 * */
public class OutputStreamWriterDemo {
	public static void main(String[] args)  throws Exception{
		//创建
		FileOutputStream fos=new FileOutputStream("d:\\ops.txt");
		OutputStreamWriter ops=new OutputStreamWriter(fos, "utf-8");
		//写入
		for (int i = 0; i < 10; i++) {
			ops.write("好好学习,天天向上\n");
			ops.flush();
		}
		ops.close();
		System.out.println("工作完成");
	}
}

8.File类

  • 概念:代表物理盘符中的一个文件或者文件夹
  • 方法: 
    • createNewFile()//创建一个新文件
    • mkdir()//创建一个新目录
    • delete()//删除文件或空目录
    • exists()//判断File对象所对象所代表的对象是否存在
    • getAbsolutePath()//获取文件的绝对路径
    •  getName ()//取得名字
    •  getParent ()//获取文件/目录所在的目录
    • isDirectory ()//是否是目录
    • isFile()//是否是文件
    • length()//获得文件的长度
    • listFiles()//列出目录中的所有内容
    • renameTo()//修改文件名为

 文件操作:

package com.study.File;

import java.io.File;
import java.lang.reflect.Field;
import java.util.Date;
import javax.xml.crypto.Data;

/*
File类的使用
1. 分隔符
2. 文件操作
3. 文件夹操作
*/
public class Demo {
	public static void main(String[] args) throws Exception {
		separator();
		fileOpe();
	}
	//1.分隔符
	private static void separator() {
		System.out.println("路径分隔符:"+File.pathSeparator);
		System.out.println("名称分隔符"+File.separator);
	}
	//2.文件操作
	private static void fileOpe() throws  Exception{
		//1创建文件file.createNewFile()
		File file=new File("d:\\fiel.txt");//文件存储路径
		//System.out.println(file.toString());
		//1.1判断文件是否存在
		if (!file.exists()) {
			boolean b=file.createNewFile();
			System.out.println("创建结果:"+b);
		}
		/*
		 *file.exists()是一个函数,中文名是检查文件或目录是否存在
		 *file.createNewFile();创建一个新的空文件,创建成功返回true。
		 *当抽象路径制定的文件存在时,创建失败返回false。
		 * */
		// 2. 删除文件
	    // 2.1 直接删除
//	    boolean b1=file.delete(); // 成功true
//	    System.out.println("删除结果:"+b1);
	    // 2.2 使用jvm退出时删除
//	    file.deleteOnExit();
//	    Thread.sleep(5000);//定时5秒删除
		// 3. 获取文件信息
		System.out.println("获取绝对路径" + file.getAbsoluteFile());
	    System.out.println("获取路径:"+file.getPath());
	    System.out.println("获取文件名称:"+file.getName());
	    System.out.println("获取文件父目录"+file.getParent());
	    System.out.println("获取文件长度"+file.length());
	    System.out.println("获取文件创建时间"+new Date(file.lastModified()).toLocaleString());
	    //判断
	    System.out.println("是否可写:"+file.canWrite());
	    System.out.println("是否是文件:"+file.isFile());
	    System.out.println("是否隐藏:"+file.isHidden());
	}
}

文件夹操作:

package com.study.File;

import java.io.File;
import java.util.Date;

/*
 * File类使用
 * 1分隔符
 * 2文件操作
 * 3文件夹操作
 * */
public class Demo2 {
	public static void main(String[] args) throws Exception {
		directoryOpe();
	}
	//分隔符
	private static void separator() {
	
	
	}
	//文件操作
	private static void fileOpe() throws Exception{
		
	}
	private static void directoryOpe() throws Exception {
		//创建文件夹
		File dir=new File("d:\\aaa\\bbb\\ccc");//创建路径
		if (!dir.exists()) {
			//dir.mkdir();//只能创建单级目录
			System.out.println("创建结果:"+dir.mkdirs() );//创建多级目录
		}
		//删除文件夹
		//2.1直接删除
		System.out.println("结果:"+dir.delete());
		//注意:不是删除我们创建的一整个目录
		//只是删除我们创建的最底层目录,就是ccc
		//而且要求这个目录里面没有东西,为空,只能删除空目录
		//2.2jvm删除
		dir.deleteOnExit();
		Thread.sleep(5000);
		//获取文件夹信息
		System.out.println("获取绝对路径:"+dir.getAbsolutePath());
		System.out.println("获取路径:"+dir.getPath());
		System.out.println("获取文件夹名称:"+dir.getName());
		//得到的是最底层文件夹的名称
		System.out.println("获取父目录"+dir.getParent());
		System.out.println("获取创建时间"+new Date(dir.lastModified()).toLocaleString());
		//判断
		System.out.println("是否是文件夹:"+dir.isDirectory());
		System.out.println("是否是隐藏的"+dir.isHidden());
		//遍历文件夹
		File file2=new File("E:\\微信消息备份\\日冕原图");
		String[] files=file2.list();
		for (String string : files) {
			System.out.println(string);
		}
	}
}

8.1FileFilter接口 

  • public interface FileFilter
    • boolean accept(File pathname)
  • 当调用File类中的listFiles()方法时,支持传入FileFilter接口接口实现类,对获取文件进行过滤,只有满足条件的文件的才可出现在listFiles()的返回值中。 
System.out.println("-------FileFilter接口使用--------");
		 File[] files3= file2.listFiles(new FileFilter() {
		//listFiles是一个数组	
			@Override
			public boolean accept(File pathname) {
				if (pathname.getName().endsWith("jpg")) {
					//判断文件名后缀为"jpg",为真打印
					return true;
				}
					return false;
			}
		});
		 for (File file : files3) {
			System.out.println(file.getName());
		}

 案例1:遍历文件夹

package com.study.File;

import java.io.File;

/*
 * 递归遍历文件夹
 * */
public class ListDemo {
	public static void main(String[] args) {
		listDir(new File("D:\\myfiles"));
	}
	private static void listDir(File dir) {
		File[] files=dir.listFiles();
		//创建一个数组
		System.out.println(dir.getAbsolutePath());
		if (files!=null&&files.length>0) {
			//判断这话文件夹是否为空
			for (File file : files) {
				//遍历这个打开的文件夹
				if (file.isDirectory()) {
					//判断打开的文件夹里面是不是还有文件夹
					listDir(file);//是循环上述步骤
				}else {
					System.out.println(file.getAbsolutePath());
				}
			}
		}
	}
}

案例2:递归删除文件夹

private static void deleteDir(File dir) {
		File[] files=dir.listFiles();
		if (files!=null&&files.length>0) {
			for (File file : files) {
				if (file.isDirectory()) {
					deleteDir(file);//递归
				}else {
					//删除操作
					//删除这个文件内的区别文件
					System.out.println(file.getAbsolutePath()+"删除"+file.delete());
				}
			}
		}
		//文件夹内部为为空后在删除本身
		System.out.println(dir.getAbsolutePath()+"删除"+dir.delete());
	}

你可能感兴趣的:(java)