File类
文件和目录的抽象表示
静态方法
static String pathSeparator
:与系统有关的路径分隔符
static String separator
:与系统有关的默认名称分隔符
window:
\
linux:/
package alive.a_flie;
import java.io.File;
/**
* @Author zyj
* @Date 2024/09/19 10:16
* @Description
*/
public class Test {
public static void main(String[] args) {
System.out.println("File.pathSeparator = " + File.pathSeparator);
System.out.println("File.separator = " + File.separator);
//File.pathSeparator = ;
//File.separator = \
String path1 = "D:\\code\\alive";
System.out.println("path1 = " + path1);
String path2 = "D:" + File.separator + "code" + File.separator + "alive";
System.out.println("path2 = " + path2);
}
}
构造方法
File(String parent,String child)
:根据所填写的路径创建File对象,parent:父路径,child:子路径
File(File parent,String child)
:根据所填写的路径创建File对象,parent:父路径,是一个File对象,child:子路径
File(String pathname)
:根据所填写的路径创建File对象,pathname:直接指定路径
package alive.a_flie;
import java.io.File;
/**
* @Author zyj
* @Date 2024/09/19 10:16
* @Description
*/
public class Test {
public static void main(String[] args) {
File f1 = new File("D:\\code\\alive", "test.txt");
System.out.println("f1 = " + f1);
File f2 = new File(new File("D:\\code\\alive"), "test.txt");
System.out.println("f2 = " + f2);
File f3 = new File("D:\\code\\alive\\test.txt");
System.out.println("f3 = " + f3);
}
}
File的获取方法
String getAbsolutePath()
:获取File的绝对路径(带盘符路径)
String getPath()
:获取的是封装路径,new File对象时写的路径
String getName
:获取的是文件或者文件夹名称
long length()
:获取的是文件的长度(文件字节数)
package alive.a_flie;
import java.io.File;
/**
* @Author zyj
* @Date 2024/09/19 10:16
* @Description
*/
public class Test {
public static void main(String[] args) {
File file = new File("D:\\code\\alive\\test.txt");
System.out.println("file.getAbsolutePath() = " + file.getAbsolutePath());
File f1 = new File("test.txt");
System.out.println("f1.getAbsolutePath() = " + f1.getAbsolutePath());
System.out.println("file.getPath() = " + file.getPath());
System.out.println("file.getName() = " + file.getName());
System.out.println("file.length() = " + file.length());
//file.getAbsolutePath() = D:\code\alive\test.txt
//f1.getAbsolutePath() = D:\code\alive\javaSE\test.txt
//file.getPath() = D:\code\alive\test.txt
//file.getName() = test.txt
//file.length() = 0
}
}
File方法
boolean crateNewFile()
:创建文件;
① 如果创建的文件已经存在,则创建失败,返回false
② 如果创建的文件之前没有,则创建失败,返回true
boolean mkdirs()
:创建文件夹,既可以多级文件夹又可以创建单级文件夹
① 如果创建的文件夹已经存在,则创建失败,返回false
② 如果创建的文件夹之前没有,则创建失败,返回true
boolean delete()
:删除文件或者文件夹
注意:
① 如果删除文件,不在回收站
② 如果删除文件夹,必须是空的文件夹
boolean isDirectiry()
:判断是否是文件夹
boolean isFile()
:判断是否是文件
boolean exists()
:判断文件或文件夹是否存在
String[] list()
:遍历指定的文件夹,返回的是String数组
File[] listFiles()
:遍历指定的文件夹,返回的是File数组
注意点:
listFiles方法底层还是list方法
package alive.a_flie;
import java.io.File;
import java.io.IOException;
/**
* @Author zyj
* @Date 2024/09/19 10:16
* @Description
*/
public class Test {
public static void main(String[] args) throws IOException {
File f1 = new File("D:\\code\\alive\\2.text");
System.out.println("file = " + f1);
boolean newFile = f1.createNewFile();
System.out.println("newFile = " + newFile);
File f2 = new File("D:\\code\\alive\\2");
boolean mkdir = f2.mkdir();
System.out.println("mkdir = " + mkdir);
System.out.println("f2.isDirectory() = " + f2.isDirectory());
System.out.println("f1.isFile() = " + f1.isFile());
boolean d1 = f1.delete();
System.out.println("del = " + d1);
boolean d2 = f2.delete();
System.out.println("d1 = " + d1);
System.out.println("d2 = " + d2);
System.out.println("f1.exists() = " + f1.exists());
//file = D:\code\alive\2.text
//newFile = true
//mkdir = true
//f2.isDirectory() = true
//f1.isFile() = true
//del = true
//d1 = true
//d2 = true
//f1.exists() = false
File f3 = new File("D:\\code\\alive");
String[] list = f3.list();
for (String s : list) {
System.out.println("s = " + s);
}
File[] files = f3.listFiles();
for (File file : files) {
System.out.println("file = " + file);
}
//s = alive-service
//s = javaSE
//s = owner_webapp
//s = test.txt
//s = 需求文档.md
//file = D:\code\alive\alive-service
//file = D:\code\alive\javaSE
//file = D:\code\alive\owner_webapp
//file = D:\code\alive\test.txt
//file = D:\code\alive\需求文档.md
}
}
练习
查询目录下的所有文件
package alive.b_flie;
import java.io.File;
/**
* @Author zyj
* @Date 2024/09/19 16:12
* @Description
*/
public class Test {
public static void main(String[] args) {
showAllFiles(new File("D:\\code\\alive"));
}
private static void showAllFiles(File file) {
for (File f : file.listFiles()) {
if (f.isFile()) {
System.out.println(f.getName());
} else {
showAllFiles(f);
}
}
}
}
相对路径和绝对路径
① 绝对路径:从盘符开始写的路径;
D:\code\alive
② 相对路径:不从盘符名开始写的路径
哪个路径是参照路径,哪个路径就可以省略不写,剩下的就是在idea中的相对路径写法
在idea中参照路径就是当前project的绝对路径
绝对路径:D:\code\alive\javaSE\file\test.txt
相对路径:file\test.txt
在idea中写相对路径,其实就是从模块名中写
如果直接写文件名默认是在工程更目录下
IO流
什么是IO流
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象
流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便直观的进行数据操作
IO流分类
- 按照流的流向分类
输入流
InputStream
:表示将数据读取到Java程序(内存)中使用的流;
输出流OutputSteam
:表示从Java程序(内存)向外传输使用的流;
- 按照流的数据单位分
字节流
:万能流,一切皆字节,一次性传输一个字节数据,将数据以字节的形式传输;
字符流
:操作文本文档,一次性传输一个字符数据,将数据以字符的形式传输;
- 按照流的层次分
节点流
:可以从或向一个特点的节点读写数据
处理流
:是对一个已存在的流连接和封装,通过所封装的流的功能调用实现数据读写
字节输出流(OutputSteam)
① 字节输出流OutputStream是一个
抽象类
子类:FileOutputStream
② 构造:
FileOutputStream(File file)
FileOutputStream(String name)
③ 特点:
指定的文件没有,则会自动创建;
每执行一次,默认都会创建一个新的文件,覆盖旧的文件
方法:
void write(int b)
:一次写一个字节
void write(byte[] b)
:一次写一个字节数组
void write(byte[] b,int off,int len)
:一次写一个字节数组的一部分,b
:写的数组,off
:从数组的哪个索引开始写len
:写多少个
void close()
:关闭资源
package alive.c_io;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @Author zyj
* @Date 2024/09/19 16:57
* @Description
*/
public class Test {
public static void main(String[] args) throws IOException {
FileOutputStream outputStream = new FileOutputStream("file/test.txt");
outputStream.write(98);
byte[] bytes = {97, 98, 99, 100, 101, 102, 103};
outputStream.write(bytes);
outputStream.write(bytes, 0, 2);
byte[] strBytes = "张云进".getBytes();
FileOutputStream outputStream2 = new FileOutputStream("file\\test1.txt");
outputStream2.write(strBytes);
outputStream.close();
}
}
FileOutputStream(String name,boolean append)
:会实现内容追加,不会覆盖原始内容;
①\r\n
(window):换行占两个字节
②\n
(linux)
③\r
(macOS)
字节输入流(InputStream)
InputStream,是一个抽象类
子类:FileInputStream
读数据,将数据读到内存中
FileInputStream(File file)
FileInputStream(String name)
方法:
int read()
:一次读一个字节,返回的是读取的字节
int read(byte[] b)
:一次读取一个字节数组,返回的是读取的字节个数
int read(byte[] b,int off,int len)
:一次读取一个字节数组的一部分
void close()
:关闭资源
package alive.d_io;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @Author zyj
* @Date 2024/09/19 18:06
* @Description
*/
public class Test {
public static void main(String[] args) throws IOException {
FileInputStream inputStream = new FileInputStream("file\\test1.txt");
// int r1 = inputStream.read();
// System.out.println("r1 = " + r1);
// int r2 = inputStream.read();
// System.out.println("r2 = " + r2);
// int r3 = inputStream.read();
// System.out.println("r3 = " + r3);
// int r4 = inputStream.read();
// System.out.println("r4 = " + r4);
// int r5 = inputStream.read();
// System.out.println("r4 = " + r5);
// r1 = 98
// r2 = 97
// r3 = 98
// r4 = 99
// r4 = -1
int len;
while ((len = inputStream.read()) != -1) {
System.out.println("==>" + (char) len);
}
inputStream.close();
}
}
每个文件末尾都一个结束标记,
read
读到结束标记则返回-1
package alive.d_io;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @Author zyj
* @Date 2024/09/19 18:06
* @Description
*/
public class Test {
public static void main(String[] args) throws IOException {
FileInputStream inputStream = new FileInputStream("file\\test1.txt");
byte[] bytes = new byte[2];
int length;
while ((length = inputStream.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, length));
}
inputStream.close();
//aa
//ab
//bb
//cc
//c
}
}
① 创建的数组相当于一个临时存储区域,我们要读取的内容会临时保存到数组中,然后再从数组中获取
② 数组的长度定多少,每次就能读取多少,一般情况下数组长度定为1024或者1024的倍数,如果剩余未读字节数不够数组长度,那么能读取多少就读多少
练习1
package alive.e_io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @Author zyj
* @Date 2024/09/20 10:45
* @Description
*/
public class Test {
public static void main(String[] args) throws IOException {
FileInputStream is = new FileInputStream("file\\dog.png");
FileOutputStream os = new FileOutputStream("file\\copyDog.png");
int read;
while ((read = is.read()) != -1) {
System.out.println(read);
os.write(read);
}
os.close();
is.close();
}
}
字符输入流 FileReader
字符流用来操作文本文档,
Reader
是一个抽象类
子类:FileReader
UTF-8:一个中文占三个字节
GBK:一个中文占两个字节
复制使用字节流不使用字符流
作用:
将文本文档中的内容读取到内存中的类
FileReader(File file)
FileReader(String path)
方法:
int read()
:一次读取一个字符,返回的是字符对应的int值
int read(char[] cbuf)
:一次读取一个字符数组,返回读取个数
int read(char[] cbuf,int off, int len)
:一次读取一个字符数组的一部分,返回的是读取个数
void close()
:关闭资源
package alive.f_fliereader;
import java.io.FileReader;
/**
* @Author zyj
* @Date 2024/09/20 15:41
* @Description
*/
public class Test {
public static void main(String[] args) throws Exception {
FileReader fr = new FileReader("file\\test.txt");
// int read = fr.read();
// System.out.println("read = " + read);
// System.out.println("(char)read = " + (char) read);
//read = 20808
//(char)read = 先
// int res;
// while ((res = fr.read()) != -1) {
// System.out.print((char) res);
// }
char[] ch = new char[1024];
int res;
while ((res = fr.read(ch)) != -1) {
System.out.println(new String(ch, 0, res));
}
fr.close();
}
}
字符输出流 FileWriter
① 字符输出流
writer
抽象类
子类:FileWriter
② 将数据写到文件中
③ 构造:
FileWriter(File file)
FileWriter(String fileName)
FileWriter(String filename,blooean append)
④ 方法:
void write (int c)
:一次写入一个字符
void write (char[] cbuf)
:一次写入一个字符数组
void write (char[] cbuf,int off,int len)
:一次写入数组的一部分
void write (String str)
:写入字符串
void flush
:将缓冲区中的数据刷到文件中
void close()
:关闭流
注意点:
FileWriter底层自带一个缓冲区,我们写的数据会先保存到缓冲区中,所以我们先将缓冲区中的数据写到文件中
IO流异常处理
package alive.h_exception;
import java.io.FileWriter;
import java.io.IOException;
/**
* @Author zyj
* @Date 2024/09/20 16:31
* @Description
*/
public class Test {
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("file\\test2.txt");
fw.write("hello");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
}
}
JDK7 后的写法
package alive.h_exception;
import java.io.FileReader;
import java.io.FileWriter;
/**
* @Author zyj
* @Date 2024/09/20 16:31
* @Description
*/
public class Test {
public static void main(String[] args) {
try (FileReader fr = new FileReader("file\\test.txt"); FileWriter fw = new FileWriter("file\\text1.txt")) {
System.out.println((char) fr.read());
} catch (Exception e) {
}
}
}
使用上面的结构会自动关闭流,无需手动关闭
字节缓冲流
为什么使用字节缓冲流?
FileOutputStream、FileInputStream、FileReader、FileWriter都叫基本类;其中FileInputStream和FileOutputStream的读写方法都是本地方法(native),本地方法是和系统硬盘通信的,两个读写都是硬盘之间进行读写的,效率比较不高;而缓冲流中底层带有一个长度为8192
的数组(缓冲区),此时读和写都是在内存(缓冲区)中进行的,读写效率比较高;
使用之前需要将基本流包装成缓冲流,new 对象时,传递基本流
字节缓冲流
①BufferedOutputStream
:字节缓冲输出流
构造方法:BufferedOutputStream(OutputStream out)
使用:和FileStream一致
②BufferedInputStream
:字节缓冲输入流
构造方法:BufferedInputStream(InputStream in)
使用:和FileInputStream一致
package alive.i_buffered;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* @Author zyj
* @Date 2024/09/20 17:13
* @Description
*/
public class T1 {
public static void main(String[] args) {
baseStream();
bufferedStream();
}
public static void baseStream() {
long start = System.currentTimeMillis();
try (FileInputStream fis = new FileInputStream("file\\demo.mp4"); FileOutputStream fos = new FileOutputStream("file\\demo_c.mp4")) {
int res;
while ((res = fis.read()) != -1) {
fos.write(res);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
long end = System.currentTimeMillis();
System.out.println("字节流使用时间==》" + (end - start));
//字节流使用时间==》47219
}
}
public static void bufferedStream() {
long start = System.currentTimeMillis();
try (FileInputStream fis = new FileInputStream("file\\demo.mp4");
FileOutputStream fos = new FileOutputStream("file\\demo_b_c.mp4");
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos)) {
int res;
while ((res = bis.read()) != -1) {
bos.write(res);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
long end = System.currentTimeMillis();
System.out.println("字节流使用时间==》" + (end - start));
//字节流使用时间==》480
}
}
}
关闭原理
在使用缓冲流的时候,为什么只需要关闭缓冲流而不用关闭基本流?
缓冲流的close底层会自动关闭
读写原理
缓冲流底层有数组(缓冲区),都是在内存之间进行读写,那么缓冲流读写的过程是什么样的?
① 先依靠基本流将数据读出来,交给缓冲流,由于缓冲流缓冲区8192,所以每次读取8192个字节放到缓冲区中
② 等待输出流缓冲区填满,再依靠基本流写入硬盘
③ 如果输入流缓冲区中的数据读不到了,重新从硬盘上读8192个字节,进入到输入流缓冲区中,继续利用len在两个缓冲区之间来回传递值
字符缓冲流
字符流的基本流底层是有缓冲区的,所以效率不是特别明显
字符缓冲输出流(BufferedWriter)
构造
BufferedWriter(Writer w)
newLine()
:换行
package alive.i_buffered;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
/**
* @Author zyj
* @Date 2024/09/20 17:53
* @Description
*/
public class T2 {
public static void main(String[] args) throws IOException {
BufferedWriter bfw = new BufferedWriter(new FileWriter("file\\text1.txt", true));
bfw.write("静止了所有的花开");
bfw.newLine();
bfw.write("遥远了清晰了爱");
bfw.newLine();
bfw.write("天郁闷爱却很喜欢");
bfw.newLine();
bfw.write("那时候我不懂着叫爱");
bfw.close();
}
}
字符缓冲输入流(BufferedReader)
构造
BufferedReader(Reader r)
String readLine()
:一次读一行,如果读到结束表姐,返回null
package alive.i_buffered;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/**
* @Author zyj
* @Date 2024/09/21 14:05
* @Description
*/
public class T3 {
public static void main(String[] args) throws IOException {
BufferedReader bfr = new BufferedReader(new FileReader("file\\text1.txt"));
String str = null;
while ((str = bfr.readLine()) != null) {
System.out.println("str = " + str);
}
bfr.close();
}
}
字符编码
计算机中存储的信息都是二进制数表示的,我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制转换之后的结果。【按照某种规则,将字符存储到计算机中,称为编码】。反之,将存储在计算机中的二进制按照某种规则解析显示出来,称为解码。比如,按照A规则存储,同样按照A规则解析,那么就能显示正确的文本符号,反之,按照A规则存储,再按照B规则解析,就会出现乱码现象。
- 字符编码Character Encoding:是一套自然语言的字符与二进制数之间的对应规则
字符集
字符集Charset:编码表,是一个系统支持的所有字符的集合,包括各国家文字,标点符号,图形符号、数字等。
计算机要准确的存储和识别各种字符集编号,需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASII字符集、GBK字符集、Unicode字符集等。
-
ACII字符集
- ACII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格键、换行键)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)。
- 基本的ASCII字符集,使用7位(bits)表示一个字符,共128字符,ASCII的扩展字符集使用8位(bits)表示一个字符,共256字符,方便支持欧洲常用字符。
-
ISO-8859-1字符集
- 拉丁码表,别名Latin-1,用于显示欧洲使用的语言,包括荷兰、丹麦、德语、意大利语、西班牙语等。
- ISO-8859-1使用单字节编码,兼容ASII编码
-
GBxxx字符集
- GB国标的意思,是为了显示中文而的设计一套字符集
- GB2312:简体中文码表,一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合成包含7000多个简体汉字,此外数字符号、罗马希腊的字母、日文的假名都编进去了,连在ASCII里面本来就有的数字、标点、字母都统统重新编写了两个字节的编码,这就是常说的“全角”字符,而原来在127号以下的那些就叫“半角”字符了
- GBK:是常用的中文码表,是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等
- GB18030:最新的中文码表,收录了70244个,采用多字节编码,每个字可以由1个、2个或者4个字节组成。支持中国国内少数民族的文字,同时支持繁体字以及日韩汉字等。
-
Unicode字符集:
- Unicode编码系统为表达任意语言的任意字符而设计的,是业界的一种标准,也称为统一码、标准万国码。
- 它最多使用4字节的数字来表达每个字母、符号、或者文字。有三种编码方案,UTF-8、UTF-16和UTF-32。最为常用的UTF-8编码。
- UTF-8编码,可以用来表示Unicode标准任何字符,它是电子邮件、网页以及其他存储或者传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求用一至四个字节为每个字符编码,编码规则:
- 128个US-ASCII字符,只需一个字节编码
- 拉丁文等字符,需要两个字节编码
- 大部分常用字(含中文),需要三个字节编码
- 其他极少数使用的Unicode辅助字符,使用四个字节编码
转换流
编码规则不一致时,会出现中文乱码
InputStreamReader
字节流通向字符流的桥梁
读数据
InputStreamReader(InputStream in,String charsetName)
charsetName:指定编码,不区分大小写
package alive.j_reversestream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
/**
* @Author zyj
* @Date 2024/09/21 15:52
* @Description
*/
public class T1 {
public static void main(String[] args) throws Exception {
InputStreamReader isr = new InputStreamReader(new FileInputStream("file\\text1.txt"), "gbk");
System.out.println((char) isr.read());
isr.close();
}
}
OutputStreamWriter
字符流通向字节流的桥梁
OutputStreamWriter(OutputStream out,String charsetName)
按照指定的编码规则存数据
package alive.j_reversestream;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
/**
* @Author zyj
* @Date 2024/09/21 23:10
* @Description
*/
public class T2 {
public static void main(String[] args) throws Exception {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("file\\text2.txt"), "gbk");
osw.write("韩");
osw.close();
}
}
序列化流
序列化和反序列化
读写对象
ObjectOutputStream
:序列化,写对象
ObjectInputStream
:反序列化,读对象
序列化流ObjectOutputStream
写对象
ObjectOutputStream(OutputStream out)
writeObject(Object obj)
:写对象
将对象写入文件中,别序列化的对象需要实现Serializable
接口
package alive.k_serializable;
import java.io.Serializable;
/**
* @Author zyj
* @Date 2024/09/22 19:50
* @Description
*/
public class Person implements Serializable {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package alive.k_serializable;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
/**
* @Author zyj
* @Date 2024/09/22 19:50
* @Description
*/
public class T1 {
public static void main(String[] args) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file\\p1.txt"));
oos.writeObject(new Person("tom", 11));
oos.close();
}
}
反序列化ObjectInputStream
读对象
ObjectInputStream(InputStream in)
Object readObject()
package alive.k_serializable;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
/**
* @Author zyj
* @Date 2024/09/22 19:50
* @Description
*/
public class T1 {
public static void main(String[] args) throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("file\\p1.txt"));
Person p = (Person) ois.readObject();
System.out.println("p = " + p);
ois.close();
}
}
transient
使用关键字
transient
修饰属性,此属性不能被序列化
private transient int age;
反序列化异常处理
- 序列化之后,修改源码后没有序列化而直接反序列化,会出现序列号冲突问题
将序列化固化,序列化不变
在对象加入``public static final long 的变量,并为其赋值
public static final long serialVersionUID = 42L;
将一个对象实现序列化接口,才能让这个对象以二进制的形式在网络中传输
- 遍历读取和存储多个对象
package alive.k_serializable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
/**
* @Author zyj
* @Date 2024/09/22 19:50
* @Description
*/
public class T1 {
public static void main(String[] args) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file\\p1.txt"));
ArrayList<Person> list = new ArrayList<>();
list.add(new Person("Jack", 19));
list.add(new Person("Tom", 10));
list.add(new Person("Alex", 23));
oos.writeObject(list);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("file\\p1.txt"));
ArrayList<Person> persons = (ArrayList<Person>) ois.readObject();
System.out.println("persons = " + persons);
oos.close();
ois.close();
}
}
打印流PrintStream
new PrintStream(String fileName)
println(String str)
:打印输出,换行
print(String str)
:打印输出,不换行
package alive.l_printstream;
import java.io.FileNotFoundException;
import java.io.PrintStream;
/**
* @Author zyj
* @Date 2024/09/23 15:05
* @Description
*/
public class T1 {
public static void main(String[] args) throws FileNotFoundException {
PrintStream ps = new PrintStream("file\\print.txt");
ps.println("hello word");
ps.print("hello word");
ps.print("hello word");
ps.close();
}
}
改变流向
System.out.println()
:本身输出到控制台
改变流向:可以让输出语句从控制台上输出改变成往指定文件中输出
static void setOut(PrintStream out)
:改变流向,让输出语句从控制台输出转移至指定文件中
package alive.l_printstream;
import java.io.FileNotFoundException;
import java.io.PrintStream;
/**
* @Author zyj
* @Date 2024/09/24 10:54
* @Description
*/
public class T2 {
public static void main(String[] args) throws FileNotFoundException {
PrintStream ps = new PrintStream("file\\log.txt");
System.setOut(ps);
System.out.println("2024年9月24日10:56:32");
System.out.println("hello word");
ps.close();
}
}
使用场景:
可以将输出的内容以及详细信息放到日志文件中,永久保存
打印流续写
package alive.l_printstream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
/**
* @Author zyj
* @Date 2024/09/24 11:04
* @Description
*/
public class T3 {
public static void main(String[] args) throws FileNotFoundException {
PrintStream ps = new PrintStream(new FileOutputStream("file\\log.txt", true));
System.setOut(ps);
System.out.println("追加的内容A");
System.out.println("追加的内容B");
System.out.println("追加的内容C");
System.out.println("追加的内容D");
System.out.println("追加的内容E");
ps.close();
}
}
Properties集合
使用场景在配置文件中使用
package alive.m_properties;
import java.io.FileInputStream;
import java.util.Properties;
import java.util.Set;
/**
* @Author zyj
* @Date 2024/09/24 11:11
* @Description
*/
public class T1 {
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
FileInputStream fis = new FileInputStream("file\\jdbc.properties");
properties.load(fis);
Set<String> set = properties.stringPropertyNames();
for (String key : set) {
System.out.println(key + "->" + properties.getProperty(key));
}
}
}
Commons-io工具包
IO 技术开发中,代码量很大, 而且代码的重复率很高,如果我们要遍历目录,拷贝目录就需要使用方法递归调用,也增大了程序的复杂度。
Apache软件基金会,开发了IO技术的工具类commonIO,大大简化了IO开发
https://commons.apache.org/io/download_io.cgi
导入Jar包
工具包的使用
IOUtils类
- 静态方法:
IOUtils.copy(InputStream in,OutputStream out)
传递字节流,实现文件复制- 静态方法:
IOUtils.closeQuietly(任意流对象)
自动释放资源,自动处理close()方法抛出的异常
package alive.n_utils;
import org.apache.commons.io.IOUtils;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @Author zyj
* @Date 2024/09/24 11:50
* @Description
*/
public class T1 {
public static void main(String[] args) throws IOException {
IOUtils.copy(new FileInputStream("file\\demo.mp4"), new FileOutputStream("file\\demo_dd.mp4"));
}
}
package alive.n_utils;
import org.apache.commons.io.IOUtils;
import java.io.FileWriter;
/**
* @Author zyj
* @Date 2024/09/24 13:44
* @Description
*/
public class T2 {
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("file\\text1.txt");
fw.write("hello");
}catch (Exception e){
e.printStackTrace();
}finally {
if(fw != null){
IOUtils.closeQuietly(fw);
}
}
}
}
FileUtils类
- 静态方法
FileUtils.copyDirectoryToDirectory(File src,File dest)
传递File类型的目录,进行整个目录的复制,自动进行递归遍历。
参数:src - 要复制的文件夹目录
dest:将文件复制到目标
writeStringToFile(File file,String str)
:写字符串到文本文件中。
String readFileToString(File file)
:读取文本文件,返回字符串
package alive.n_utils;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
/**
* @Author zyj
* @Date 2024/09/24 13:53
* @Description
*/
public class T3 {
public static void main(String[] args) throws IOException {
FileUtils.copyDirectoryToDirectory(new File("file\\test"), new File("file\\test_copy"));
String str = FileUtils.readFileToString(new File("file\\test.txt"));
System.out.println("str = " + str);
}
}