File文件类
// 相对路径或绝对路径 \\ 或 /
File f1 = new File("C:/Users/LXQ/Desktop/itcast_study/JavaSEPlus_study/gzjavaseproject/readme.txt");
File f2 = new File("readme.txt"); // 相对路径是从当前项目目录开始找
boolean b1 = f1.isFile(); // 判断file对象是文件吗
boolean b2 = f1.isDirectory(); // 判断file对象是目录吗
boolean b3 = f1.exists(); // 判断文件是否存在
System.out.println(f1.getName()); // 获取文件名称
System.out.println(f2.getAbsolutePath()); // 获取文件绝对路径
System.out.println(f2.getPath()); // 获取定义file对象时,使用的路径
System.out.println(f1.length()); // 返回文件中字节个数
System.out.println(f1.lastModified()); // 获取文件最后操作的时间
// 创建与删除
File f4 = new File("test1");
System.out.println(f4.mkdir()); // 新建目录
File f3 = new File("test1/test.txt");
System.out.println(f3.createNewFile()); // 新建文件
File f5 = new File("test2/one");
System.out.println(f5.mkdirs()); // 新建多级目录
删除的注意事项
- 可以删除文件、空文件夹
- 默认不能删除非空文件夹
System.out.println(f3.delete()); // 删除文件目录/文件
System.out.println(f4.delete());
System.out.println(f5.delete());
new File("test2/one").mkdir();
new File("test2/two").mkdir();
new File("test2/three").mkdir();
// 文件目录的遍历
System.out.println(Arrays.toString(new File("test2").list())); // 获取目录文件名称,返回一个String类型数组
File[] f = new File("test2").listFiles(); // 获取一级目录对象数组,返回一个File类型数组
for (File file : f) {
System.out.println(file.getAbsolutePath());
}
方法递归实现文件搜索
public class Demo {
public static boolean mark = false;
public static void main(String[] args) {
File f = new File("C:\\");
selectFile(f,"Maven1.png");
}
public static void selectFile(File dir,String fileName) {
if(mark) return;
if(!dir.exists()) return;
if(dir.isDirectory()){
File[] files = dir.listFiles();
if(files == null) return;
for (File f : files) {
selectFile(f,fileName);
}
}else {
if(dir.getName().equals(fileName)) {
mark = true;
System.out.println(dir.getAbsolutePath());
}
}
}
}
常见字符集
标准ASCII:使用一个字节存储一个字符,二进制中首位为0
GBK:一个中文编码集,两个字节表示汉字(首位为1),一个字节表示数字、字母等(首位为0)
Unicode字符集(规则)
- UTF-32:无论什么字符,都用四个字节存储(不可变),通信效率低。
- UTF-8(开发使用):可变长编码方案,共分为四个长度分区:1个字节、2个字节、3个字节(汉字)、4个字节
编码/解码方式
// idea 默认为 utf-8 字符集编码
String str = "我爱中国123afg";
// 编码方式
byte[] b1 = str.getBytes(); // 默认为utf-8字符集
byte[] b2 = str.getBytes("GBK"); // 参数为字符集名称
// 解码方式
String s1 = new String(b1);
System.out.println(s1);
String s2 = new String(b1,"GBK"); // 字符集不同,结果乱码
System.out.println(s2);
输入/输出流
流区别
- 字节输入输出流适用于数据文件的复制和转移。
- 字符输入输出流比较适用于读写纯文本文件。
- 输入流将数据读取到内存中。
- 输出流将内存中的数据写出去。
字节输入流
InputStream is = new FileInputStream("C:/***/test1.txt");
// read 每次读一个字节,读取效率低下,无法读取汉字
// 若是数据则返回一个int类型数据,字符以Ascll存储;若是无数据,则返回 -1
int b;
while((b = is.read()) != -1){
System.out.print((char)b);
}
// read([]) 每次读取数组,效率提高,但是还是会造成乱码的问题
int len;
byte[] buffer = new byte[4];
while((len = is.read(buffer)) != -1){
// 0,len 取数组中的从0开始的len长度的字节
String s = new String(buffer,0,len);
System.out.print(s);
}
// 文件太大,则会引起内存溢出
byte[] b1 = is.readAllBytes(); // 一次性读取数据
String s1 = new String(b1);
System.out.println(s1);
is.close();
字节输出流
// 覆盖管道
OutputStream os = new FileOutputStream("C:\\***\\test2.txt");
// 追加管道
//OutputStream os = new FileOutputStream("C:\\***\\test2.txt",true);
os.write('a');os.write('b'); // 输出一个字节,字母数字为一个字节大小
os.write("我爱中国".getBytes()); // 输出字节数组
os.write("\t\n".getBytes()); // 文件中换行
os.write("我爱中国".getBytes(),1,11); // 从1开始的11个字节内容
// 刷新,将缓冲区中的数据同步到硬盘中
os.flush();
// 关闭包含了刷新
os.close();
文件复制
File f = new File("C:/***/1.png");
if(!f.exists()) f.createNewFile(); // 创建文件
try(
InputStream is = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream("test\\test4.png");
BufferedOutputStream bos = new BufferedOutputStream(os);
){
byte[] buffer = new byte[1024];
int len;
while((len = bis.read(buffer)) != -1){
bos.write(buffer,0,len);
}
System.out.println("复制成功");
}catch(Exception e){
e.printStackTrace();
}
字符输入流
try (
// 定义资源,出现任何问题都会自动关闭资源
Reader is = new FileReader("C:\\***\\test1.txt");
){
// read 每次读一个字符
int b; // int类型四个字节,可以表示任意字符
while((b = is.read()) != -1){
System.out.print((char)b);
}
// read([]) 每次读取字符数组
int len;
char[] buffer = new char[4];
while((len = is.read(buffer)) != -1){
// 0,len 取数组中的从0开始的len长度的字节
String s = new String(buffer,0,len);
System.out.print(s);
}
} catch (Exception e) {
e.printStackTrace();
}
字符输出流
try (
// 覆盖管道
//Writer os = new FileWriter("C:\\***\\test2.txt");
// 追加管道
Writer os = new FileWriter("C:\\***\\test2.txt",true);
) {
os.write('a');
os.write('b');
os.write("我爱中国");
os.write("\t\n"); // \t\n 换行作用,加上\t主要是解决一些兼容性问题,加上\t任何系统的适用。
os.write("我爱中国",0,2);
} catch (Exception e) {
e.printStackTrace();
}
缓冲流(带有缓冲为高级流)
- 字节缓冲输入流:
BufferedInputStream - 字节缓冲输出流:
BufferedOutputStream - 字符缓冲输入流:
BufferedReader - 字符缓冲输出流:
BufferedWriter
缓冲流为什么提高了读写数据的性能
- 缓冲流自带8KB缓冲区
- 可以提高原始字节流、字符流读写数据的性能
缓冲流与普通的字节/字符流使用方法相同
public BufferedOutputStream(OutputStream os)
public BufferedInputStream(InputStream is)
// 字符流的缓冲流新增了新的功能
public BufferedReader(Reader r)
ublic String readLine() // 读取一行数据
public BufferedWriter(Writer w)
public void newLine() // 写一行数据
字符输入转换流
InputStreamReader
解决字符流读取文本内容乱码的问题,例如读取文件为GBK,Reader默认读取字符集为UTF-8
// 把原始的字节输入流,按照指定字符集编码转成字符输入流(重点)
public InputStreamReader(InputStream is ,String charset);
try (
InputStream s = new FileInputStream("C:\\***\test1.txt");
Reader isr = new java.io.InputStreamReader(s,"GBK");
BufferedReader bs = new BufferedReader(isr);
){
String line;
while((line = bs.readLine()) != null){
System.out.print(line);
}
} catch (IOException e) {
e.printStackTrace();
}
打印流
PrintStream和PrintWriter的区别
- 打印数据的功能上是一模一样的:都是使用方便,性能高效(核心优势)
PrintStream继承自字节输出流OutputStream,因此支持写字节数据的方法。PrintWriter继承自字符输出流Writer,因此支持写字符数据出去。
try (
//PrintStream stdout = new PrintStream("test3.txt");
PrintWriter stdout = new PrintWriter("test3.txt");
// 打印流内部包含了缓冲流,打印效率高效,两者打印功能相同
){
stdout.println(90);
stdout.println("名师出高徒");
stdout.println('9');
}catch(Exception e){
e.printStackTrace();
}
数据输入/输出流
// 数据输入流
try (
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
){
dos.writeInt(1234);
dos.writeDouble(4.56);
dos.writeBoolean(true);
dos.writeChar('a');
dos.writeUTF("我爱中国");
}catch(Exception e) {
e.printStackTrace();
}
// 数据输出流
try (
DataInputStream dos = new DataInputStream(new FileInputStream("data.txt"));
){
// 数据输入流数据输出流如何
int i = dos.readInt();
double v = dos.readDouble();
boolean b = dos.readBoolean();
char c = dos.readChar();
String s = dos.readUTF();
System.out.println(i);
System.out.println(v);
System.out.println(b);
System.out.println(c);
System.out.println(s);
}catch(Exception e) {
e.printStackTrace();
}