Java基础加强14-File、字符的编码与解码、IO流、IO框架
前言:
这个系列记录了我学习面向语言Java的完整过程,可以当作笔记使用。
每篇文章都包含可运行的代码示例和常见错误分析,尤其适合没有编程经验的读者。学习时建议先准备好安装JDK(Java Development Kit)和IDEA(IntelliJ IDEA集成开发环境),随时尝试修改示例代码。
一,File(文件)
1,创建对象:
注:创建对象一般用第一个( File(String pathname) )。
2,创建和删除文件:
3,判断文件类型、获取文件信息:
通过对象调用方法:
4,文件夹的遍历:
示例:
5,文件搜索(递归):
示例:
import java.io.File;
import java.io.IOException;public class Test2 {public static void main(String[] args) {//目标:完成文件搜索,找到C盘下的QQ.exe的位置。try {File dir = new File("C:\\");findFile(dir, "QQ.exe");} catch (IOException e) {e.printStackTrace();}}/*** 递归查找文件* @param dir 搜索的目录* @param name 要搜索的文件名* @throws IOException 当执行外部程序时可能抛出的异常*/public static void findFile(File dir, String name) throws IOException {//1,判断极端情况:如果当前对象是文件、为空或不存在,则直接返回if(dir.isFile()||dir==null||!dir.exists())return ;//2,获取目录下的所有一级文件或者文件夹对象File[] files = dir.listFiles();//3,判断当前目录下是否存在一级文件或者文件夹对象(需有访问权限且存在内容)if(files!=null &&files.length>0){//4,遍历一级文件或者文件夹对象for(File file:files){//5,判断当前对象是否是文件if(file.isFile()){//6,判断文件名是否与目标文件名一致if(file.getName().equals(name)){System.out.println("找到目标文件:"+file.getAbsolutePath());Runtime r = Runtime.getRuntime();//拿到Java的虚拟机对象r.exec(file.getAbsolutePath());//执行找到的.exe程序,需抛异常}}else{//7,如果当前对象是文件夹,则递归调用本方法继续查找findFile(file, name);}}}}
}
二,字符的编码与解码
示例:
import java.util.Arrays;public class Test3 {public static void main(String[] args) throws Exception {// 1、编码String name = "我爱你中国abc666";// byte[] bytes = name.getBytes(); // 平台的UTF-8编码的。通过对象去点方法byte[] bytes = name.getBytes("GBK"); // 指定GBK进行编码。(需抛异常)System.out.println(bytes.length); // 输出编码后的字节数组长度System.out.println(Arrays.toString(bytes)); // 输出编码后的字节数组内容// 2、解码// String name2 = new String(bytes); // 平台的UTF-8解码的。创建字符串对象调用构造器String name2 = new String(bytes, "GBK"); // 指定GBK进行解码(需抛异常)System.out.println(name2); // 输出解码后的字符串}
}
三,IO流(读写文件数据)(了解)
1,认识:
介绍:
分类:
体系:
2,文件字节输入流、输出流:
文件字节输入流:
示例:
注:
文件字节输出流:
示例:
import java.io.FileOutputStream;
import java.io.OutputStream;public class FileOutputStreamDemo1 {public static void main(String[] args) throws Exception {// 目标:学会使用文件字节输出流。// 1,创建文件字节输出流管道于目标文件接通(如果目标文件不存在会自动创建)// OutputStream os =new FileOutputStream("day03-file-io\\src\\file2.txt");//覆盖管道OutputStream os = new FileOutputStream("day03-file-io\\src\\file2.txt", true);// 追加管道// 2、写入数据// public void write(int b)os.write(97); // 写入一个字节数据 Ascll码 aos.write('b'); // 写入一个字符数据// os.write('徐'); // 写入汉字(3个字符)数据 会乱码// 3、写一个字节数组出去// public void write(byte[] b)byte[] bytes = "我爱你中国666".getBytes();os.write(bytes);os.write("\r\n".getBytes()); // 换行 "\r\n".getBytes(),对字符串进行编码成字节数组byte[] b// 4、写一个字节数组的一部分出去os.write(bytes, 0, 3);// 汉字'我',占3个字节os.write("\r\n".getBytes()); // 换行os.close();// 关闭管道}
}
运行结果:
3,文件复制:
示例:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;public class CopyDemo1 {public static void main(String[] args) {//目标:使用字节流完成文件的复制操作。//源文件:C:\Users\t670000000\Desktop\-\图片\mll.jpg//目标文件:C:\Users\t670000000\Desktop\-\图片\fzmll.jpgtry {// 调用复制文件的方法,传入源文件路径和目标文件路径copyFile("C:\\Users\\t670000000\\Desktop\\-\\图片\\mll.jpg","C:\\Users\\t670000000\\Desktop\\-\\图片\\fzmll.jpg");} catch (Exception e) {// 捕获并打印异常信息e.printStackTrace();}}/*** 复制文件的方法* @param srcPath 源文件路径* @param destPath 目标文件路径* @throws Exception 可能抛出的IO异常*/private static void copyFile(String srcPath, String destPath) throws Exception {//1,创建文件字节输入流管道,关联源文件InputStream fis = new FileInputStream(srcPath);//源文件//2,创建文件字节输出流管道,关联目标文件(目标文件不存在会自动创建)FileOutputStream fos = new FileOutputStream(destPath);//目标文件//3,读取一个字节数组,写入一个字节数组(高效复制)byte[] buffer = new byte[1024];// 缓冲区,每次读取1024字节int len;// 记录每次实际读取的字节数// 循环读取:当读取到的字节数不为-1时(未读完),继续读取while ((len = fis.read(buffer)) != -1) {// 写入读取到的字节(从缓冲区0位置开始,写入len个字节)fos.write(buffer, 0, len);//读取多少字节,就写入多少字节}System.out.println("复制成功");// 关闭流管道(先关输出流,再关输入流)fos.close();//关闭输出流管道fis.close();//关闭输入流管道}
}
4,资源释放问题:
资源释放方案:
示例:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;public class CopyDemo1 {public static void main(String[] args) {//目标:掌握资源的新方式:try-with-resources//源文件:C:\Users\t670000000\Desktop\-\图片\mll.jpg//目标文件:C:\Users\t670000000\Desktop\-\图片\fzmll.jpg// 调用复制文件的方法,传入源文件路径和目标文件路径copyFile("C:\\Users\\t670000000\\Desktop\\-\\图片\\mll.jpg","C:\\Users\\t670000000\\Desktop\\-\\图片\\fzmll.jpg");}/*** 复制文件的方法(使用try-with-resources自动管理资源)* @param srcPath 源文件路径* @param destPath 目标文件路径*/private static void copyFile(String srcPath, String destPath) {// try-with-resources语法:资源对象定义在try后的括号中// 资源用完后会自动调用close()方法关闭,无需手动关闭try (// 1,创建文件字节输入流管道,关联源文件InputStream fis = new FileInputStream(srcPath);//源文件// 2,创建文件字节输出流管道,关联目标文件(目标文件不存在会自动创建)FileOutputStream fos = new FileOutputStream(destPath);//目标文件) {// 3,读取一个字节数组,写入一个字节数组(高效复制)byte[] buffer = new byte[1024];// 缓冲区,每次读取1024字节int len;// 记录每次实际读取的字节数// 循环读取:当读取到的字节数不为-1时(未读完),继续读取while ((len = fis.read(buffer)) != -1) {// 写入读取到的字节(从缓冲区0位置开始,写入len个字节)fos.write(buffer, 0, len);//读取多少字节,就写入多少字节}System.out.println("复制成功");} catch (IOException e) {// 捕获并打印IO异常信息e.printStackTrace();}}
}
5,文件字符输入流、输出流:
文件字符输入流:
示例:
import java.io.FileReader;public class FileReaderDemo1 {public static void main(String[] args) {//目标:掌握文件字符输入流读取文件的内容到内存(程序)中。// 使用try-with-resources自动管理资源,流会自动关闭try (//1,创建文件字符输入流管道,与源文件接通FileReader fr = new FileReader("day03-file-io\\src\\file2.txt")) {//2,定义一个字符数组作为缓冲区,用于每次读取多个字符(提升性能)char[] chs = new char[1024];// 每次最多读取1024个字符int len;// 用于记录每次实际读取的字符个数(-1表示读取完毕)// 循环读取:当实际读取的字符数不为-1时,继续读取while ((len = fr.read(chs)) != -1) {//3,将字符数组中实际读取的部分(从0索引开始,长度为len)转换为字符串并输出String str = new String(chs, 0, len);System.out.print(str);}// 拓展:文件字符输入流每次读取多个字符,性能较好,// 而且读取中文是按照字符读取,不会出现乱码!这是一种读取中文很好的方案。} catch (Exception e) {// 捕获并打印异常信息e.printStackTrace();}}
}
文件字符输出流:
示例:
import java.io.FileWriter;public class FileWriterDemo1 {public static void main(String[] args) {//目标:掌握文件字符输出流的使用:写字符出去的流。// 使用try-with-resources自动管理资源,流会自动关闭try (//1,创建一个字符输出流对象,指定写出的目的地。//FileWriter fw = new FileWriter("day03-file-io\\src\\file2.txt")//覆盖管道(每次写入覆盖原有内容)FileWriter fw = new FileWriter("day03-file-io\\src\\file2.txt", true)//追加管道(每次写入在原有内容后追加)) {//2,写一个字符出去:public void write(int c)(支持字符或ASCII码)fw.write('a');// 写入字符'a'fw.write(98);// 写入ASCII码98对应的字符'b'fw.write('陈');// 写入中文字符'陈'(字符流支持中文,无乱码)fw.write("\r\n");// 写入Windows系统换行符//3,写一个字符串出去:public void write(String str)fw.write("Java");// 写入字符串"Java"fw.write("\r\n");// 换行//4,写一个字符串的一部分出去:public void write(String str, int off, int len)// 从字符串索引1开始,写入3个字符("ava")fw.write("java", 1, 3);fw.write("\r\n");// 换行//5,写一个字符数组出去:public void write(char[] cbuf)char[] chars = "我爱你中国666".toCharArray();// 将字符串转为字符数组fw.write(chars);// 写入整个字符数组fw.write("\r\n");// 换行//6,写字符数组的一部分出去:public void write(char[] cbuf, int off, int len)// 从字符数组索引0开始,写入3个字符("我爱你")fw.write(chars, 0, 3);fw.write("\r\n");// 换行// 刷新缓冲区:将缓冲区中的数据强制写入文件(刷新后流仍可继续使用)fw.flush();// fw.close();// 关闭资源:关闭时会自动刷新缓冲区,但关闭后流无法再使用} catch (Exception e) {// 捕获并打印异常信息e.printStackTrace();}}
}
6,缓冲流:
缓冲字节流:
示例:
import java.io.*;public class CopyDemo2 {public static void main(String[] args) {//目标:掌握资源的新方式:try-with-resources//源文件:C:\Users\t670000000\Desktop\-\图片\mll.jpg//目标文件:C:\Users\t670000000\Desktop\-\图片\fzmll.jpg// 调用复制文件的方法,传入源文件路径和目标文件路径copyFile("C:\\Users\\t670000000\\Desktop\\-\\图片\\mll.jpg","C:\\Users\\t670000000\\Desktop\\-\\图片\\fzmll.jpg");}/*** 复制文件的方法(使用缓冲流提升效率,结合try-with-resources自动管理资源)* @param srcPath 源文件路径* @param destPath 目标文件路径*/private static void copyFile(String srcPath, String destPath) {// try-with-resources语法:资源对象定义在try后的括号中// 资源用完后会自动调用close()方法关闭,无需手动关闭try (// 1,创建文件字节输入流管道,关联源文件(低级流)InputStream fis = new FileInputStream(srcPath);//源文件// 把低级的字节输入流包装为高级的缓冲字节输入流(提升读取效率)InputStream bis = new BufferedInputStream(fis);// 2,创建文件字节输出流管道,关联目标文件(低级流,目标文件不存在会自动创建)FileOutputStream fos = new FileOutputStream(destPath);//目标文件// 把低级的字节输出流包装为高级的缓冲字节输出流(提升写入效率)OutputStream bos = new BufferedOutputStream(fos);) {// 3,读取一个字节数组,写入一个字节数组(高效复制)byte[] buffer = new byte[1024];// 缓冲区,每次读取1024字节int len;// 记录每次实际读取的字节数// 循环读取:通过缓冲输入流读取数据,当读取到的字节数不为-1时(未读完),继续读取while ((len = bis.read(buffer)) != -1) {// 通过缓冲输出流写入数据(从缓冲区0位置开始,写入len个字节)bos.write(buffer, 0, len);//读取多少字节,就写入多少字节}System.out.println("复制成功");} catch (IOException e) {// 捕获并打印IO异常信息e.printStackTrace();}}
}
缓冲字符流:
示例:
import java.io.BufferedReader;
import java.io.FileReader;public class FileReaderDemo2 {public static void main(String[] args) {// 使用try-with-resources自动管理资源,流会自动关闭try (//1,创建文件字符输入流管道,与源文件接通(低级流)FileReader fr = new FileReader("day03-file-io\\src\\file2.txt");//2,创建缓冲字符输入流,包装低级的字符输入流(提升读取效率,支持按行读取)BufferedReader br = new BufferedReader(fr);) {String line;// 用于记录每次读取的一行数据// 循环按行读取:readLine()方法读取一行文本(不包含换行符),返回null表示读取完毕while ((line = br.readLine()) != null) {// 输出读取到的一行数据System.out.println(line);}} catch (Exception e) {// 捕获并打印异常信息e.printStackTrace();}}
}
示例:
7,其他流:
1,
2,
3,特殊数据流:
数据输入输出时包括了类型,适合用于通信,不适合查看数据(乱码)。
DataInputStream(数据输入流):
构造器 | 说明 |
---|---|
public DataInputStream(InputStream in) | 创建新数据输入流包装基础的字节输入流 |
方法 | 说明 |
---|---|
public final byte readByte() throws IOException | 从基础字节输入流中读取一个 byte 类型的数据 |
public final int readInt() throws IOException | 从基础字节输入流中读取一个 int 类型的数据 |
public final double readDouble() throws IOException | 从基础字节输入流中读取一个 double 类型的数据 |
public final String readUTF() throws IOException | 从基础字节输入流中读取以 UTF - 8 编码的字符串数据 |
public int read(byte[] b, int off, int len) throws IOException | 从基础字节输入流中读取字节数据到字节数组 b 中,从 off 位置开始,读取 len 个字节 |
public final int readUnsignedByte() throws IOException | 从基础字节输入流中读取一个无符号的 byte 数据(以 int 形式返回) |
public final long readLong() throws IOException | 从基础字节输入流中读取一个 long 类型的数据 |
public final short readShort() throws IOException | 从基础字节输入流中读取一个 short 类型的数据 |
public final boolean readBoolean() throws IOException | 从基础字节输入流中读取一个 boolean 类型的数据 |