目录
方法递归
字符集
编码-解码
IO流
字节流
字节输入流 InputSream
FileInputStream
字节输出流 OutputSream
FileOutputSream
释放资源的方式
try-catch-finallly
try-with-resource
字符流
字符输入流 Reader
FileReader
文件字符输出流 Writer
FileWriter
缓冲流
字节缓冲流 BufferedInputStream BufferedOutputStream
字符缓冲流 BufferedReader BufferedWriter
转换流
字符输入转换流 InputStreamReader
字符输出转换流 OutputStreamWriter
打印流
PrintStream
PrintWriter
数据流
数据输出流 DataOutputStream
数据输入流 DataInputStream
序列化流
对象字节输出流 ObjectOutputStream
对象字节输入流 ObjectInputStream
注意
IO框架
Commons-io
方法递归
方法调用自身
直接递归:方法直接调用自己
间接递归:方法调用其他方法,其他方法又回调方法自己
递归死循环 -> 栈内存溢出错误
递归公式 + 递归终结点 + 其方向要走向终结点
其他应用:文件搜索
private static void searchFile(File dir, String fileName) throws Exception {
if(dir == null || !dir.exists() || dir.length() == 0 ){
System.out.println("没找到");
return;
}
File[] files = dir.listFiles();
if(files != null && files.length > 0){
for (File file : files) {
if (file.isFile()){
if (file.getName().contains(fileName)){
System.out.println("路径为"+file.getAbsolutePath());
// 启动软件
Runtime runtime = Runtime.getRuntime();
runtime.exec(file.getAbsolutePath());
}
}else {
searchFile(file,fileName);
}
}
}
}
private static void deleteDir(File dir) {
if (dir == null || !dir.exists() || dir.length() == 0) {
return;
}
// 是文件则删除
if (dir.isFile()){
dir.delete();
return;
}
// 空文件夹则删除
File[] files = dir.listFiles();
if (files == null){
return;
}
// 遍历当前文件夹下的所有。是文件则删除,是文件夹再进入
for (File file : files) {
if (file.isFile()){
file.delete();
}else {
deleteDir(file);
}
}
dir.delete();
}
字符集
ASCII 0xxxxxxx 英文数字符号
GBK 1xxxxxxx xxxxxxxx 汉字2 英文数字1
unicode - UTF-8 可变长编码方案 1-4个字节
英文、数字等只占1个字节(兼容ASCII),汉字占3个字节
编码-解码
IO流
I(Input) 输入流:把数据读到内存中
O(Output) 输出流:负责写数据出去
按流中数据的最小单位 可分为:
字节流 适合操作所有类型文件
字符流 只适合操作纯文本
字节流
字节输入流 InputSream
FileInputStream
每次读取一个字节 read()
InputStream is = new FileInputStream(("文件路径"));
int b;
while((b = is.read()) != -1){
System.out.print((char)b);
is.close();
}
每次读一个字节,读取性能较差,读取中文输出为乱码
每次读取多个字节 read(byte[] buffer)
byte[] buffer = new byte[3];
int len;
while((len = is.read(buffer)) != -1){
// 读多少,倒多少
String rs = new String(buffer, 0, len);
System.out.print(rs);
}
is.close;
读取汉字时有可能出现乱码,因为汉字三个字节可能分开读入了
解决方案:把文件内的所有字节一次性读取
但是还是存在问题
如果文件过大,创建的字节数组也会过大,可能引起内存溢出
因此字符流更适合读写文本,字节流更适合做数据的转移,比如文件复制
字节输出流 OutputSream
FileOutputSream
注意覆盖与追加
换行
os.write("\r\n".getBytes());
拷贝文件
复制文本、图片、视频等,任何文件都可以
释放资源的方式
try-catch-finallly
只有虚拟机终止 System.exit(0);时不会执行finally中的内容
不要在finally中return数据
一般用于在程序执行完成之后释放资源
InputStream is = null;
OutputStream os = null;
try{
...}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(os != null)os.close();
}catch(Exception e){
e.printStackTrace();
}
try{
if(is != null)os.close();
}catch(Exception e){
e.printStackTrace();
}
}
try-with-resource
字符流
字符输入流 Reader
FileReader
try(
Reader fr = new FileReader("文件路径");
){
// 每次读取单个字符
int c;
while((c = fr.read()) != -1){
System.out.print((char)c);
}
// 每次读取多个字符
char[] buffer = new char[3];
int len;
while((len = fr.read(buffer)) != -1){
System.out. print(new String(buffer, 0, len));
}
}catch(Exception e){
e.printStackTrace();
}
文件字符输出流 Writer
FileWriter
注意写文件时,是覆盖还是追加
注意:字符输出流写出数据后,必须刷新流,或者关闭流,写出去的数据才能生效
字符流适合做文本文件的操作(读、写
缓冲流
对原始流进行包装,以提高原始流读写数据的性能
字节缓冲流 BufferedInputStream BufferedOutputStream
原理:字节缓冲输入流自带了8KB缓冲池,字节缓冲输出流也自带了8KB缓冲池
可以修改缓冲池大小
字符缓冲流 BufferedReader BufferedWriter
自带8KB的字符缓冲池,提高字符输入流读取字符数据的性能,提高字符输出流写字符数据的性能
字符缓冲输入流
字符缓冲输出流
低级流不一定比包装流差,缓冲池也不是越大越好
转换流
如果代码编码和被读取的文本编码一致,使用字符流读取文本文件时不会出现乱码,不一致时则会出现乱码
字符输入转换流 InputStreamReader
解决不同编码时,字符流读取文本内容乱码的问题。
先获取文件的原始字节流,再将其按真实的字符集编码转成字符输入流,这样字符输入流中的字符就不乱码了
字符输出转换流 OutputStreamWriter
控制写出去的字符使用指定字符集编码
1.可以调用String的getBytes
String data = "一串字符";
byte[] bytes = data.getBytes("GBK");
2.也可以使用字符输出转换流
获取字符输出流,再按照指定的字符集编码将其转换成字符输出流,以后写出去的字符就会用该字符集编码了
打印流
方便高效的打印数据出去
PrintStream
打印什么、存储什么
PrintWriter
PrintStream和PrintWriter都方便高效,PrintStream继承自字节输出流OutputStream,支持写字节数据的方法,PrintWriter继承自字符输出流Writer,支持写字符数据出去
打印流还可以重定向输出语句:
PrintStream ps = new PrintStream("文件路径");
System.setOut(ps);
System.out.println("要打印的内容");
这样输出语句不会打印在控制台,而是在指定的文件内
数据流
数据输出流 DataOutputStream
允许把数据和其类型一并写出去
数据输入流 DataInputStream
用于读取数据输出流写出去的数据
序列化流
对象序列化:把Java对象写入到文件中去
对象反序列化:把文件里的Java对象读出来
对象字节输出流 ObjectOutputStream
把Java对象进行序列化
对象要序列化,必须要实现序列化接口 Serializable
对象字节输入流 ObjectInputStream
把Java对象进行反序列化
注意
1.在序列化时,如果想将对象中某变量不序列化
可以在类中,在变量前加上transient修饰符,此时该成员变量不参与序列化
2.如果要一次性序列化多个对象,可以用ArrayList集合存储多个对象,然后直接对集合进行序列化[因为ArrayList集合已实现序列化接口 Serializable]
IO框架
框架:解决某类问题编写的一套类、接口等
在框架的基础上开发,可以得到优秀的软件架构,提高开发效率
jar包
IO框架:封装了Java的对文件、数据进行操作的代码,提供更简单的方式操作文件、读写数据
Commons-io
把要用的框架下载好,拷贝要用的jar包,在项目中新建文件夹lib,把jar包粘贴在该文件夹中,右键文件夹Add as Library
Files类也有很多功能啊,好卷,请为我提供呆瓜式编程