第一部分 file类
1)File类
计算机常识:
1.名字为".jpg"的一定是图片吗?
不一定,有可能是文件夹
2.什么叫做文本文档:
用记事本打开,人能看懂的文件
比如:.txt .html .css等
.doc -> 不是
3.E:\Idea\io\1.jpg -> 1.jpg的父路径是谁?
E:\Idea\io
4.路径分隔符:(指的是一个路径和其他路径之间的分隔符)
;路径名称分隔符(指的是一个路径之间的分隔符 \)
\
1.File类概述:
文件和目录路径名的抽象表示形式 -> 指的就是文件或者文件夹的对象
2.解释:
我们创建File对象的时候指定文件或者文件夹的路径,指定谁的路径,File就代表谁的对象
然后我们就可以利用File对象中的方法操作指定的文件或者文件夹
比如: File file = new File("E:\Idea\io\1.jpg")
到时候调用File的方法就是在操作指定的1.jpg
2)File类的静态成员
static String pathSeparator :与系统有关的路径分隔符,为了方便,它被表示为一个字符串
static String separator:与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串
public class Demo01File {
public static void main(String[] args) {
//static String pathSeparator :与系统有关的路径分隔符,为了方便,它被表示为一个字符串
System.out.println(File.pathSeparator); // ;
//static String separator:与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串
System.out.println(File.separator);// \
}
}
【如何用Java正确编写一个路径?】
public class Demo01File {
public static void main(String[] args) {
method02();
}
private static void method02() {
/*
如果直接写\,就写的太死了
因为:
win: \
linux: /
java代码要求:一次编写,到处运行
*/
//String path = "E:\\Idea\\io";
String path = "E:"+File.separator+"Idea"+File.separator+"io";
System.out.println(path);
}
}
3)File的构造方法
File(String parent, String child) 根据所填写的路径创建File对象
parent:父路径
child:子路径
File(File parent, String child) 根据所填写的路径创建File对象
parent:父路径,是一个File对象
child:子路径
File(String pathname) 根据所填写的路径创建File对象
pathname:直接指定路径
public class Demo02File {
public static void main(String[] args) {
/*File(String parent, String child) 根据所填写的路径创建File对象
parent:父路径
child:子路径*/
File file1 = new File("E:\\Idea\\io", "1.jpg");
System.out.println(file1);
/*File(File parent, String child) 根据所填写的路径创建File对象
parent:父路径,是一个File对象
child:子路径*/
File parent = new File("E:\\Idea\\io");
File file2 = new File(parent, "1.jpg");
System.out.println(file2);
/*File(String pathname) 根据所填写的路径创建File对象
pathname:直接指定路径*/
File file3 = new File("E:\\Idea\\io\\1.jpg");
System.out.println(file3);
}
}
注意:
1.创建File对象,路径可以放不存在的路径,但是直接指定的时候没有意义
但是,
如果我们指定一个不存在的文件夹或者文件,我们可以先做判断,然后利用File中的方法去创建
4)File的获取方法
String getAbsolutePath() -> 获取File的绝对路径->带盘符的路径
String getPath() ->获取的是封装路径->new File对象的时候写的啥路径,获取的就是啥路径
String getName() -> 获取的是文件或者文件夹名称
long length() -> 获取的是文件的长度 -> 文件的字节数
public class Demo03File {
public static void main(String[] args) {
File file = new File("E:\\Idea\\io\\1.txt");
//String getAbsolutePath() -> 获取File的绝对路径->带盘符的路径
System.out.println("file.getAbsolutePath() = " + file.getAbsolutePath());
//String getPath() ->获取的是封装路径->new File对象的时候写的啥路径,获取的就是啥路径
System.out.println("file.getPath() = " + file.getPath());
//String getName() -> 获取的是文件或者文件夹名称
System.out.println("file.getName() = " + file.getName());
//long length() -> 获取的是文件的长度 -> 文件的字节数
System.out.println("file.length() = " + file.length());
}
}
5)相对路径和绝对路径
1.绝对路径:
带盘符的路径
跨盘符访问可以使用绝对路径
2.相对路径:
不带盘符的路径
在同一个盘符下写的路径
3.我们现在重心在idea中怎么写相对路径:
a.要找一个参照路径:当前project的绝对路径
b.哪个路径为参照路径,就可以省略哪个路径,剩下的就是我们要写的相对路径
比如:在模块(day19_IO)下创建一个1.txt -> 1.txt的相对路径咋写
a.先写出1.txt的绝对路径:E:\Idea\idea2022\workspace\CD_230417Java\day19_IO\1.txt
b.再找出参照路径:E:\Idea\idea2022\workspace\CD_230417Java
c.哪个路径为参照路径,哪个路径就可以省略,剩下的就是相对路径: day19_IO\1.txt
4.注意:
a.在IO部分相对路径:从模块名开始写
b.如果直接写文件或者文件夹名,不带模块名,此时所在位置,在project下
6)File的创建方法
boolean createNewFile() -> 创建文件
如果要创建的文件之前有,创建失败,返回false
如果要创建的文件之前没有,创建成功,返回true
boolean mkdirs() -> 创建文件夹(目录)既可以创建多级文件夹,还可以创建单级文件夹
如果要创建的文件夹之前有,创建失败,返回false
如果要创建的文件夹之前没有,创建成功,返回true
public class Demo04File {
public static void main(String[] args) throws Exception{
File file1 = new File("day19_IO\\1.txt");
/*boolean createNewFile() -> 创建文件
如果要创建的文件之前有,创建失败,返回false
如果要创建的文件之前没有,创建成功,返回true*/
System.out.println(file1.createNewFile());
/*boolean mkdirs() -> 创建文件夹(目录)既可以创建多级文件夹,还可以创建单级文件夹
如果要创建的文件夹之前有,创建失败,返回false
如果要创建的文件夹之前没有,创建成功,返回true*/
File file2 = new File("E:\\Idea\\io\\haha\\hehe\\heihei\\xixi\\hiahia");
System.out.println(file2.mkdirs());
}
}
7)File类的删除方法
boolean delete()->删除文件或者文件夹
注意:
1.如果删除文件,不走回收站
2.如果删除文件夹,必须是空文件夹,而且也不走回收站
public class Demo05File {
public static void main(String[] args) throws Exception{
File file1 = new File("E:\\Idea\\io\\1.txt");
System.out.println("file1.delete() = " + file1.delete());
System.out.println("===============================");
File file2 = new File("E:\\Idea\\io\\haha");
System.out.println("file2.delete() = " + file2.delete());
}
}
8)File类的判断方法
boolean isDirectory() -> 判断是否为文件夹
boolean isFile() -> 判断是否为文件
boolean exists() -> 判断文件或者文件夹是否存在
public class Demo06File {
public static void main(String[] args) {
File file = new File("E:\\Idea\\io\\1.jpg");
//boolean isDirectory() -> 判断是否为文件夹
System.out.println("file.isDirectory() = " + file.isDirectory());
//boolean isFile() -> 判断是否为文件
System.out.println("file.isFile() = " + file.isFile());
//boolean exists() -> 判断文件或者文件夹是否存在
System.out.println("file.exists() = " + file.exists());
}
}
9)File的遍历方法
String[] list() -> 遍历指定的文件夹,返回的是String数组
File[] listFiles()-> 遍历指定的文件夹,返回的是File数组
listFiles底层依靠list(),先调用list,返回String[],遍历String数组,根据遍历出来的文件或者文件夹创建File对象,然后放到File[]中
public class Demo07File {
public static void main(String[] args) {
File file = new File("E:\\Idea\\io\\aa");
//String[] list() -> 遍历指定的文件夹,返回的是String数组
String[] list1 = file.list();
for (String s : list1) {
System.out.println(s);
}
System.out.println("=========================");
//File[] listFiles()-> 遍历指定的文件夹,返回的是File数组
File[] files = file.listFiles();
for (File file1 : files) {
System.out.println(file1);
}
}
}
练习1-
遍历指定文件夹下所有的.jpg文件
1.创建File对象,指明要遍历的文件夹路径
2.调用listFiles方法,遍历文件夹,返回File数组
3.遍历File数组,在遍历的过程中,判断,是否为文件
4.如果是文件,获取文件名称,判断是否以.jpg结尾,如果是,直接输出此文件
5.如果不是文件,肯定是文件夹,就继续遍历此文件夹,重复2 3 4 5的步骤
public class Demo08File {
public static void main(String[] args) {
//1.创建File对象,指明要遍历的文件夹路径
File file = new File("E:\\Idea\\io\\aa");
method(file);
}
public static void method(File file) {
//2.调用listFiles方法,遍历文件夹,返回File数组
File[] files = file.listFiles();
//3.遍历File数组,在遍历的过程中,判断,是否为文件
for (File file1 : files) {
//4.如果是文件,获取文件名称,判断是否以.jpg结尾,如果是,直接输出此文件
if (file1.isFile()) {
String name = file1.getName();
if (name.endsWith(".jpg")) {
System.out.println(name);
}
} else {
//5.如果不是文件,肯定是文件夹,就继续遍历此文件夹,重复2 3 4 5的步骤
method(file1);
}
}
}
}
第二部分 字节流
1.IO流:
I:Input -> 输入
O:Output -> 输出2.IO概述:
将数据从一个设备上传输到另外一个设备上的技术
3.为啥要学IO流呢?
a.之前学过数组,集合,都是存储数据的,但是数组和集合都是临时存储(程序运行,数据还在,运行完毕,数据消失),但是我们想的是,如何将数据永久保存,将数据保存到硬盘上就可以了
4.IO流操作:
输出:将数据写到硬盘上 -> 写
输入:将硬盘上的数据读回来 -> 读
1)IO流介绍以及输入输出以及流向的介绍
四大基础类
OutputStream
InputStream
Writer
Reader
FileOutputStream
- 作用: 用于将数据以字节形式写入到本地文件中。它是
OutputStream
的子类,专门用于文件输出操作。可以用来写入文本、二进制数据(如图像数据)或其他原始字节。- 特点: 创建
FileOutputStream
对象时,可以选择是否以追加模式打开文件(即在文件末尾添加数据而不覆盖原有内容)。默认情况下,如果不指定追加模式,写入操作会覆盖文件原有的内容。FileInputStream
- 作用: 用于从本地文件中读取字节数据。它是
InputStream
的子类,专用于文件输入操作。能够读取文本、二进制数据或其他原始字节流。- 特点: 使用
FileInputStream
读取文件时,读取位置从文件起始处开始,并随着读取操作逐步推进。通常配合循环或其他手段来读取整个文件或所需部分。FileWriter
- 作用: 用于以字符流的形式将文本数据写入到本地文件中。它是
Writer
的子类,特别适合处理文本数据,因为字符流能处理Unicode字符集,确保多语言文本的正确编码。- 特点: 默认使用系统默认的字符编码来写入文件,但也可以指定特定字符集。与
FileOutputStream
类似,可以选择追加模式写入文件。FileReader
- 作用: 用于从本地文件中读取字符流形式的文本数据。它是
Reader
的子类,适用于处理文本文件,尤其是包含非ASCII字符的文件。- 特点: 同样使用系统默认的字符编码读取文件,也可以通过构造函数指定字符集。读取操作从文件起始处开始,并按需读取字符数据。
BufferedOutputStream
- 作用: 对
OutputStream
(如FileOutputStream
)进行封装,提供缓冲机制。它内部维护一个缓冲区,将用户提供的数据暂存于缓冲区中,当缓冲区满或者用户显式调用flush()
方法时,才一次性将缓冲区内容写入底层输出流。- 优点: 缓冲可以减少实际I/O操作次数,提高数据写入效率,尤其在处理大量小规模写入时效果显著。
BufferedInputStream
- 作用: 对
InputStream
(如FileInputStream
)进行封装,同样提供缓冲机制。它从底层输入流中预先读取一定数量的数据到缓冲区,用户请求读取时直接从缓冲区获取,避免频繁与底层设备交互。- 优点: 缓冲有助于提升读取性能,减少I/O操作次数,特别是当频繁进行小规模读取时。
BufferedWriter
- 作用: 类似于
BufferedOutputStream
,是对Writer
(如FileWriter
)的缓冲封装。提供字符流级别的缓冲写入功能,优化文本数据的写入效率。BufferedReader
- 作用: 类似于
BufferedInputStream
,是对Reader
(如FileReader
)的缓冲封装。提供字符流级别的缓冲读取功能,提高文本数据的读取速度。OutputStreamWriter
- 作用: 将字符流(
Writer
)与字节流(OutputStream
)关联起来,使得可以直接以字符形式写入到字节输出流中。用户指定特定字符编码,将字符数据转换为对应字节序列写入底层字节流。InputStreamReader
- 作用: 与
OutputStreamWriter
相反,它将字节流(InputStream
)与字符流(Reader
)关联起来,允许以字符形式从字节输入流中读取数据。根据指定的字符编码,将接收到的字节序列解码为相应的字符。ObjectOutputStream
- 作用: 用于序列化(即转换为字节流)Java对象,并将它们写入到输出流中。支持将对象的属性和状态信息保存到文件或网络流,以便后续反序列化恢复对象。常用于持久化对象数据、在网络间传递对象等场景。
ObjectInputStream
- 作用: 与
ObjectOutputStream
配对使用,用于从输入流中反序列化Java对象。它读取由ObjectOutputStream
写出的字节流,还原为原始的Java对象及其状态。主要用于从文件或网络流中恢复先前序列化的对象。PrintStream
- 作用: 是一种特殊的输出流,扩展了
FilterOutputStream
,提供了更方便的方法来输出各种类型的数据(如字符串、整数、浮点数等),并自动处理字符编码和行结束符。常见的如System.out
就是PrintStream
的实例。它还支持自动flush机制和错误处理。以上这些类构成了Java I/O体系的核心组成部分,根据具体需求,开发人员可以选择合适的类来实现文件、网络或其他I/O设备上的数据读写操作。其中,带缓冲的类通常提供更好的性能,而
ObjectOutputStream
和ObjectInputStream
则用于处理对象的序列化与反序列化。PrintStream
则为简单、直观的输出提供了便利。
2)IO的流向
1.输出:从内存出发,将数据保存到硬盘上 -> 写
2.输入:将数据从硬盘上读到内存中 -> 读
3)IO流的分类
字节流:按照字节操作文件-> 一切皆字节-> 字节流是万能流
字节输出流:OutputStream -> 抽象类 -> 写
字节输入流:InputStream -> 抽象类 -> 读
字符流:操作文本文档 -> 用记事本打开的,人能看懂的
字符输出流:Writer -> 抽象类 -> 写
字符输入流:Reader -> 抽象类 -> 读
4)OutputStream中子类[FileOutputStream]的介绍以及方法的简单介绍
1.概述:
字节输出流:FileOutputStream extends OutputStream
2.作用:将内存中的数据保存(写)到硬盘上
3.构造: 如果指定的文件不存在,FileOutputStream自动创建,当然不能创建文件夹
FileOutputStream(File file) -> 根据File对象创建FileOutputStream对象
FileOutputStream(String name) -> 根据String表示的路径创建FileOutputStream
4.方法:
void write(int b) -> 一次写一个字节
void write(byte[] b) -> 一次写一个字节数组
void write(byte[] b, int off, int len) -> 一次写一个字节数组一部分
b:被操作的数组
off:从数组的哪个索引开始写
len:写多少个
void close() : 关闭资源
/**
* void write(int b) -> 一次写一个字节
* @throws FileNotFoundException
*/
private static void method01() throws Exception {
FileOutputStream fos = new FileOutputStream("day19_IO\\io\\1.txt");
fos.write(97);
//关流
fos.close();
}
/**
* void write(byte[] b) -> 一次写一个字节数组
*/
private static void method02()throws Exception {
FileOutputStream fos = new FileOutputStream("day19_IO\\io\\1.txt");
byte[] bytes = {97,98,99,100,101};
fos.write(bytes);
fos.close();
}
/**
* void write(byte[] b, int off, int len) -> 一次写一个字节数组一部分
* b:被操作的数组
* off:从数组的哪个索引开始写
* len:写多少个
*/
private static void method03()throws Exception {
FileOutputStream fos = new FileOutputStream("day19_IO\\io\\1.txt");
byte[] bytes = {97,98,99,100,101,102};
fos.write(bytes,0,2);
fos.close();
}
private static void method04()throws Exception {
FileOutputStream fos = new FileOutputStream("day19_IO\\io\\1.txt");
//byte[] bytes = "你好".getBytes();//[-28, -67, -96, -27, -91, -67]
fos.write("abcd".getBytes());
fos.close();
}
5)InputStream子类[FileInputStream]的介绍以及方法的使用
1.概述:字节输入流
FileInputStream extends InputStream
2.作用:读数据
3.构造:
FileInputStream(File path)
FileInputStream(String path)
4.方法:
int read() -> 一次读取一个字节,返回的是字符对应的字节整数
int read(byte[] b) -> 一次读取一个字节数组,返回的是读取的个数
int read(byte[] b, int off, int len)-> 一次读取一个字节数组一部分,返回的是读取的个数
b:读取的数组
off:从哪个索引开始读
len:读多少个
void close() : 关闭资源
6) 一次读一个字节
private static void method02() throws Exception{
FileInputStream fis = new FileInputStream("day19_IO\\io\\1.txt");
//定义一个变量,接收读取的字节
int len;
while((len = fis.read())!=-1){
//System.out.println(len);
System.out.println((char) len);
}
fis.close();
}
/**
* int read() -> 一次读取一个字节,返回的是字符对应的字节整数
*/
private static void method01()throws Exception {
FileInputStream fis = new FileInputStream("day19_IO\\io\\1.txt");
int data1 = fis.read();
System.out.println(data1);
int data2 = fis.read();
System.out.println(data2);
int data3 = fis.read();
System.out.println(data3);
/*int data4 = fis.read();
System.out.println(data4);*/
fis.close();
}
1.用同一个流对象读完之后,再次读就读不出来了
2.流用完之后要关闭,关闭之后流对象就不能用了
Exception in thread "main" java.io.IOException: Stream Closed
at java.io.FileInputStream.read0(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:207)
at com.atguigu.b_io.Demo03FileInputStream.method01(Demo03FileInputStream.java:39)
at com.atguigu.b_io.Demo03FileInputStream.main(Demo03FileInputStream.java:7)
3.不要循环判断的时候read一次,然后输出时再read一次,不然输出的内容会跳着输出
7) 读取-1问题
每个文件末尾都会有一个"标记",叫做"结束标识"
8)一次读取一个字节数组以及过程
/**
* int read(byte[] b) -> 一次读取一个字节数组,返回的是读取的个数
*
* 注意:
* a.字节数组定多长,每次就会读取多少个字节,数组相当于是一个临时存储空间,
* 读到的内容会自动保存到数组中
* b.一般情况下,数组长度都是指定1024或者1024的倍数
*/
private static void method03()throws Exception {
FileInputStream fis = new FileInputStream("day19_IO\\io\\1.txt");
byte[] bytes = new byte[5];
/*int len1 = fis.read(bytes);
//System.out.println(len1);//2
System.out.println(new String(bytes,0,len1));
int len2 = fis.read(bytes);
//System.out.println(len2);//2
System.out.println(new String(bytes,0,len2));
int len3 = fis.read(bytes);
//System.out.println(len3);//1
System.out.println(new String(bytes,0,len3));
int len4 = fis.read(bytes);
System.out.println(len4);// 读到结束标记之后返回-1*/
//定义一个变量,接收读取的字节个数
int len;
while((len = fis.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
fis.close();
}
9)字节流实现图片复制分析
图片复制代码实现:
package com.newio.b_io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Demo04Copy {
public static void main(String[] args)throws Exception {
FileInputStream fis = new FileInputStream("E:\\Idea\\io\\27.jpg");
FileOutputStream fos = new FileOutputStream("E:\\Idea\\io\\upload\\27.jpg");
//定义一个数组
byte[] bytes = new byte[1024];
int len;
while((len = fis.read(bytes))!=-1){
fos.write(bytes,0,len);
}
//关流-> 先开的后关
fos.close();
fis.close();
}
}
第三部分 字符流
1)字节流读取中文的问题
1.注意:字节流是万能流,侧重文件复制,但是不要边读边看(尤其是遇到中文了)
2.原因:同一个中文在不同的编码表中所占字节不一样
GBK:一个中文占2个字节
UTF-8:一个中文占3个字节
2)FileReader的介绍以及使用
1.概述:字符输入流
FileReader extends Reader
2.作用:读数据
3.构造:
FileReader(File file)
FileReader(String path)
4.方法:
int read() -> 一次读取一个字符
int read(char[] cbuf) -> 一次读取一个字符数组,返回读取个数
int read(char[] cbuf, int off, int len) -> 一次读取一个字符数组一部分,返回读取个数
void close()->关流
/**
* int read() -> 一次读取一个字符
*/
private static void method01()throws Exception {
FileReader fr = new FileReader("day19_IO\\io\\2.txt");
/*int data1 = fr.read();
System.out.println((char) data1);
int data2 = fr.read();
System.out.println((char) data2);*/
int len;
while((len = fr.read())!=-1){
System.out.println((char) len);
}
fr.close();
}
/**
* int read(char[] cbuf) -> 一次读取一个字符数组,返回读取个数
*/
private static void method02()throws Exception {
FileReader fr = new FileReader("day19_IO\\io\\2.txt");
char[] chars = new char[2];
int len;//接收的是读取的个数
while((len = fr.read(chars))!=-1){
System.out.println(new String(chars,0,len));
}
fr.close();
}
即使用字符流读取,如果编码不一致,依然会乱码
3)FileWriter的介绍以及使用
1.概述:字符输出流
FileWriter extends Writer
2.作用:写数据
3.构造:
FileWriter(File file)
FileWriter(String path)
FileWriter(String path,boolean append)-> 续写追加
4.方法:
void write(int c) -> 一次写一个字符
void write(String str) -> 一次写一个字符串
void write(char[] cbuf) -> 一次写一个字符数组
void write(char[] cbuf, int off, int len) -> 一次写一个字符数组一部分
void write(String str, int off, int len) -> 一次写一个字符串一部分
void flush() -> 刷新缓冲区
void close() -> 关闭资源
5.注意:FileWriter底层自带一个缓冲区,我们需要将缓冲区中的数据刷到文件中
public class Demo06FileWriter {
public static void main(String[] args) throws Exception{
FileWriter fw = new FileWriter("day19_IO\\io\\3.txt");
fw.write("李白乘舟将欲行\r\n");
fw.write("忽闻岸上踏歌声\n");
fw.write("桃花潭水深千尺\n");
fw.write("不及汪伦送我情\n");
fw.flush();
}
}
public class Demo07FileWriter {
public static void main(String[] args) throws Exception{
FileWriter fw = new FileWriter("day19_IO\\io\\3.txt",true);
fw.write("鹅鹅鹅\r\n");
fw.write("曲项向天歌\n");
fw.write("白毛浮绿水\n");
fw.write("红掌拨清波\n");
fw.flush();
}
}
4)FileWriter的刷新功能和关闭功能
flush:将缓冲区中的数据刷新到文件中,后续流对象还能使用
close:先刷新,再关闭,后续流对象不能继续使用
5)IO流的异常处理方式
public class Demo09FileWriter {
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("day19_IO\\io\\3.txt");
fw.write("你好java");
} catch (Exception e) {
e.printStackTrace();
} finally {
/*
fw如果没有new出来,就没必要close了
*/
if (fw!=null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
6)jdk7后IO流的处理方式(拓展)
1.格式:
try(IO流对象){
可能出现异常的代码
} catch (Exception e) {
e.printStackTrace();
}2.以上异常处理方式,会自动关流
public class Demo10FileWriter {
public static void main(String[] args) {
try (FileWriter fw = new FileWriter("day19_IO\\io\\3.txt");) {
fw.write("你好java");
} catch (Exception e) {
e.printStackTrace();
}
}
}
第四部分 字节缓冲流
1.为啥要学缓冲流:
之前所学的FileOutputStream等流,方法都是和硬盘之间进行读写的,效率不高,缓冲流底层自带缓冲区,此时读和写都是在内存中完成的,读写效率要高
2.字节缓冲输出流:BufferedOutputStream
a.构造:
BufferedOutputStream(OutputStream out)
b.方法:
和FileOutputStream一样
3.字节缓冲输入流:BufferedInputStream
a.构造:
BufferedInputStream(InputStream in)
b.方法:
和FileInputStream一样
4.缓冲流底层默认有一个8192的缓冲区(数组)
public class Demo01BufferedOutput_BufferedInput {
public static void main(String[] args)throws Exception {
//copy1();
copy2();
}
/**
* 用缓冲流复制
* @throws Exception
*/
private static void copy2()throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\Idea\\io\\upload\\1.avi"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\Idea\\io\\upload\\2.avi"));
long start = System.currentTimeMillis();
//定义一个数组
byte[] bytes = new byte[1024];
int len;
while((len = bis.read(bytes))!=-1){
bos.write(bytes,0,len);
}
long end = System.currentTimeMillis();
System.out.println((end-start)+"毫秒");
//关流-> 先开的后关
bos.close();
bis.close();
}
/**
* 用普通流复制一个视频
*/
private static void copy1()throws Exception {
FileInputStream fis = new FileInputStream("E:\\Idea\\io\\upload\\1.avi");
FileOutputStream fos = new FileOutputStream("E:\\Idea\\io\\upload\\2.avi");
long start = System.currentTimeMillis();
//定义一个数组
byte[] bytes = new byte[1024];
int len;
while((len = fis.read(bytes))!=-1){
fos.write(bytes,0,len);
}
long end = System.currentTimeMillis();
System.out.println((end-start)+"毫秒");
//关流-> 先开的后关
fos.close();
fis.close();
}
}
第五部分 字符缓冲流
1)字符缓冲输出流_BufferedWriter
1.概述:BufferedWriter extends Writer
2.构造:
BufferedWriter(Writer w)
3.方法:
和FileWriter一样
4.特有方法:
void newLine() -> 换行
public class Demo02BufferedWriter {
public static void main(String[] args)throws Exception {
BufferedWriter bw = new BufferedWriter(new FileWriter("day20_IO\\io\\bufferedwriter.txt"));
bw.write("枯藤老树昏鸦");
bw.newLine();
bw.write("小桥流水人家");
bw.newLine();
bw.write("古道西风瘦马");
bw.newLine();
bw.write("夕阳西下,断肠人在天涯");
bw.newLine();
bw.close();
}
}
2)字符缓冲输入流_BufferedReader
1.概述:BufferedReader extends Reader
2.构造:
BufferedReader(Reader r)
3.方法:
和FileReader一样
4.特有方法:
String readLine()一次读一行
public class Demo03BufferedReader {
public static void main(String[] args)throws Exception {
BufferedReader br = new BufferedReader(new FileReader("day20_IO\\io\\bufferedwriter.txt"));
/*String s1 = br.readLine();
System.out.println("s1 = " + s1);
String s2 = br.readLine();
System.out.println("s2 = " + s2);
String s3 = br.readLine();
System.out.println("s3 = " + s3);
String s4 = br.readLine();
System.out.println("s4 = " + s4);*/
String line;
while((line = br.readLine())!=null){
System.out.println(line);
}
br.close();
}
}
3)字符缓冲流练习
将in.txt中的内容排好序,写到另外一个新文件中
c.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必得裨补阙漏,有所广益。
h.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。
d.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。
b.宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。
a.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。
i.今当远离,临表涕零,不知所言。
f.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。
g.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。
e.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。
步骤:
1.创建一个ArrayList集合,用于保存读取到的内容,进行排序
2.创建BufferedReader,用于读取每一行数据
3.创建BufferedWriter,将读取到的内容写到out.txt中
4.边读,边往Arraylist集合中存
5.利用Collections.sort进行排序
6.遍历集合,边遍历边写到out.txt中public class Demo04Copy { public static void main(String[] args) throws Exception{ //1.创建一个ArrayList集合,用于保存读取到的内容,进行排序 ArrayList<String> list = new ArrayList<>(); //2.创建BufferedReader,用于读取每一行数据 BufferedReader br = new BufferedReader(new FileReader("day20_IO\\io\\in.txt")); //3.创建BufferedWriter,将读取到的内容写到out.txt中 BufferedWriter bw = new BufferedWriter(new FileWriter("day20_IO\\io\\out.txt")); //4.边读,边往Arraylist集合中存 String line; while((line = br.readLine())!=null){ list.add(line); } //5.利用Collections.sort进行排序 Collections.sort(list); //6.遍历集合,边遍历边写到out.txt中 for (String s : list) { bw.write(s); bw.newLine(); } bw.close(); br.close(); } }
第六部分 转换流
1)字符编码
计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数转换之后的结果。[按照某种规则,将字符存储到计算机中,称为编码] 。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码 。比如说,按照A规则存储,同样按照A规则解析,那么就能显示正确的文本f符号。反之,按照A规则存储,再按照B规则解析,就会导致乱码现象。
2)字符集
字符集
Charset
:也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。计算机要准确的存储和识别各种字符集符号,需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBK字符集、Unicode字符集等。
ASCII字符集 :
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)。
基本的ASCII字符集,使用7位(bits)表示一个字符,共128字符。ASCII的扩展字符集使用8位(bits)表示一个字符,共256字符,方便支持欧洲常用字符。
ISO-8859-1字符集:
拉丁码表,别名Latin-1,用于显示欧洲使用的语言,包括荷兰、丹麦、德语、意大利语、西班牙语等。
ISO-8859-1使用单字节编码,兼容ASCII编码。
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)要求所有互联网协议都必须支持UTF-8编码。所以,我们开发Web应用,也要使用UTF-8编码。它使用一至四个字节为每个字符编码,编码规则:
128个US-ASCII字符,只需一个字节编码。
拉丁文等字符,需要二个字节编码。
大部分常用字(含中文),使用三个字节编码。
其他极少使用的Unicode辅助字符,使用四字节编码。
1.存储的过程就是编码的过程
读取的过程就是解码的过程
2.注意:
a.编码和解码必须遵循的是同一个字符集,不然会乱码
3.一个汉字在UTF-8编码中占3个字节
一个汉字在GBK编码中占2个字节
3)转换流_InputStreamReader
1.概述:字节流通向字符流的桥梁 ->读取
2.构造:
InputStreamReader(InputStream in, String charsetName)
charsetName:指定字符集,不区分大小写
3.用法:
和FileReader一样
public class Demo01InputStreamReader {
public static void main(String[] args)throws Exception {
InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\Idea\\io\\upload\\1.txt"),"gbk");
int data = isr.read();
System.out.println((char)data);
isr.close();
}
}
4)转换流_OutputStreamWriter
1.概述:OutputStreamWriter extends Writer -> 字符流通向字节流的桥梁
2.构造:
OutputStreamWriter(OutputStream out, String charsetName)
out:抽象类,传递子类对象
charsetname:指定字符编码
3.方法:和FileWriter一样
public class Demo02OutputStreamWriter {
public static void main(String[] args)throws Exception {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\Idea\\io\\upload\\2.txt"),"GBK");
osw.write("你");
osw.close();
}
}
第七部分 序列化流
1)序列化流与反序列化流介绍
(1)Java序列化就是指把Java对象转换为字节序列的过程
Java反序列化就是指把字节序列恢复为Java对象的过程。(2)序列化最重要的作用:在传递和保存对象时.保证对象的完整性和可传递性。对象转换为有序字节流,以便在网络上传输或者保存在本地文件中。
2)序列化流_ObjectOutputStream
1.作用:写对象
2.构造:
ObjectOutputStream(OutputStream out)
3.方法:
writeObject(对象)
4.注意:想要将对象进行序列化,需要实现Serializable接口
/**
* 序列化:ObjectOutputStream
*/
private static void write()throws Exception {
ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("day20_IO\\io\\object.txt"));
oos.writeObject(new Person("张三",18));
oos.close();
}
public class Person implements Serializable {
private String name;
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
3)反序列化_ObjectInputStream
1.作用:读对象
2.构造:
ObjectInputStream(InputStream in)
3.方法:
Object readObject()
/**
* 反序列化:ObjectInputStream
*/
private static void read()throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day20_IO\\io\\object.txt"));
Object o = ois.readObject();
System.out.println(o);
ois.close();
}
4)不想被反序列化操作(了解)
1.在数据前面加关键字:
transient
5)反序列化时出现的问题以及分析以及解决(扩展)
.问题描述:
序列化之后,我们修改源码,修改完之后没有重新序列化,直接反序列化,就会出现序列号冲突问题
public class Person implements Serializable {
static final long serialVersionUID = 42L;
private String name1;
public Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name1 = name;
this.age = age;
}
public String getName() {
return name1;
}
public void setName(String name) {
this.name1 = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name1 + '\'' +
", age=" + age +
'}';
}
}
public class Demo01Object {
public static void main(String[] args)throws Exception {
write();
read();
}
/**
* 反序列化:ObjectInputStream
*/
private static void read()throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day20_IO\\io\\object.txt"));
Object o = ois.readObject();
System.out.println(o);
ois.close();
}
/**
* 序列化:ObjectOutputStream
*/
private static void write()throws Exception {
ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("day20_IO\\io\\object.txt"));
oos.writeObject(new Person("张三",18));
oos.close();
}
}
6)经验问题
EOFException: 文件意外到达结尾异常
出现原因:反序列化的时候,次数和保存到文件中的对象个数不一样-----------------------------------------------------------------------------------------------------------------------
解决方法:
将多个对象放到集合中,然后序列化这个集合
第八部分 打印流_PrintStream(了解)
1)PrintStream打印流基本使用
1.构造:
PrintStream(String fileName)
2.方法:
println()原样输出,自带换行效果
print() 原样输出,不换行
public class Demo01PrintStream {
public static void main(String[] args)throws Exception {
PrintStream ps = new PrintStream("day20_IO\\io\\print.txt");
ps.println("白日依山尽");
ps.println("黄河入海流");
ps.println("欲穷千里目");
ps.println("更上一层楼");
ps.close();
}
}
扩展:改变流向
1.什么叫做改变流向:
System.out.println()->本身是输出到控制台上的
改变流向:可以让输出语句从控制台上输出改变成往指定文件中输出
2.方法:System类中的方法
static void setOut(PrintStream out) -> 改变流向-> 让输出语句从控制台输出转移到指定文件中
3.作用:
配合日志文件使用,可以将输出语句中的内容放到日志文件中保存起来
以后我们希望将输出的内容永久保存,但是输出语句将结果输出到控制台上,是临时显示;所以我们需要将输出的结果保存到日志文件中,就可以用setOut改变流向
public class Demo02PrintStream {
public static void main(String[] args)throws Exception {
PrintStream ps = new PrintStream("day20_IO\\io\\log.txt");
System.setOut(ps);
System.out.println("门前大桥下,游过一群鸭");
ps.close();
}
}
2)PrintStream打印流完成续写
PrintStream(OutputStream out)
public class Demo03PrintStream {
public static void main(String[] args)throws Exception {
PrintStream ps = new PrintStream(new FileOutputStream("day20_IO\\io\\printstream.txt",true));
ps.println("火大了火大了,饺子破了");
ps.println("饺子破没法吃怎么办呀?");
ps.println("皮儿在外馅儿在内那是饺子");
ps.println("皮儿在内馅儿在外那是披萨");
ps.close();
}
}
第九部分 Properties集合
1)Properties结合IO流使用方法
1.Properties概述:是Hashtable的子类
2.特点:
a.key唯一,value可重复
b.无序
c.无索引
d.线程安全
e.key和value都是默认String
3.特有方法:
setProperty(String key,String value) 存键值对
getProperty(String key) 根据key获取value
stringPropertyNames()获取所有的key存到set集合中
load(InputStream in)将流中的数据装载到Properties集合中
public class Demo01Properties {
public static void main(String[] args) {
Properties properties = new Properties();
properties.setProperty("username","tom");
properties.setProperty("password","1234");
Set<String> set = properties.stringPropertyNames();
for (String key : set) {
String value = properties.getProperty(key);
System.out.println(key+"..."+value);
}
}
}
1.问题描述:
很多数据直接放到源码中不太合适,如果我们要修改这些数据,就要去源码中修改,类和类之间有联系,有可能改完之后有问题了
2.解决:
将这些硬数据放到文件中,然后动态解析文件(配置文件),动态获取文件中的数据,到时候想修改数据,我们直接去文件中改,不用频繁修改源代码了
3.使用:
load(InputStream in)将流中的数据装载到Properties集合中
4.Properties的使用场景:
配合配置文件使用
5.怎么创建properties配置文件:
a.右键->file
b.取名字:xxx.properties
properties配置文件的配置要求:
1.必须是key=value形式
2.每一个键值对写完要换行写下一对
3.尽量不要写中文
4.key和value都是String的,但是不要加""
5.不要有空格username=root
password=1234
public class Demo02Properties {
public static void main(String[] args)throws Exception {
FileInputStream in = new FileInputStream("day20_IO\\pro.properties");
Properties properties = new Properties();
properties.load(in);
Set<String> set = properties.stringPropertyNames();
for (String key : set) {
String value = properties.getProperty(key);
System.out.println(key+"..."+value);
}
}
}
第十部分 Commons-io工具包
1)介绍
IO技术开发中,代码量很大,而且代码的重复率较高。如果我们要遍历目录,拷贝目录就需要使用方法的递归调用,也增大了程序的复杂度。
Apache软件基金会,开发了IO技术的工具类`commonsIO`,大大简化IO开发。
2)添加第三方 jar包
1.Apache软件基金会属于第三方(Oracle公司是第一方,我们自己是第二方,其他的都是第三方)我们要使用第三方开发号的工具,需要添加jar包
2.jar包介绍:属于一个压缩包,里面装的都是class文件
我们想使用jar包中开发好的API,我们需要将jar引入到我们当前项目环境下
3.怎么引入jar包:
a.在当前模块下创建一个文件夹,取名为lib或者libs
b.将jar包复制到lib下
c.将jar包解压到当年项目环境下
对着lib右键 -> add as library -> ok
3)工具包的使用
IOUtils类
- 静态方法:IOUtils.copy(InputStream in,OutputStream out)传递字节流,实现文件复制。
- 静态方法:IOUtils.closeQuietly(任意流对象)悄悄的释放资源,自动处理close()方法抛出的异常。
public class Demo01IOUtils {
public static void main(String[] args) {
//- 静态方法:IOUtils.copy(InputStream in,OutputStream out)传递字节流,实现文件复制。
//IOUtils.copy(new FileInputStream("E:\\Idea\\io\\1.jpg"),new FileOutputStream("E:\\Idea\\io\\柳岩.jpg"));
//- 静态方法:IOUtils.closeQuietly(任意流对象)悄悄的释放资源,自动处理close()方法抛出的异常。
FileWriter fw = null;
try {
fw = new FileWriter("day20_IO\\io\\commons.txt");
} catch (IOException e) {
e.printStackTrace();
} finally {
//fw.close();
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)读取文本文件,返回字符串。
public class Demo01FileUtils {
public static void main(String[] args) throws IOException {
//- 静态方法:FileUtils.copyDirectoryToDirectory(File src,File dest);
//传递File类型的目录,进行整个目录的复制,自动进行递归遍历。
//参数:
//src:要复制的文件夹路径
//dest:要将文件夹粘贴到哪里去
//FileUtils.copyDirectoryToDirectory(new File("E:\\Idea\\io\\aa"),new File("E:\\Idea\\io\\bb"));
//- 静态方法:writeStringToFile(File file,String str)写字符串到文本文件中。
//FileUtils.writeStringToFile(new File("day20_IO\\io\\commons.txt"),"hahah");
//- 静态方法:String readFileToString(File file)读取文本文件,返回字符串。
String s = FileUtils.readFileToString(new File("day20_IO\\io\\commons.txt"));
System.out.println(s);
}
}
第十一部分 Lombok
1)基本介绍
1.作用:简化javabean
2.使用:
a.导jar包
b.下插件
Lombok通过增加一些“处理程序”,可以让java变得简洁、快速。
Lombok能以注解形式来简化java代码,提高开发效率。开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法,而且需要维护。
Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。出现的神奇就是在源码中没有getter和setter方法,但是在编译生成的字节码文件中有getter和setter方法。这样就省去了手动重建这些代码的麻烦,使代码看起来更简洁些。
2)常用注解
@Getter和@Setter
作用:生成成员变量的get和set方法。
写在成员变量上,指对当前成员变量有效。
写在类上,对所有成员变量有效。
注意:静态成员变量无效。
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private String name;
private Integer age;
}
public class Test01 {
public static void main(String[] args) {
Person person = new Person();
person.setName("柳岩");
person.setAge(36);
System.out.println(person.getName()+"..."+person.getAge());
System.out.println(person);
System.out.println("======================");
Person person1 = new Person("曼曼", 18);
System.out.println(person1);
}
}
第十二部分 正则表达式
1)正则表达式的概念以及演示
1.概述:
就是一个具有特殊规则的字符串
2.作用:
用于校验规则
3.如何判断输入的字符串是否符合正则表达式
boolean matches(String regex)-> regex代表的是正则表达式
4.需求:校验一个QQ号
a.不能0开头
b.必须都是数字
c.必须是5-15位
public class Demo01Regex {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String data = sc.next();
//boolean result = method(data);
//System.out.println("result = " + result);
System.out.println("======================");
boolean result1 = method02(data);
System.out.println("result1 = " + result1);
}
private static boolean method02(String data) {
boolean result = data.matches("[1-9][0-9]{4,14}");
return result;
}
private static boolean method(String data) {
//a.不能0开头
if (data.startsWith("0")){
return false;
}
//b.必须都是数字
char[] chars = data.toCharArray();
for (char aChar : chars) {
if (aChar<'0' || aChar>'9'){
return false;
}
}
//c.必须是5-15位
if (data.length()<5 || data.length()>15){
return false;
}
return true;
}
}
2)正则表达式-字符类
java.util.regex.Pattern:正则表达式的编译表示形式。
正则表达式-字符类:[]表示一个区间,范围可以自己定义
语法示例:
1. [abc]:代表a或者b,或者c字符中的一个。
2. [^abc]:代表除a,b,c以外的任何字符。
3. [a-z]:代表a-z的所有小写字符中的一个。
4. [A-Z]:代表A-Z的所有大写字符中的一个。
5. [0-9]:代表0-9之间的某一个数字字符。
6. [a-zA-Z0-9]:代表a-z或者A-Z或者0-9之间的任意一个字符。
7. [a-dm-p]:a 到 d 或 m 到 p之间的任意一个字符
public class Demo02Regex {
public static void main(String[] args) {
//1.验证字符串是否以h开头,d结尾,中间是aeiou的某一个字符
boolean result01 = "had".matches("[h][aeiou][d]");
System.out.println("result01 = " + result01);
//2.验证字符串是否以h开头,d结尾,中间不是aeiou的某一个字符
boolean result02 = "had".matches("[h][^aeiou][d]");
System.out.println("result02 = " + result02);
//3.验证字符串是否是开头a-z的任意一个小写字母,后面跟ad
boolean result03 = "had".matches("[a-z][a][d]");
System.out.println("result03 = " + result03);
}
}
3)正则表达式-逻辑运算符
/**
正则表达式-逻辑运算符
语法示例:
1. &&:并且
2. | :或者
**/
public class Demo03Regex {
public static void main(String[] args) {
//1.要求字符串是小写a-z的任意字符,并且字符不能以[aeiou]开头,后面跟ad
boolean result01 = "aad".matches("[[a-z]&&[^aeiou]][a][d]");
System.out.println("result01 = " + result01);
//2.要求字符串是aeiou中的某一个字母开头,后跟ad
boolean result02 = "aad".matches("[a|e|i|o|u][a][d]");
System.out.println("result02 = " + result02);
}
}
4)正则表达式0-预定义字符
/**
正则表达式-预定义字符
语法示例:
1. "." : 匹配任何字符。(重点) 不能加[]
2. "\\d":任何数字[0-9]的简写;(重点)
3. "\\D":任何非数字[^0-9]的简写;
4. "\\s": 空白字符:[ \t\n\x0B\f\r] 的简写
5. "\\S": 非空白字符:[^\s] 的简写
6. "\\w":单词字符:[a-zA-Z_0-9]的简写(重点)
7. "\\W":非单词字符:[^\w]
**/
public class Demo04Regex {
public static void main(String[] args) {
//1.验证字符串是否是三位数字
//boolean result01 = "111".matches("[0-9][0-9][0-9]");
boolean result01 = "111".matches("\\d\\d\\d");
System.out.println("result01 = " + result01);
//2.验证手机号:1开头 第二位3 5 8 剩下的9位都是0-9的数字
boolean result02 = "13838381438".matches("[1][358]\\d\\d\\d\\d\\d\\d\\d\\d\\d");
System.out.println("result02 = " + result02);
//3.验证字符串是否以h开头,d结尾,中间是任意一个字符
boolean result03 = "had".matches("[h].[d]");
System.out.println("result03 = " + result03);
}
}
5)正则表达式-数量词
/**
正则表达式-数量词
语法示例:x代表字符
1. X? : x出现的数量为 0次或1次
2. X* : x出现的数量为 0次到多次 任意次
3. X+ : x出现的数量为 1次或多次 X>=1次
4. X{n} : x出现的数量为 恰好n次 X=n次
5. X{n,} : x出现的数量为 至少n次 X>=n次 x{3,}
6. X{n,m}: x出现的数量为 n到m次(n和m都是包含的) n=<X<=m
**/
public class Demo05Regex {
public static void main(String[] args) {
//1.验证字符串是否是三位数字
boolean result01 = "1111".matches("\\d{3}");
System.out.println("result01 = " + result01);
//2.验证手机号:1开头 第二位3 5 8 剩下的9位都是0-9的数字
boolean result02 = "13838381438".matches("[1][358]\\d{9}");
System.out.println("result02 = " + result02);
//3.验证qq号:不能是0开头 都是数字 5-15
boolean result03 = "1212121".matches("[1-9][0-9]{4,14}");
System.out.println("result03 = " + result03);
}
}
6)正则表达式-分组括号()
public class Demo06Regex {
public static void main(String[] args) {
//校验字符串abc可以出现任意次
boolean result01 = "abcabcabca".matches("(abc)*");
System.out.println("result01 = " + result01);
}
}
7)String类中和正则表达式相关的方法
/**
String类中和正则表达式相关的方法
boolean matches(String regex) 判断字符串是否匹配给定的正则表达式。
String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串。
String replaceAll(String regex, String replacement)把满足正则表达式的字符串,替换为新的字符
**/
public class Demo07Regex {
public static void main(String[] args) {
String s = "abc dfad sadfasdf a";
String[] arr = s.split(" +");
System.out.println(Arrays.toString(arr));
System.out.println("=================");
//String replaceAll(String regex, String replacement)把满足正则表达式的字符串,替换为新的字符
String s1 = "abc adfa sadfads dfdsa dsaf";
String newStr = s1.replaceAll(" +", "z");
System.out.println("newStr = " + newStr);
}
}
8)正则表达式生成
https://www.sojson.com/regex/generate
IO 流总结
写的不好的,希望看到这边的人给我指出来,谢谢读者!