此笔记来自于B站黑马程序员
File
创建对象
public class FileTest1 {
public static void main(String[] args) {
// 1.创建一个 File 对象,指代某个具体的文件
// 路径分隔符
// File f1 = new File("D:/resource/ab.txt");
// File f1 = new FIle("D:\\resource\\ab.txt");
File f1 = new File(pathname: "D:" + File.separator + "resource" + File.separator + "ab.txt");
System.out.println(f1.length()); //文件大小
File f2 = new File("D:/resource");
System.out.println(f2.length());
// 注意: File 对象可以代指一个不存在的文件路径
File f3 = new File("D:/resource/aaaa.txt");
System.out.println(f3.length());
System.out.println(f3.exists()); // false
/ **
我现在要定位的文件是在模块中,应该怎么定位呢?
绝对路径:带盘符的
File f4 = new File("D:\\code\\javasepromax\\file-io-app\\src\\itheima.txt");
相对路径(重点):不带盘符,默认是直接去工程下寻找文件的
*/
File f4 = new File("file-io-app\\src\\itheima.txt");
}
}
- File对象既可以代表文件、也可以代表文件夹。
- File封装的对象仅仅是一个路径名,这个路径可以是存在的,也允许是不存在的。
常用方法1:判断文件类型、获取文件信息
就不演示代码了,Java 有一个很好的优势,即见名知意思
常用方法2:创建文件、删除文件
/***
** 目标:掌握 File 的创建和删除文件相关的
**/
public class FileTest3 {
public static void main(String[] args) {
// 1.public boolean createFile(); 创建一个新文件(文件内容为空), 创建成功返回true, 反之
File f1 = new File("D:/resurce/itheima2.txt");
System.out.println(f1.createNewFile());
// 2.public boolean mkdir(); 用于创建文件夹,注意:只能创建一级文件夹
File f2 = new File("D:/resource/aaa");
System.out.println(f2.mkdir());
// 3.public boolean mkdirs() 用于创建文件夹,注意;可以创建多级文件夹
File f3 = new File("D:/resource/bbb/ccc/ddd/eee/fff/ggg");
System.out.println(f3.mkdirs());
// 4.public boolean delete() 删除文件,或者空文件,注意:不能删除非空文件夹
System.out.println(f1.delete());
System.out.println(f2.delete());
File f4 = new File("D:/resource");
System.out.println(f4.delete());
}
}
delete方法默认只能删除文件和空文件夹,删除文件后的文件不会进入回收站
常用方法3:遍历文件夹
public class FilleTest4 {
public static void main(String[] args) {
// 1. public String[] list(): 获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回"
File f1 = new File("D:/course/带研发内容");
String[] names = f1.list();
for (String name : names) {
System.out.println(name);
}
// 2 public File[] listFiles(): (重点)获取当前目录下所有的“一级文件对象"到一个文件对象数组中去返回(重点)
File f = new File("D:/resource/aaa");
File[] files1 = f.listFiles();
System.out.println(Arrays.toString(files1));
}
}
使用 listFiles 方法时的注意事项:
- 当主调是文件,或者路径不存在时,返回null
- 当主调是空文件夹时,返回一个长度为0的数组
- 当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹的路径放在File数组中返回
- 当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
- 当主调是一个文件夹,但是没有权限访问该文件夹时,返回null
前置知识:方法递归
什么是方法递归?
递归是一种算法,在程序设计语言中广泛应用。
从形式上说:方法调用自身的形式称为方法递归(recursion)
递归的形式
直接递归:方法自己调用自己。
间接递归:方法调用其他方法,其他方法又回调方法自己。
使用方法递归时需要注意的问题:
递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误。
文件搜素
package com.itheima.d2_recursion
import java.io.File;
public class RecursionTest3 {
public static void main(String[] args) {
searchFile(new File("D:/"), "QQ.exe");
}
/**
* 去目录下搜索某个文件
* @param dir 目录
* @param fileName 要搜索的文件名称
*/
public static void searchFile(File dir, String fileName) {
// 1.把非法的情况都拦截住
if (dir == null || !dir.exists() || dir.isFile()) {
reutrn;
}
// 2.dir不是null,存在,一定是目录对象
// 获取当前目录下的全部一级文件对象
File[] files = dir.listFiles();
// 3. 判断当前目录下是否存在一级文件对象,以及是否可以拿到一级文件对象
if (files != null && files.length > 0) {
// 4.遍历全部一级文件对象
for (File f : files) {
if (f.isFile()) {
if (f.getName().contains(fileName)) {
System.out.println("找到了: " + f.getAbsolutePath());
}
} else {
searchFile(f, fileName);
}
}
}
}
}
前置知识:字符集
本节要点
- ASCI字符集:只有英文、数字、符号等,占1个字节。
- GBK字符集:汉字占2个字节,英文、数字占1个字节。
- UTF-8字符集:汉字占3个字节,英文、数字占1个字节。
注意1:字符编码时使用的字符集,和解码时使用的字符集必须一致,**否则会出现乱码 **⚠️
注意2:英文,数字一般不会乱码,因为很多字符集都兼容了 ASCII 编码。 ⚠️
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws Exception {
// 1.编码
String data = "a我b";
byte[] bytes = data.getBytes(); // 默认是按照平台字符集 (UTF-8) 进行编码的
System.out.println(Arrays.toString(bytes));
// 按照指定字符集进行编码
byte[] bytes1 = data.getBytes("GBK");
System.out.println(Arrays.toString(bytes1));
// 2.解码
String s1 = new String(bytes);
System.out.println(s1);
String s2 = new String(bytes1, "GBK");
System.out.println(s2);
}
}
IO 流
IO 流的应用场景
IO 流概述
IO流-字节流
文件字节输入流:每次读取一个字节(FileInputStream)
public class FileInputStreamTest1 {
public static void main(String[] args) throws Exception {
// 1. 创建文件字节输入流管道,与源文件接通
// InpustStream is = new FileInputStream(new File("file-io-app\\src\\itheima01.txt"));
// 简化写法,推荐使用
InputStream is = new FileInputStream(("file-io-app\\src\\itheima01.txt"));
// 2.开始读取文件的字节数据
// public int read(); 每次读取一个字节返回,如果没有数据了,返回-1
// int b1 = is.read();
// System.out.println((char)b1);
//
// int b2 = is.read();
// System.out.println((char) b2);
// int b3 = is.read();
// System.out.println(b3);
int b;
while ((b = is.read()) != -1) {
System.out.print((char) b);
}
// 读取的性能很差
// 读取汉字会乱码
// 流使用完毕后,必须关闭,释放系统资源
is.close();
}
}
public class FileInputStreamTest1 {
public static void main(String[] args) throws Exception {
// 1. 创建文件字节输入流管道,与源文件接通
// InpustStream is = new FileInputStream(new File("file-io-app\\src\\itheima01.txt"));
// 简化写法,推荐使用
InputStream is = new FileInputStream(("file-io-app\\src\\itheima01.txt"));
// 2.开始读取文件的字节数据: 每次读取多个数据
// public int read(byte b[]) throws IOException
// 每次读取多个字节到字节数组中去,返回读取的字节数量,读取完毕会返回 -1
byte[] buffer = new byte[3];
int len = is.read(buffer);
String rs = new String(buffer);
System.out.println(rs);
System.out.println("当次读取的字节数量: " + len);
// buffer = [abc]
// buffer = [66c]
int len2 = is.read(buffer);
// 注意:读取多少,倒出多少
String rs2 = new String(buffer, 0, len2);
System.out.println(rs2);
System.out.println("当次读取的字节数量: " + len2);
int len3 = is.read(buffer);
System.out.println(len3); // -1
is.close();
}
}
文件字节输入流:每次读取多个字节 (FileOutputStream)
public class FileInputStreamTest1 {
public static void main(String[] args) throws Exception {
// 1. 创建文件字节输入流管道,与源文件接通
// InpustStream is = new FileInputStream(new File("file-io-app\\src\\itheima01.txt"));
// 简化写法,推荐使用
InputStream is = new FileInputStream(("file-io-app\\src\\itheima01.txt"));
byte[] buffer = new byte[3];
int len; // 记住每次读取了多少个字节。abc 66
while ((len = is.read(buffer)) != -1) {
// 注意:读取多少,倒出多少
String rs = new String(buffer, 0, len);
System.out.print(rs);
}
// 性能得到了明显的提升!!
// 这种方案也不能避免读取汉字输出乱码的问题!!
is.close(); // 关闭流
}
}
文件字节输入流:一次读取完全部字节 (FileReader)
文件字节输入流:一次读取完全部字节
- 方式一: 自己定义一个字节数组与被读取的文件大小一样大,然后使用该字节数组,一次读完文件的全部字节。
public class FileInputStreamTest1 {
public static void main(String[] args) throws Exception {
// 1. 创建文件字节输入流管道,与源文件接通
// InpustStream is = new FileInputStream(new File("file-io-app\\src\\itheima01.txt"));
// 简化写法,推荐使用
InputStream is = new FileInputStream(("file-io-app\\src\\itheima01.txt"));
// 2.准备一个字节数组,大小与文件的大小正好是一样大
File f = new File("file-io-app\\src\\itheima03.txt");
long size = f.length();
byte[] buffer = new byte[(int)size];
int len = is.read(buffer);
System.out.println(new String(buffer));
System.out.println(size);
System.out.println(len);
is.close(); // 关闭流
}
}
方式二:Java官方为lnputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组中返回。
public class FileInputStreamTest1 {
public static void main(String[] args) throws Exception {
// 1. 创建文件字节输入流管道,与源文件接通
// InpustStream is = new FileInputStream(new File("file-io-app\\src\\itheima01.txt"));
// 简化写法,推荐使用
InputStream is = new FileInputStream(("file-io-app\\src\\itheima01.txt"));
byte[] buffer = is.readAllBytes();
System.out.println(new String(buffer));
is.close(); // 关闭流
}
}
总结
文件字节输出流:写字节出去 (FileWriter)
作用:以内存为基准,把内存中的数据以字节的形式写出到文件中去。
public class FileOutputStreamTest4 {
public static void main(String[] args) throws Exception {
//1、创建一个字节输出流管道与目标文件接通。
//覆盖管道:覆盖之前的数据
// OutputStream os =
// new File0utputStream("file-io-app/src/itheima04out.txt");
//追加数据的管道
OutputStream os =
new File0utputStream(name:"file-io-app/src/itheima04out.txt", append:true);
//2、开始写字节数据出去了
os.write(97); //97 就是一个字节,代表 a
os.write('b'); //‘b'也是一个字节
//os.write('磊');//[ooo]默认只能写出去一个字节
byte[] bytes = "我爱你中国abc".getBytes();
os.write(bytes);
os.write(bytes, off:0, len:15);
os.close();//关闭流
}
}
案例:文件复制
public class FileOutputStreamTest4 {
public static void main(String[] args) throws Exception {
// 复制文件
InputStream is = new FileInputStream("file-io-app\\src\\itheima03.txt");
// 2.创建一个字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream("file-io-app\\src\\itheima03copy.txt");
// 1024 * 1024 + 6;
// 3.创建要给字节数组,负责转移字节数组
byte[] buffer = new byte[1024]; // 1kb
int lne;
while ((len == is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
os.close();
is.close();
System.out.println("复制完成!!!");
}
}
IO流-资源释放方式
- finally 代码区的特点:无论 try 中的程序是正常执行了,还是出现了异常,最后都一定会执行 finally区,除非JVM终止。
作用:一般用于在程序执行完成后进行资源的释放操作**(专业级做法)。**
public class Test1 {
public static void main(String[] args) {
try {
System.out.println(10 / 0);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("===finally执行了一次===");
}
}
public static int chu(int a, int b) {
try {
return a / b;
} catch (Exception e) {
return -1;
} finally {
// 千万不要在 finally 中返回数据(会覆盖之前return的语句)
return 111;
}
}
}
public class FileOutputStreamTest4 {
public static void main(String[] args) throws Exception {
InputStream is = null;
OutputStream os = null;
// 复制文件
try {
System.out.println(10 / 0);
is = new FileInputStream("file-io-app\\src\\itheima03.txt");
// 2. 创建一个字节输出流管道与目标文件接通
os = new FileOutputStream("file-io-app\\src\\itheima03copy.txt");
// 制作一个错误
System.out.println(10 / 0);
// 3. 创建要给字节数组,负责转移字节数组
byte[] buffer = new byte[1024]; // 1KB
// 4. 从字节输入流中读取字节数据,写出去到字节输出流中。读多少写出去多少。
int lne; // 记住每次读取了多少个字节
while ((len == is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
System.out.println("复制完成!!!");
} catch(IOException e) {
e.printStackTrace();
} finally {
if (os != null) os.close();
if(is != null) is.close();
}
}
}
JDK7 开始提供了更简单的资源释放方案:try-with-resource****
该资源使用完毕后,会自动调用其 close()方法,完成对资源的释放!
public class FileOutputStreamTest4 {
public static void main(String[] args) throws Exception {
// 复制文件
try (
InputStream is = new FileInputStream("file-io-app\\src\\itheima03.txt");
// 2. 创建一个字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream("file-io-app\\src\\itheima03copy.txt");)
{
System.out.println(10 / 0);
// 制作一个错误
// 3. 创建要给字节数组,负责转移字节数组
byte[] buffer = new byte[1024]; // 1KB
// 4. 从字节输入流中读取字节数据,写出去到字节输出流中。读多少写出去多少。
int lne; // 记住每次读取了多少个字节
while ((len == is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
System.out.println("复制完成!!!");
} catch(IOException e) {
e.printStackTrace();
}
}
}
public class MyConnection implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("释放了与某个硬件的链接资源~~~~");
}
}
- () 中只能放置资源,否则报错
- 什么是资源呢?
- 资源一般指的是最终实现了 AutoCloseable 接口。
- public abstract class InputStream implements Closeable { }
- public abstract class OutputStream implements Closeable, Flushable { }
- public interface Closeable extends AutoCloseable { }
IO 流-字符流(字节流:适合复制文件等,不适合读写文本文件)
文件字符输入流(FileReader)-读字符数据进来
public class itcasttest2 {
public static void main(String[] args) {
try (
// 1.创建一个文件字符输入流管道与源文件接通
Reader fr = new FileReader("io-app2\\src\\itheima01.txt");
) {
char[] buffer = new char[3];
int len; // 记住每次读取了多少字符
while ((len = fr.read(buffer)) != -1) {
// 读取多少倒出多少
System.out.print(new String(buffer, 0, lent));
}
// 性能是比较不错的
} catch (Exception e) {
e.printStackTrace();
}
}
}
文件字符输出流(FileWriter)-写字符数据出去
public class test3 {
public static void main(String[] args) {
try {
( // 0.创建一个文件输出流管道与目标文件接通
// 覆盖管道
// Writer fw = new FileWriter("io-app2/src/itheima02out.txt");
Writer fw = new FileWriter("io-app2/src/itheima02out.txt", true))
{
// 1.public void write(int c)写一个字符出去
fw.write('a');
fw.write(97);
fw.write('磊');
fw.write("\r\n"); //换行(可兼容性好)
// 2.public void write(String c) 写一个字符串出去
fw.write("我爱你中国abc");
fw.write("\r\n");
// 3.public void write(String c, int pos, int len) 写字符串的一部分出去
fw.write("我爱你中国abc", 0, 5);
fw.write("\r\n");
// 4. public void write(char[] buffer): 写一个字符数组出去
char[] buffer = {'黑','马', 'a', 'b', 'c'};
fw.write(buffer);
fw.write("\r\n");
fw.close();
}
}
}
}
**字符输出流写出数据后,必须刷新流,或者关闭流,**写出去的数据才能生效 ⚠️
IO 流-缓冲流
字节缓冲流
提高字节流读写数据的性能
public class BufferInputStreamTest1 {
public static void main(String[] args)) {
tyr (
InputStream is = new FileInputStream("io-app2/src/itheima01.txt");
// 1.定义一个字节缓冲输入流包装原始的字节输入流
InputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream("io-app2/src/itheima01_back.txt");
// 2.定义一个字节缓冲输出流包装原始的字节输出流
OutputStream 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();
}
}
}
字符缓冲流
字符缓冲输入流(BufferedReader)
作用:自带 8K(8192)的字符缓冲池,可以提高字符输入流读取字符数据的性能。
public class BufferedReaderTest2 {
public static void main(String[] args) {
try (
Reader fr = new FileReader("io-app2\\src\\itheima02.txt");
// 创建一个字符缓存输入流包装原始的字符输入流
BufferedReader br = new BufferedReader(fr);
) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
字符缓冲输出流(BufferedWriter)
public class BufferedWriterTest3 {
public static void main(String[] args) {
try (
Writer fw = new FileWriter("io-app2/src/itheimao5out.txt", true);
BufferWriter bw = new BufferedWriter(fw);
) {
bw.write('a');
bw.write(97);
bw.write('磊');
bw.newLine();
bw.write("我爱你中国abc");
bw.newLine();
} catch (Exception e) {
e.printStackTrace();
}
}
}
原始流、缓冲流的性能分析[重点]
测试用例:
分别使用原始的字节流,以及字节缓冲流复制一个很大视频。
测试步骤:
使用低级的字节流按照一个一个字节的形式复制文件。
使用低级的字节流按照字节数组的形式复制文件。
使用高级的缓冲冲字节流按照一个一个字节的形式复制文件。
使用高级的缓冲字节流按照字节数组的形式复制文件。
public class TimeTest4 {
private static final String SRC_FILE = "D:\\resource\\线程池.avi";
private static final String DEST_FILE = "D:\\";
public static void main(String[] args) {
copy01(); //copy01();//低级字节流一个一个字节的赋值,慢的简直让人无法忍受,直接淘汰!
copy02(); //低级的字节流流按照一个一个字节数组的形式复制,速度较慢!
copy03(); // 缓冲流按照一个一个字节的形式复制,速度较慢
copy04(); //缓冲流按照一个一个字节数组的形式复制,速度极快,推荐使用!
}
private static void copy01() {
long startTime = System.currentTimeMillis();
try (
InputStream is = new FileInputStream(SRC_FILE);
outputStream os = new FileOutputStream(DEST_FILE + "1.avi");
) {
int b;
while ((b = is.read()) != -1) {
os.write(b);
}
} catch (Exception e) {
e.printStackTrace();
}
logn endTime = System.currentTimeMillis();
System.out.println("低级字节流一个一个字节复制耗时: " + (endTime - startTime) / 1000.0);
}
private static void copy02() {
long startTime = System.currentTimeMillis();
try (
InputStream is = new FIleInputStream(SRC_FILE);
OutputStream os = new FIleOutputStream(DEST_FILE + "2.avi");
) {
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1 ) {
os.write(buffer, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMIllis();
System.out.println("低级字节流使用字节数组复制耗时: " + (endTime - startTime) / 1000.0 + "s");
}
private static void copy03() {
long startTime = System.currentTimeMillis();
try (
InputStream is = new FileInputStream(SRC_FILE);
BufferInputStream bis = new BufferInputStream(is);
OutputStream os = new FileOutputStream(DEST_FILE + "1.avi");
BufferOutputStream bos = new BufferOutputStream(os);
) {
int b;
while ((b = is.read()) != -1) {
bos.write(b);
}
} catch (Exception e) {
e.printStackTrace();
}
logn endTime = System.currentTimeMillis();
System.out.println("缓冲流一个一个字节复制耗时: " + (endTime - startTime) / 1000.0);
}
private static void copy04() {
long startTime = System.currentTimeMillis();
try (
InputStream is = new FIleInputStream(SRC_FILE);
BufferInputStream bis = new BufferInputStream(is);
OutputStream os = new FIleOutputStream(DEST_FILE + "2.avi");
BufferOutputStream bos = new BufferOutputStream(os);
) {
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1 ) {
bos.write(buffer, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMIllis();
System.out.println("低级字节流使用字节数组复制耗时: " + (endTime - startTime) / 1000.0 + "s");
}
}
IO 流-转换流
-
如果代码编码和被读取的文本文件的编码是一致的,使用字符流读取文本文件时不会出现乱码!
-
如果代码编码和被读取的文本文件的编码是不一致的,使用字符流读取文本文件时就会出现乱码!
引出问题:不同编码读取时会乱码
字符输入转换流 (InputStreamReader)
解决思路:先获取文件的原始字节流,再将其按真实的字符集编码转成字符输入流,这样字符输入流中的字符就不乱码了。
public class InputStreamReaderTest2 {
public static void main(String[] args) {
try (
// 1.得到文件的原始字节流(GBK的字节流形式)
InputStream is = new FileInputStream("io-app2/src/itheima06.txt");
// 2.把原始的字节输入流按照指定的字符集编码转换成字符输入流
Reader isr = new InputStreamReader(is, "GBK");
// 3. 把字符输入流包装成缓冲字符输入流
BufferedReader br = new BufferedReader(isr);
) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
字符输出转换流(OutputStreamWrite)
- 解决思路:获取字节输出流,再按照指定的字符集编码将其转换成字符输出流,以后写出去的字符就会用该字符集编码了。
IO 流-打印流
作用:打印流可以实现更方便、更高效的打印数据出去,能实现打印啥出去就是啥出去。
import java.io.PrintStream;
imort java.nio.charset.Charset;
public class PrintTest1 {
public static void main(String[] args) {
try (
// 1. 创建一个打印流管道
PrintStream ps = new PrintStream("io-app2/src/itheima08.txt", Charset.forName("GBK"));
) {
ps.println(97);
ps.println('a');
ps.println("我爱你中国abc");
ps.println(true);
ps.println(99.5);
ps.write(97);
} catch (Exception e) {
e.printStackTrace();
}
}
}
PrintWriter
PrintStream 和 PrintWriter 的区别
- 打印数据的功能上是一模一样的:两者都是使用方便,性能高效 (核心优势)
- PrintStream 继承自字节 输出流OutputStream,因此支持写字节数据的方法。
- PrintWriter 继承自字符 输出流Writer,因此支持写字符数据出去。
public class PrintTest2 {
public static void main(String[] args) {
System.out.println("老骥伏枥");
System.out.println("志在千里");
try (PrintStream ps = new PrintStream("io-app2/src/itheima09.txt"); ) {
// 把系统默认的打印流对象改成自己设置的打印流
System.setOut(ps);
System.out.println("烈士暮年");
System.out.println("壮心不已");
} catch (Exception e) {
e.printStackTrace();
}
}
}
IO 流-数据流
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class DataOutputStreamTest1 {
public static void main(String[] args) {
try (
// 1. 创建一个数据输出流包装低级的字节输出流
DataOutputStream dos = new DataOutputStream(new FileOutputStream("io-app2/src/itheima10out.txt"));
) {
dos.writeInt(97);
dos.writeDouble(99.5);
dos.writeBoolean(true);
dos.writeUTF("黑马程序员666!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class DataInputStreamTest2 {
public static void main(String[] args) {
try (
DataTnputStream dis = new DataInputStream(new FileInputStream("io-app2/src/itheima10out.txt"));
) {
int i = dis.readInt();
System.out.println(i);
double d = dis.readDouble();
System.out.println(d);
boolean b = dis.readBoolean();
System.out.println(b);
String rs = dis.readUTF();
System.out.println(rs);
} catch (Exception e) {
e.printStackTrace();
}
}
}
IO 流-序列化流
- 对象序列化:把Java对象写入到文件中去
- 对象反序列化:把文件里的java对象读出来
可以把 Java 对象进行序列化:把 Java 对象存入到文件中去
注意:对象如果要参与序列化,必须实现序列化接口**(java.io.Serializable)**
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class Test1ObjectOutputStream {
public static void main(Stirng[] args) {
try (
// 2. 创建一个对象字节输出流包装原始的字节 输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io-app2/src/itheima11out.txt"));
) {
// 1.创建一个 Java 对象
User u = new User("admin", "张三", 32, "666888xyz");
// 3.序列化对象到文件中
oos.writeObject(u);
System.out.println("序列化对象成功!!");
} catch(Exception e) {
e.printStackTrace();
}
}
}
ObjectlnputStream(对象字节输入流)
可以把 Java 对象进行反序列化:把存储在文件中的 Java 对象读入到内存中来。
public class Test20bjectInputStream {
public static void main(String[] args) {
try (
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io-app/src/itheima11out.txt"));
) {
User u = (User) ois.readObject();
System.out.println(u);
}catch (Exception e) {
e.printStackTrace();
}
}
}
transient 这个成员变量将不参与序列化
补充知识::IO 框架
什么是框架?
- 解决某类问题,编写的一套类、接口等,可以理解成一个半成品,大多框架都是第三方研发的。
- 好处:在框架的基础上开发,可以得到优秀的软件架构,并能提高开发效率。
- 框架的形式:一般是把类、接口等编译成class形式,再压缩成一个.jar结尾的文件发行出去。
什么是 IO 框架
- 封装了 Java 提供的对文件、数据进行操作的代码,对外提供了更简单的方式来对文件进行操作,对数据进行读写等。
Commons-io
Commons-io 是 apache开源基金组织 提供的一组有关 lO操作 的小框架,目的是 提高lO流 的开发效率。
建议用 Maven, 导入依赖就是爽啊.
public class CommonsTOTest1 {
public static void main(String[] args) throws Exception {
// FileUtils.copyFile(new File("io-app2\\src\\itheima01.txt"), new File("io-app2/src/a.txt"));
// FileUtils.copyDirectory(new File("D:\\resource\\私人珍藏"), new File("D:\\resource\\私人珍藏3"));
// FileUtils.deleteDirectory(new File("D:\\resource\\私人珍藏3"));
// Java提供的原生的一行代码搞定很多事情
Files.copy(Path.of("io-app2\\src\\itheima01.txt"), Path.of("io-app2\\src\\b.txt"));
System.out.println(Files.readString(Path.of("io-app2\\src\\itheima01.txt"));
}
}