目录
读写文本内容更适合用字符流,字节流适合做数据的转移,如:文件复制等
File 是 java.io. 包下的类,File类的对象,用于代表当前操作系统的文件(文件,文件夹)
注意:File类只能对文件本身进行操作,不能读写文件里面存储的数据
IO流用于读写数据的 (读写文件/网络中数据)
File:代表文本
File
1.创建File类的对象
// 1、创建一个File对象,指代某个具体的文件。
// 路径分隔符
File f1 = new File("D:/resource/ab.txt");
//File f1 = new File("D:\\resource\\ab.txt");
File f1 = new File("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()); //0
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");
System.out.println(f4.length());
2.判断文件类型,获取文件信息
// 1.创建文件对象,指代某个文件
File f1 = new File("D:/resource/ab.txt");
//File f1 = new File("D:/resource/");// 判断对应的文件路径是否存在,存在返回true.
System.out.println(f1.exists());// 判断当前文件对象指代的是否是文件,是文件返回true,反之。
System.out.println(f1.isFile());// 判断当前文件对象指代的是否是文件夹,是文件夹返回true,反之。
System.out.println(f1.isDirectory());// 获取文件的名称(包含后缀)
System.out.println(f1.getName());
//获取父路径
System.out.println(vodio.getparent());// 获取文件的大小,返回字节个数
System.out.println(f1.length());// 获取文件的最后修改时间。
long time = f1.lastModified();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
System.out.println(sdf.format(time));// 获取创建文件对象时,使用的路径
File f2 = new File("D:\\resource\\ab.txt");
File f3 = new File("file-io-app\\src\\itheima.txt"); //相对路径
System.out.println(f2.getPath()); //D:\resource\ab.txt
System.out.println(f3.getPath()); //file-io-app\src\itheima.txt// 获取绝对路径
System.out.println(f2.getAbsolutePath()); //D:\resource\ab.txt
System.out.println(f3.getAbsolutePath())
3.创建文件,删除文件
// 创建一个新文件(文件内容为空),创建成功返回true,反之。
File f1 = new File("D:/resource/itheima2.txt");
System.out.println(f1.createNewFile()); //alt+回车// 用于创建文件夹,注意:只能创建一级文件夹
File f2 = new File("D:/resource/aaa");
System.out.println(f2.mkdir());// 用于创建文件夹,注意:可以创建多级文件夹
File f3 = new File("D:/resource/bbb/ccc/ddd/eee/fff/ggg");
System.out.println(f3.mkdirs());// 删除文件,或者空文件,注意:不能删除非空文件夹。,删除文件不会进入回收站
System.out.println(f1.delete());
System.out.println(f2.delete());
File f4 = new File("D:/resource");
System.out.println(f4.delete());
4.遍历文件夹(一级文件名称,对象)
// 获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。
File f1 = new File("D:\\course\\待研发内容");
String[] names = f1.list();
for (String name : names) {
System.out.println(name);
}
// (重点)获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点)
File[] files = f1.listFiles();
for (File file : files) {
System.out.println(file.getAbsolutePath()); //绝对路径
}
案例:改变某个文件夹下视频的序号,要求从19开始
前置知识:方法递归
递归是一种算法
直接递归:方法自己调用自己
间接递归:方法调用其他方法,其他方法又回调方法自己
注意:递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误。
public static void main(String[] args) {
test1();
}// 直接方法递归
public static void test1(){
System.out.println("----test1---");
test1(); // 直接方法递归
}// 间接方法递归
public static void test2(){
System.out.println("---test2---");
test3();
}public static void test3(){
test2(); // 间接递归
}
递归的应用、执行流程、算法思想
public class RecursionTest2 {
public static void main(String[] args) {
System.out.println("5的阶乘是:" + f(5));
}public static int f(int n){
// 终结点
if(n == 1){
return 1;
}else {
return f(n - 1) * n;
}
}
}
递归算法三要素
递归的公式: f(n) = f(n-1) * n;
递归的终结点:f(1)
递归的方向必须走向终结点:
应用:文件搜索
需求:从D:盘中,搜索“QQ.exe” 这个文件,找到后直接输出其位置。
分析: 先找出D:盘下的所有一级文件对象
遍历全部一级文件对象,判断是否是文件
如果是文件,判断是否是自己想要的
如果是文件夹,需要继续进入到该文件夹,重复上述过程
public static void main(String[] args) throws Exception {
searchFile(new File("D:/") , "QQ.exe");
}/**
* 去目录下搜索某个文件
* dir 目录
* fileName 要搜索的文件名称
*/
public static void searchFile(File dir, String fileName) throws Exception {
// 1、把非法的情况都拦截住
if(dir == null || !dir.exists() || dir.isFile()){
return; // 代表无法搜索
}// 2、dir不是null,存在,一定是目录对象。
// 获取当前目录下的全部一级文件对象。
File[] files = dir.listFiles();// 3、判断当前目录下是否存在一级文件对象,以及是否可以拿到一级文件对象。
if(files != null && files.length > 0){
// 4、遍历全部一级文件对象。
for (File f : files) {
// 5、判断文件是否是文件,还是文件夹
if(f.isFile()){
// 是文件,判断这个文件名是否是我们要找的
if(f.getName().contains(fileName)){
System.out.println("找到了:" + f.getAbsolutePath()); //绝对路径
//启动
Runtime runtime = Runtime.getRuntime();
runtime.exec(f.getAbsolutePath());
}
}else {
// 是文件夹,继续重复这个过程(递归)
earchFile(f, fileName);
}
}
}
}
应用:删除非空文件夹
前置知识:字符集
标准ASCLL使用1个字节存储一个字符,首尾是0,总共可表示128个字符
GBK(汉字内码扩展规范,国标),GBK中一个中文字符编码成两个字节的形式存储
汉字的第一个字节的第一位必须是1
GBK兼容了ASCLL字符集
Unicode字符集(统一码,也叫万国码)
UTF-8字符集:英文字符、数字等只占1个字节(兼容标准ASCII编码),汉字字符占用3个字节。
ASCII字符集:只有英文、数字、符号等,占1个字节。
GBK字符集:汉字占2个字节,英文、数字占1个字节。
UTF-8字符集:汉字占3个字节,英文、数字占1个字节。
注意1:字符编码时使用的字符集,和解码时使用的字符集必须一致,否则会出现乱码
注意2:英文,数字一般不会乱码,因为很多字符集都兼容了ASCII编码。
编码,解码
// 1、编码
String data = "a我b";
byte[] bytes = data.getBytes(); // 默认是按照平台字符集(UTF-8)进行编码的。
System.out.println(Arrays.toString(bytes)); //97,-26,120,-111 98// 按照指定字符集进行编码。
byte[] bytes1 = data.getBytes("GBK");
System.out.println(Arrays.toString(bytes1));// 2、解码
String s1 = new String(bytes); // 按照平台默认编码(UTF-8)解码
System.out.println(s1);String s2 = new String(bytes1, "GBK");
System.out.println(s2);
IO流
按流的方向分为:
输入流 :负责把数据读到内存中
输出流:负责写数据出去
按流中数据的最小单位,分为
字节流{适合操作所用类型的文件}
字符流(只适合操作纯文本文件)
FileInputStream(文件字节输入流)
作用:以内存为基准把磁盘文件中的数据以字节的形式读入到内存中去
1.读取一个字节
public static void main(String[] args) throws Exception {
// 1、创建文件字节输入流管道,与源文件接通。
// 简化写法:推荐使用。InputStream is = new FileInputStream(("file-io-app\\src\\itheima01.txt"));
// 2、开始读取文件的字节数据。
// public int read():每次读取一个字节返回,如果没有数据了,返回-1.// 3、使用循环改造上述代码
int b; // 用于记住读取的字节。
while ((b = is.read()) != -1){
System.out.print((char) b);
}// 读取数据的性能很差!
// 读取汉字输出会乱码!!无法避免的!!
// 流使用完毕之后,必须关闭!释放系统资源!
is.close();
}
2.读取多个字节
public static void main(String[] args) throws Exception { //ali+回车
// 1、创建一个字节输入流对象代表字节输入流管道与源文件接通。
InputStream is = new FileInputStream("file-io-app\\src\\itheima02.txt");// 2、开始读取文件中的字节数据:每次读取多个字节。
// public int read(byte b[]) throws IOException// 每次读取多个字节到字节数组中去,返回读取的字节数量,读取完毕会返回-1.
// 3、使用循环改造。
byte[] buffer = new byte[3]; //定义了一个字节数组,每次读3个字节
int len; // 记住每次读取了多少个字节。 abc 66
while ((len = is.read(buffer)) != -1){ //3!=-1
// 注意:读取多少,倒出多少。
String rs = new String(buffer, 0 , len);
System.out.print(rs);
}
// 性能得到了明显的提升!!
// 这种方案也不能避免读取汉字输出乱码的问题!!is.close(); // 关闭流
}
}
3.一次性读取全部字节
public static void main(String[] args) throws Exception {
// 1、一次性读取完文件的全部字节到一个字节数组中去。
// 创建一个字节输入流管道与源文件接通
InputStream is = new FileInputStream("file-io-app\\src\\itheima03.txt");// 2、准备一个字节数组,大小与文件的大小正好一样大。
byte[] buffer = is.readAllBytes();
System.out.println(new String(buffer));is.close(); // 关闭流
}
读写文本内容更适合用字符流,字节流适合做数据的转移,如:文件复制等
FileOutputStream文件字节输出流
把内存中数据以字节的形式写出到文件中去
目标:掌握文件字节输出流FileOutputStream的使用。
public class FileOutputStreamTest4 {
public static void main(String[] args) throws Exception {
// 1、创建一个字节输出流管道与目标文件接通。
// 覆盖管道:覆盖之前的数据
// OutputStream os =
// new FileOutputStream("file-io-app/src/itheima04out.txt");// 追加数据的管道
OutputStream os =
new FileOutputStream("file-io-app/src/itheima04out.txt", true);// 2、开始写字节数据出去了
os.write(97); // 97就是一个字节,代表a
os.write('b'); // 'b'也是一个字节
// os.write('磊'); // [ooo] 默认只能写出去一个字节byte[] bytes = "我爱你中国abc".getBytes(); //字符串转字节数
os.write(bytes);os.write(bytes, 0, 15); //我爱你中国 指定输出
// 换行符
os.write("\r\n".getBytes());os.close(); // 关闭流
案例:文件复制(字节流)
目标:使用字节流完成对文件的复制操作。
public class CopyTest5 {
public static void main(String[] args) throws Exception {
// 需求:复制照片。
// 1、创建一个字节输入流管道与源文件接通(照片:D:/../..)
InputStream is = new FileInputStream("file-io-app\\src\\itheima03.txt");
// 2、创建一个字节输出流管道与目标文件接通。
OutputStream os = new FileOutputStream("file-io-app\\src\\itheima03copy.txt");
// 3、创建一个字节数组,负责转移字节数据。
byte[] buffer = new byte[1024]; // 1KB.
// 4、从字节输入流 中读取字节数据,写出去到字节输出流中。读多少写出去多少。
int len; // 记住每次读取了多少个字节。
while ((len = is.read(buffer)) != -1){
os.write(buffer, 0, len);
}os.close();
is.close();
System.out.println("复制完成!!");
}
}
释放资源的方式
try-catch-finally
finally代码区的特点:无进try中的程序是正常执行了,还是出现了异常,最后都一定会执行finally区,除非JVM终止,一般用于在程序执行完成后进行资源的释放操作
作用:一般用于在程序执行完成后进行资源的释放操作(专业级做法)。
try-with-resource
该资源使用完毕后,会自动调用其close()方法,完成对资源的释放!
() 中只能放置资源对象。
// 什么是资源呢?资源都是会实现AutoCloseable接口。资源都会有一个close方法,并且资源放到这里后
// 用完之后,会被自动调用其close方法完成资源的释放操作。
try (
// 1、创建一个字节输入流管道与源文件接通
InputStream is = new FileInputStream("file-io-app\\src\\itheima03.txt");
// 2、创建一个字节输出流管道与目标文件接通。
OutputStream os = new FileOutputStream("file-io-app\\src\\itheima03copy.txt");
// 注意:这里只能放置资源对象。(流对象)
// int age = 21;
// 什么是资源呢?资源都是会实现AutoCloseable接口。资源都会有一个close方法,并且资源放到这里后
// 用完之后,会被自动调用其close方法完成资源的释放操作。
){
// 3、创建一个字节数组,负责转移字节数据。
byte[] buffer = new byte[1024]; // 1KB.
// 4、从字节输入流中读取字节数据,写出去到字节输出流中。读多少写出去多少。
int len; // 记住每次读取了多少个字节。
while ((len = is.read(buffer)) != -1){
os.write(buffer, 0, len);
}
System.out.println("复制完成!!");
} catch (Exception e) {
e.printStackTrace();
}
}
文件字符输入流FileReader
作用:以内存为基准,可以把文件中的数据以字符的形式读入到内存中去。
public static void main(String[] args) {
try (
// 1、创建一个文件字符输入流管道与源文件接通
Reader fr = new FileReader("io-app2\\src\\itheima01.txt");//alt+回车——选择第二个
){
// 2、读取文本文件的内容了。
// int c; // 记住每次读取的字符编号。
// while ((c = fr.read()) != -1){
// System.out.print((char) c);
// }
// 每次读取一个字符的形式,性能肯定是比较差的。// 3、每次读取多个字符。
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();
}
}
文件字符输出流FileWriter
以内存为基准,可以把文件中的数据以字符的形式读入到内存中去。
写字符数据出去,必须刷新流,或者关闭流,写出去的数据才能生效
fw.close(); // 关闭流,关闭流包含刷新操作!
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);
){
// 写一个字符出去
fw.write('a');
fw.write(97);
//fw.write('磊'); // 写一个字符出去
fw.write("\r\n"); // 换行// 写一个字符串出去
fw.write("我爱你中国abc");
fw.write("\r\n");// 写字符串的一部分出去
fw.write("我爱你中国abc", 0, 5); //我爱你中国
fw.write("\r\n");// 写一个字符数组出去
char[] buffer = {'黑', '马', 'a', 'b', 'c'};
fw.write(buffer);
fw.write("\r\n");// 写字符数组的一部分出去
fw.write(buffer, 0, 2);
fw.write("\r\n");
} catch (Exception e) {
e.printStackTrace();
}
}
IO流-缓存流
字节缓存流
作用:提高字节流读写数据的性能
原理:字节缓冲输入流自带了 8KB 缓冲池;字节缓冲输出流也自带了 8KB 缓冲池。
try (
InputStream is = new FileInputStream("io-app2/src/itheima01.txt");
// 1、定义一个字节缓冲输入流包装原始的字节输入流
InputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream("io-app2/src/itheima01_bak.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();
}
}
字符缓存流
作用:自带 8K ( 8192 )的字符缓冲池,可以提高字符输入流读取字符数据的性能。
新增的功能:按照行读取字符
BuffererReader字符缓存输入流
try (
Reader fr = new FileReader("io-app2\\src\\itheima04.txt");
// 创建一个字符缓冲输入流包装原始的字符输入流
BufferedReader br = new BufferedReader(fr);
){
String line; // 记住每次读取的一行数据
while ((line = br.readLine()) != null){
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
BufferedWriter字符缓存输出流
作用:作用:自带 8K 的字符缓冲池,可以提高字符输出流写字符数据的性能。
掌握字符缓冲输出流的用法。
public class BufferedWriterTest3 {
public static void main(String[] args) {
try (
Writer fw = new FileWriter("io-app2/src/itheima05out.txt", true);
// 创建一个字符缓冲输出流管道包装原始的字符输出流
BufferedWriter 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(); // 低级字节流一个一个字节的赋值,慢的简直让人无法忍受,直接淘汰!
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();
}
long endTime = System.currentTimeMillis();
System.out.println("低级字节流一个一个字节复制耗时:" + (endTime - startTime) / 1000.0 + "s");
}
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*64];
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);
BufferedInputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream(DEST_FILE + "3.avi");
BufferedOutputStream bos = new BufferedOutputStream(os);
){
int b;
while ((b = bis.read()) != -1){
bos.write(b);
}
}catch (Exception e){
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("缓冲流一个一个字节复制耗时:" + (endTime - startTime) / 1000.0 + "s");
}
private static void copy04() {
long startTime = System.currentTimeMillis();
try (
InputStream is = new FileInputStream(SRC_FILE);
BufferedInputStream bis = new BufferedInputStream(is, 64 * 1024);
OutputStream os = new FileOutputStream(DEST_FILE + "4.avi");
BufferedOutputStream bos = new BufferedOutputStream(os, 64 * 1024);
){
byte[] buffer = new byte[1024 * 64]; // 32KB
int len;
while ((len = bis.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();
}
}
}
OutputStreamWriter字符输出转换流
作用:可以控制写出去的字符使用什么字符集编码。
解决思路:获取字节输出流,再按照指定的字符集编码将其转换成字符输出流,以后写出去的字符就会用该字符集编码了。
public class OutputStreamWriterTest3 {
public static void main(String[] args) {
// 指定写出去的字符编码。
try (
// 1、创建一个文件字节输出流
OutputStream os = new FileOutputStream("io-app2/src/itheima07out.txt");
// 2、把原始的字节输出流,按照指定的字符集编码转换成字符输出转换流。
Writer osw = new OutputStreamWriter(os, "GBK");
// 3、把字符输出流包装成缓冲字符输出流
BufferedWriter bw = new BufferedWriter(osw);
){
bw.write("我是中国人abc");
bw.write("我爱你中国123");} catch (Exception e) {
e.printStackTrace();
}
}
}
IO流-打印流
PrintStream 和 PrintWriter 的区别
打印数据的功能上是一模一样的:都是使用方便,性能高效(核心优势)
PrintStream 继承自字节输出流 OutputStream ,因此支持写字节数据的方法。
PrintWriter 继承自字符输出流 Writer ,因此支持写字符数据出去。
作用:打印流可以实现更方便、更高效的打印数据出去,能实现打印啥出去就是啥出去。
public class PrintTest1 {
public static void main(String[] args) {
try (
// 1、创建一个打印流管道
// PrintStream ps =
// new PrintStream("io-app2/src/itheima08.txt", Charset.forName("GBK"));
// PrintStream ps =
// new PrintStream("io-app2/src/itheima08.txt");
PrintWriter ps =
new PrintWriter(new FileOutputStream("io-app2/src/itheima08.txt", true));
){
ps.println(97);
ps.println('a');
ps.println("我爱你中国abc");
ps.println(true);
ps.println(99.5);
// ps.write(97); // 'a'
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出语句的重定向
可以把输出语句的打印位置改到某个文件中去。
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();
}
}
}
DataOutputStream(数据输出流)
作用:允许把数据和其类型一并写出去
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();
}
}
}
DataInputStream( 数据输入流 )
作用:用于读取数据输出流写出去的数据。
public class DataInputStreamTest2 {
public static void main(String[] args) {
try (
DataInputStream 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 对象读出来
ObjectOutputStream对象字节输出流
可以把 Java 对象进行序列化:把 Java 对象存入到文件中去。
注意:对象如果要参与序列化,必须实现序列化接口
( java.io.Serializable )
不想对密码进行序列化:
1.创建User类 public class User implements Serializable {
2.
public class Test1ObjectOutputStream {
public static void main(String[] 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();
}
}
}
ObjectInputStream对象字节输入流
可以把 Java 对象进行反序列化:把存储在文件中的 Java 对象读入到内存中来。
public class Test2ObjectInputStream {
public static void main(String[] args) {
try (
// 1、创建一个对象字节输入流管道,包装 低级的字节输入流与源文件接通
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io-app2/src/itheima11out.txt"));
){
User u = (User) ois.readObject();
System.out.println(u);
} catch (Exception e) {
e.printStackTrace();
}
}
如果要一次序列化多个对象:
用一个 ArrayList 集合存储多个对象,然后直接对集合进行序列化即可
注意: ArrayList 集合已经实现了序列化接口
IO框架
框架:
- 解决某类问题,编写的一套类、接口等,可以理解成一个半成品,大多框架都是第三方研发的。
- 好处:在框架的基础上开发,可以得到优秀的软件架构,并能提高开发效率
- 框架的形式:一般是把类、接口等编译成 class 形式,再压缩成一个 .jar 结尾的文件发行出去。
IO框架:封装了 Java 提供的对文件、数据进行操作的代码,对外提供了更简单的方式来对文件进行操作,对数据进行读写等。
导入 commons-io-2.11.0.jar 框架到项目中去。
① 在项目中创建一个文件夹: lib
② 将 commons-io-2.6.jar 文件复制到 lib 文件夹
③ 在 jar 文件上点右键,选择 Add as Library -> 点击 OK
④ 在类中导包使用
public class CommonsIOTest1 {
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")));
}
}