Day07=IO+字符流字节流+Properties配置文件+序列化与反序列化

本文详细介绍了Java中的IO流操作,包括文件的创建、读写、删除,以及遍历文件夹的方法。讲解了字节流和字符流的区别,强调了字符编码在文件读写中的重要性,并探讨了如何处理乱码问题。此外,还提到了序列化和反序列化的概念。内容涵盖了File类的常用方法、过滤器的使用以及如何通过PrintWriter和Properties类处理文件。
摘要由CSDN通过智能技术生成

io

读取和写出 in+out

File

文件和目录路径名。描述文件的对象。
File file = new File(path);通过路径来创建文件对象。
createNewFile();不存在时创建新文件
File也可以作为路径。dir.mkdir()不存在时创建文件夹。

  • 构造方法的第二种形式:父目录new File(c://haha,b.txt);
  • 删除:o.delete()
  • listFiles()获取所有文件,返回数组
  • 分隔路径,适配不同系统File.pathSeparator路径分隔符File.separator名称分隔符

如何遍历一个文件夹下的所有文件

//File file = new File(pathname:"e:\\");
//File[] files = e.listFile();//得到这一层的文件
public static void listFiles(File[] files){
	//传入文件数组
	if(files!=null&&files.length>0){
		//找到avi文件
		for(File file:files){
			if(file.isFile()){
				//如果是文件
				if(file.getName().endsWith(".avi")){
					//找到需要的avi文件
					System.out.println(file.getAbsolutePath());//打印绝对路径
					//找大于200MB的文件
					if(file.length()>200*1024*1024){
						file.delete();
				}
			}else{
				//不是文件则是文件夹
				File[] files2 = file.listFiles();
				//递归调用自己
				listFiles(files2);
		}
	}

}

可以通过这样的程序来清理垃圾文件。

文件过滤器

//传入文件
public static void listFiles(File file){
	//1.	创建过滤器 描述规则
	FileFilter filter = new AVIFileFilter();
	//2.	通过文件获取子文件夹
	File[] files = file.listFiles();
	//3.	避免空指针异常
	if(files!=null&&files.length>0)
		for...
	
}

static class AVIFileFilter implements FileFilter{
	//描述规则
	@Override
	public boolean accept(File pathname){
		if(pathname.getName().endsWith(".avi")||pathname.isDirectory());
			return true;
		return false;
		}
	}
}

更优的代码:匿名内部类

//因为过滤器只需要创建并使用一次
File[] files = file.listfiles(new FileFilter(){
	@Override
	public boolean accept(File pathname){
		if(pathname.getName().endsWith(".avi")||pathname.isDirectory()){
			return true;
		}
		return false;
	}
});

相对路径和绝对路径

相对路径是相对项目的

IO流

数据传输看成是流动,按照流动的方向分为输入输出。

  • 输入流输出流
  • 数据类型:字节流(上传下载)字符流(文字乱码问题)

字节流

  • 输入流顶级父类:InputStream 输出流顶级父类:OutputStream

一切皆字节:计算机中的任何数据都是以二进制形式存储,传输时也是以二进制形式存储。任何流在传输时,底层都是二进制。

流的一些重要方法

  • close()使用完毕后关闭流。如果读取完又不释放资源,关不掉,删不掉。
  • flush()刷新输出流,将缓冲的字节输出。
  • write 重载
    • write(byte[] b) 从指定字节数组写入到输出流
    • write(byte[] b, int off, int len) 从偏移量off开始的字节数组len字节写入到输出流
    • write(int b) 指定字节 写入的是b的8个低位,24个高位忽略(int 4字节=32bit 1字节=8bit 最大11111111=255)

FileOutputStream向文件输出流

构造方法:

  • File file写入的文件
  • File file boolean append 追加还是覆盖?
FileOutputStream fos = new FileOutputStream("c://a.txt");
//一般用字符流写
byte[] bytes = "ABCDEF".getBytes();//变成字节数组成为65 66 67 68 69
fos.write(bytes, off:1, len:2);//从1下标开始写,写2个;
fos.close();//记得关闭

FileInputStream

InputStream下的子类。构造方法:

  • File 对象
  • String name路径名
//读取一个字节的方法
FileInputStream fis = new FileInputStream("c://a.txt");
//byte b = fis.read();//报错 返回的是int
byte b = (byte)fis.read();
//if(b==-1) break;//循环打印时结束
//小写的a是97 (char)b转成字符再打印
  • read(byte[] b, int off, int len)读取一组字节。
    注意如果建立byte[10],每次读10个,但每次不会自动清空,所以如果最后不足10个,它只会覆盖前几个,后几个没变。
    输出时: len = fis.read(bytes); 打印new String(bytes, offset:0,len)每次读取时获取长度。
    一次读一组会更快。

字符流&文件利用异或字节加解密

  • 输入流顶级父类:Reader 输出流顶级父类:Writer
//加密存储的新文件 mi-a.png
File newFile = new file(oldFile.getParentFile(), "mi-"+oldFile.getName());
FileInputStream fis = new FileInputStream(oldFile);
FileOutputStream fos = new FileOutputStream(newFile);
while(true){
	int b = fis.read();
	if(b == -1){
		break;
	}
	fos.write(b^=8);//如果知道密钥就可以解密

加密后的文件打不开。

计算机硬件组成

  • 计算机中存储的文件都是二进制
  • 硬件组成:硬盘 显卡 CPU 内存(装在主板上)
  • 硬盘是磁盘,盘上有很多小点,给它加上磁。盘有凹凸不平的地方。凸起就是磁化,可以消除,这就是1。凹进去就是0。
    • 机械硬盘好处,长时间存储。耐高温低温
    • 固态硬盘存取快,不耐高温,时间长了也会丢失。读写速度超级快,NVME协议?一秒3G
  • 内存 读写1s30g、60g。速度快,但是断电就没了。比如游戏里进入地图,地图资源放到内存里。
  • 显卡 图形处理器,解析图像。计算每秒要变化的东西。专门进行浮点运算。结构简单,关注吞吐量。
  • CPU 中央处理器,解析指令
  • 显示器,1920发光体,里面有红绿蓝来控制显示的颜色。
    • 带鱼屏 写代码不需要换行,也可以分屏
    • 可旋转屏幕

字符编码

  • ASCII码让计算机支持文字显示
  • 创建自己语言的编码表,都兼容ASCII码表
  • 英文是不会乱骂的

Unicode编码(UTF-8)

可变长度字符编码

字节流读取文件出现乱码问题

unicode是动态编码表,长度不定。如果设置new byte[10],可能一个字分为两部分两次被读取,就成了乱码。
字符流是按字符来读取的。

字符输入流

写入的单位是字符。构造方法:

FileWriter fw = new FileWriter("c://b.txt",append:true);//追加
  • 有append方法
  • 如果fw2 = (FileWriter) fw.append();那么fw==fw2

字符输出流

FileReader fr = new FileReader("b.txt");
int c = fr.read();
System.out.println((char)c);
//或者是输入到数组里
char[] chars = new char[100];
fr.read(chars);
String text = new String(chars,0,len);

字符和字节输出时不同

  • 字符输出,但是计算机里存储的都是字节。如果有一个字符3个字节,那么会读满3个字节组织成文字输出,否则缓存起来。
  • 写完之后只有关闭(或flush())输入流才会刷新,刷新之后才有文字显示
  • 不刷新,文件内容都在内存里,没有输出的。

字节转换字符流

网上获取的都是字节,需要进行转换

//输入流的转换
FileInputStream ifs = new FileInputStream("c://a.txt");
//字节输入流转换为字符流(装饰者模式)
//要转换的字节流 fis 指定编码名称 
InputStreamReader isr = new InputStreamReader(fis,"gbk");
while(true){
	int c = isr.read();
	if(c==-1){
		break;
	}
}
//输出流的转换
FileOutputStream fos = new FileOutputStream("");

字符输出 打印流

也可以用于转换字符流(原来用的是OutputStreamWriter)
PrintStream ps = new PrintStream("c://c.txt");
PrintWriter pw = new PrintWriter("c://c.txt");
记得要flush()

缓存读取流

将字符输入流转换为带有缓存,可以一次读取一行的缓存字符读取流

BufferedReader br = new BufferedReader(new FileReader("c://c.txt"));
String line = br.readLine();//按行读,结尾返回null

打印异常日志

try{
	String s = null;
	s.toString();
}catch(Exception e){
	//传参传入一个打印流
	PrintWriter pw = new PrintWriter("c://c.txt",true);
	//打印日期
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	pw.println(sdf.format(new Date()));
	e.printStackTrace(pw);
	pw.close();

Properties

是HashTable的子类。跟Map集合一样,所以存键值对。但是扩展的部分跟IO有关系。

public static void main(String[] args) throws FileNotFoundException {
	//.properties文件 配置文件格式
	Properties ppt = new Properties();
	//传入字符流或字节流
	Reader r = new FileReader("");
	ppt.load(r);//加载
	//存储
	FileWriter fw = new FileWriter("c://book.properties");
	ppt.store(fw,comments:"存储的图书");//存入 注意中文会自动转成unicode码
	//输出:ppt.get("name"); ppt.get("info");
	//getProperty也可以获取
}

序列化与反序列化(面试考过)

能不能把对象存到文件里?

/*序列化,输出流*/
Book b = new Book("xx","ss");
//会报错NotSerializableException不让序列化,需要实现接口(会判断instanceof)
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(""));
oos.writeObject(b);
oos.clos();

/*反序列化,输入流*/
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(""));
Object o = ois.readObject();

//没有提供抽象方法只是个标记
static class Book implements Serializable{
	private String name;
	private String info;

	...

	toString(){}
}

总结:

  • 序列化:对象->文件里的内容
  • 反序列化:文件里的内容->对象

try-with-resources

JDK1.7出现

try(FileReader fr = new FileReader("")){
	int c = fr.read();
} catch (IOException e){
	e.printStackTrace();
}/**自动执行
finally{
	try{
		fr.close();
	}catch(Exception e){
		e.printStackTrace();
	}
 */

但如果是传进来的fr 关不掉。
JDK1.9时

FireReader fr = new FileReader("");
PrintWriter pw = ....
//结束时必然调用对象的close()
try(fr;pw){
	//读取
}catch(Exception e){
		e.printStackTrace();
	}

System.getProperty(“line.separator”)获取操作系统对应的换行符

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值