学习视频:https://www.bilibili.com/video/BV1Cv411372m
如侵权,请私信联系本人删除
文章目录
- 黑马程序员Java教程学习笔记(六)
- File概述、File对象创建
- File类的常用方法
- 方法递归
- 非规律化递归问题:文件搜索
- IO前置内容:字符集
- IO流分类、文件字节输入流、读取字节数据、避免乱码的方案
- 文件字节输出流、文件拷贝、释放资源的2种方式
- 文件字符输入流、文件字符输出流
- 缓冲流的分类、字节缓冲流使用
- 字节缓冲流的性能分析
- 字符缓冲流
- 代码与文件编码不一致读取乱码问题、转换流
- 对象序列化、反序列化
- 打印流、Properties、commons-io框架
- 线程概述、线程的创建方式
- 线程常用方法
- 线程安全问题
- 线程同步、同步代码块、同步方法、同步锁
- 线程通信
- 线程池概述
- 线程池处理Runnable、Callable任务
- Executors的工具类构建线程池对象
- 定时器
- 线程并发、并行、线程生命周期的6种状态
- 网络通信三要素:IP及其类InetAddress、端口、协议
- UDP快速入门、多发多收消息、广播、组播
- TCP通信快速入门
- TCP通信实现、多发多收消息、实现同时接收多个客户端
- TCP通信模型:线程池优化
- TCP实战案例:即时通信、BS架构模拟
- 单元测试:Junit框架
- 反射概述、获取Class类对象
- 反射获取Constructor、Field、Method对象
- 反射的作用:绕过编译阶段,做企业级通用框架
- 注解概述、自定义注解、元注解、注解解释
- 注解的应用:模拟JUnit框架
- 动态代理
- XML、XML创建
- XML文档约束
- XML文件解析技术:Dom4j
- XML文件的数据检索技术:XPath
- 补充知识:工厂模式、装饰模式
黑马程序员Java教程学习笔记(六)
File概述、File对象创建
File
类可以定位文件:进行删除、获取文本本身信息等操作- 但是不能读写文件内容
- 使用
IO流
技术可以对硬盘中的文件进行读写
File类概述:
- File类在包
java.io.File
下,代表操作系统的文件对象(文件、文件夹) - File类提供了诸如:定位文件、获取文件本身的信息、删除文件、创建文件(文件夹)等功能
注意:File创建对象,支持绝对路径,也支持相对路径
package com.mochu.d1_file;
import java.io.File;
public class FileDemo {
public static void main(String[] args) {
// 创建File对象(指定了文件的路径)
File f = new File("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
// 一般不使用File.separator 但是在一些跨平台Linux Windows都是用的情况下File.separator比较方便
// File f1 = new File("C:" + File.separator + "Users" + File.separator + "Administrator" + File.separator + "Downloads");
long fileSize = f.length();
System.out.println("文件大小:" + fileSize);
// 相对路径一般定位模块中的文件,相对在工程下(从工程目录开始)
File f2 = new File("File-IO-App\\src\\data.txt");
System.out.println(f2.length());
// File对象可以是文件也可以是文件夹(目录)
File f3 = new File("C:\\Users\\Administrator\\Downloads");
System.out.println("文件夹是否存在:" + f3.exists());
}
}
File类的常用方法
package com.mochu.d1_file;
import java.io.File;
import java.text.SimpleDateFormat;
public class FileDemo01 {
public static void main(String[] args) {
File f1 = new File("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
// 获取绝对路径
System.out.println(f1.getAbsoluteFile());
// 获取文件定义时的路径
System.out.println(f1.getPath());
// 获取文件的名称(带后缀)
System.out.println(f1.getName());
// 获取文件的字节大小
System.out.println("文件的字节大小:" + f1.length());
// 获取文件的最后修改时间
long time = f1.lastModified();
System.out.println("最后修改时间:" + new SimpleDateFormat("yy/MM/dd HH:mm:ss").format(time));
// 判断是文件还是文件夹
System.out.println(f1.isFile());
System.out.println(f1.isDirectory());
System.out.println(f1.exists());
}
}
package com.mochu.d1_file;
import java.io.File;
import java.io.IOException;
public class FileDemo02 {
public static void main(String[] args) throws IOException {
File f = new File("C:\\Users\\Administrator\\Downloads\\flag.txt");
File f1 = new File("C:\\Users\\Administrator\\Downloads\\1.txt");
System.out.println(f.createNewFile());
System.out.println(f1.createNewFile());
// 创建一级目录
File f2 = new File("C:\\Users\\Administrator\\Downloads\\test");
System.out.println(f2.mkdir());
// 创建多级目录
File f3 = new File("C:\\Users\\Administrator\\Downloads\\test\\test");
System.out.println(f2.mkdirs());
// 删除文件或者空文件夹
File f4 = new File("C:\\Users\\Administrator\\Downloads\\test\\test");
File f5 = new File("C:\\Users\\Administrator\\Downloads\\1.txt");
System.out.println(f4.delete());
System.out.println(f5.delete());
}
}
package com.mochu.d1_file;
import java.io.File;
import java.io.IOException;
public class FileDemo02 {
public static void main(String[] args) throws IOException {
// 遍历目录
File f = new File("C:\\Users\\Administrator\\Downloads");
String[] names = f.list();
for (String name : names) {
System.out.println(name);
}
// 获取当前目录下的每个文件对象
File f1 = new File("C:\\Users\\Administrator\\Downloads");
File[] files = f1.listFiles();
for (File file : files) {
System.out.println(file.getAbsoluteFile());
}
}
}
方法递归
package com.mochu.d2_recursion;
public class RecursionDemo01 {
public static void main(String[] args) {
System.out.println(f(5));
}
public static int f(int n) {
if(n == 1) {
return 1;
}else {
return f(n - 1) * n;
}
}
}
package com.mochu.d2_recursion;
public class RecursionDemo01 {
public static void main(String[] args) {
System.out.println(f(100));
}
public static int f(int n) {
if(n == 1) {
return 1;
}else {
return f(n - 1) + n;
}
}
}
f(x) - f(x)/2 - 1 = f(x+1)
2f(x) - f(x) - 2 = 2f(x + 1)
f(x) = 2f(x + 1) + 2
求f(1) = ?
终结点: f(10) = 1
package com.mochu.d2_recursion;
public class RecursionDemo01 {
public static void main(String[] args) {
System.out.println(f(1));
System.out.println(f(2));
System.out.println(f(3));
}
public static int f(int n) {
if(n == 10) {
return 1;
}else {
return 2 * f(n + 1) + 2;
}
}
}
非规律化递归问题:文件搜索
package com.mochu.d2_recursion;
import java.io.File;
import java.io.IOException;
public class RecursionDemo01 {
public static void main(String[] args) {
File f = new File("D:\\KuGou\\");
searchFile(f, "KuGou.exe");
}
/**
* 搜索某个目录下的所有文件
* @param dir 被搜索的目录
* @param fileName 被搜索的文件名称
*/
public static void searchFile(File dir, String fileName) {
// 判断dir是否是目录
if(dir.isDirectory() && dir != null) {
File[] files = dir.listFiles();
if(files != null && files.length > 0) {
for (File file : files) {
// 判断当前的一级目录文件对象是文件还是文件夹
if(file.isFile()) {
if(file.getName().contains(fileName)) {
System.out.println(file.getAbsoluteFile());
try {
Runtime r = Runtime.getRuntime();
r.exec(file.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
}
}else {
// 递归
searchFile(file, fileName);
}
}
}
}else {
System.out.println("您当前的目录有误");
}
}
}
package com.mochu.d2_recursion;
public class RecursionDemo02 {
public static int totalNumber; // 总数量
public static int lastBottleNumber; // 记录每次剩余瓶子数
public static int lastConverNumber; // 记录每次剩余盖子数
public static void main(String[] args) {
buy(10);
System.out.println("总数: " + totalNumber);
System.out.println("剩余盖子数:" + lastConverNumber);
System.out.println("剩余瓶子数:" + lastBottleNumber);
}
public static void buy(int money){
int buyNumber = money / 2;
totalNumber += buyNumber;
int coverNumber = lastConverNumber + buyNumber;
int bottleNumber = lastBottleNumber + buyNumber;
int allMoney = 0;
if(coverNumber >= 4) {
allMoney += (coverNumber / 4) * 2;
}
lastConverNumber = coverNumber % 4;
if(bottleNumber >= 2) {
allMoney += (bottleNumber / 2) * 2;
}
lastBottleNumber = bottleNumber % 2;
if(allMoney >= 2) {
buy(allMoney);
}
}
}
IO前置内容:字符集
package com.mochu.d3_charset;
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws Exception{
// 文字转换成字节(使用指定编码)
String name = "末初mochu7";
// byte[] bytes = name.getBytes(); // 以默认字符集编码
byte[] bytes = name.getBytes("GBK"); // 以默认字符集编码
System.out.println(bytes.length);
System.out.println(Arrays.toString(bytes));
// 把字节转换成文字(注意:编码前和解码的字符集需要一致,否则乱码)
// String rs = new String(bytes);
String rs = new String(bytes, "GBK"); // 指定解码字符集
System.out.println(rs);
}
}
IO流分类、文件字节输入流、读取字节数据、避免乱码的方案
- IO流也称为输入、输出流,就是用来读写数据的
I
表示input,是数据从硬盘文件读入到内存的过程,称为输入、负责读O
表示output,是内存程序的数据从内存到写出硬盘文件的过程,称为输出,负责写
package com.mochu.d4_bytestream;
import java.io.FileInputStream;
import java.io.InputStream;
public class Test {
public static void main(String[] args) throws Exception{
InputStream is = new FileInputStream("File-IO-App/src/data.txt");
int b1 = is.read();
System.out.println(b1);
System.out.println((char) b1);
int b2 = is.read();
System.out.println((char) b2);
int b3 = is.read();
System.out.println((char) b3);
// 循环读取
InputStream is1 = new FileInputStream("File-IO-App/src/data.txt");
int b;
while((b = is1.read()) != -1) {
System.out.print((char) b);
}
}
}
package com.mochu.d4_bytestream;
import java.io.FileInputStream;
import java.io.InputStream;
public class ByteStreamDemo {
public static void main(String[] args) throws Exception {
InputStream is = new FileInputStream("File-IO-App/src/data.txt");
// 定一个字节数组,用于读取字节数据
byte[] buffer = new byte[4];
int len;
while((len = is.read(buffer)) != -1) {
System.out.print(new String(buffer, 0, len));
}
}
}
package com.mochu.d4_bytestream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class ByteStreamDemo {
public static void main(String[] args) throws Exception {
File f = new File("File-IO-App/src/data.txt");
InputStream is = new FileInputStream(f);
// byte[] buffer = new byte[(int) f.length()];
// int len = is.read(buffer);
// System.out.println("读取了" + len + "个字节");
// System.out.println("文件大小:" + f.length());
// System.out.println(new String(buffer));
byte[] buffer = is.readAllBytes();
System.out.println(new String(buffer));
}
}
文件字节输出流、文件拷贝、释放资源的2种方式
package com.mochu.d5_outputstream;
import java.io.*;
public class OutStreamDemo {
public static void main(String[] args) throws Exception {
// 创建一个文件字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream("File-IO-App/src/flag.txt", true); // true: 追加管道
os.write('a');
os.write(98);
os.write("\r\n".getBytes());
byte[] buffer = {'f', 'l', 'a', 'g'};
// 刷新、释放资源
// os.flush();
os.write(buffer);
byte[] buffer2 = "末初".getBytes();
os.write(buffer2);
os.close();
}
}
文件拷贝
package com.mochu.d5_outputstream;
import java.io.*;
public class CopyDemo {
public static void main(String[] args) throws Exception {
try {
InputStream is = new FileInputStream("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
OutputStream os = new FileOutputStream("C:\\Users\\Administrator\\Downloads\\Asuna-copy.jpg");
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
System.out.println("复制完成");
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
资源释放的方式
package com.mochu.resource;
import java.io.*;
public class TryCatchFinallyDemo {
public static void main(String[] args) throws Exception {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
os = new FileOutputStream("C:\\Users\\Administrator\\Downloads\\Asuna-copy.jpg");
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
System.out.println(10 / 0);
System.out.println("复制完成");
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
// 无论代码是否正常结束,都会执行这里
// 哪怕上面有return,也必须执行完这里才行,开发中不建议这里return
System.out.println("===============Finally===============");
try {
if(is != null) is.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(os != null) os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package com.mochu.resource;
import java.io.*;
public class TryCatchFinallyDemo {
public static void main(String[] args) throws Exception {
try(
InputStream is = new FileInputStream("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
OutputStream os = new FileOutputStream("C:\\Users\\Administrator\\Downloads\\Asuna-copy.jpg");
MyConnection connection = new MyConnection();
) {
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
System.out.println("复制完成了");
} catch (Exception e) {
e.printStackTrace();
}
}
}
class MyConnection implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("链接资源被成功释放");
}
}
package com.mochu.resource;
import java.io.*;
public class TryCatchFinallyDemo {
public static void main(String[] args) throws Exception {
InputStream is = new FileInputStream("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
OutputStream os = new FileOutputStream("C:\\Users\\Administrator\\Downloads\\Asuna-copy.jpg");
try(is; os) {
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
System.out.println("复制完成了");
} catch (Exception e) {
e.printStackTrace();
}
}
}
文件字符输入流、文件字符输出流
package com.mochu.d6_char_stream;
import java.io.FileReader;
import java.io.Reader;
public class FileReaderDemo {
public static void main(String[] args) throws Exception {
Reader fr = new FileReader("C:\\Users\\Administrator\\Downloads\\text.txt");
// int code = fr.read(); // 读取一个字节
// System.out.println((char) code);
int code;
while((code = fr.read()) != -1) {
System.out.print((char) code);
}
}
}
package com.mochu.d6_char_stream;
import java.io.FileReader;
import java.io.Reader;
public class FileReaderDemo {
public static void main(String[] args) throws Exception {
Reader fr = new FileReader("C:\\Users\\Administrator\\Downloads\\text.txt");
char[] buffer = new char[1024]; // 1K字符
int len;
while((len = fr.read(buffer)) != -1) {
String rs = new String(buffer, 0, len);
System.out.print(rs);
}
}
}
package com.mochu.d6_char_stream;
import java.io.FileWriter;
import java.io.Writer;
public class FileWriterDemo {
public static void main(String[] args) throws Exception {
// Writer fw = new FileWriter("C:\\Users\\Administrator\\Downloads\\1.txt");
Writer fw = new FileWriter("C:\\Users\\Administrator\\Downloads\\1.txt", true);
fw.write(100);
fw.write('m');
fw.write('末');
fw.write("\r\n");
fw.write("末初mochu7");
char[] chars = "末初mochu7".toCharArray();
fw.write(chars);
fw.write("\r\n");
fw.write("末初mochu7", 0, 3);
fw.write(chars, 0, 2);
// fw.flush(); // 刷新后流可以使用
fw.close(); // 关闭后流不可以使用
}
}
缓冲流的分类、字节缓冲流使用
package com.mochu.d1_byte_buffer;
import java.io.*;
public class ByteBuffDemo {
public static void main(String[] args) throws Exception {
try {
InputStream is = new FileInputStream("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
InputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream("C:\\Users\\Administrator\\Downloads\\Asuna-copy.jpg");
OutputStream bos = new BufferedOutputStream(os);
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
System.out.println("复制完成");
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
字节缓冲流的性能分析
package com.mochu.d7_ByteBufferTime;
import java.io.*;
public class ByteBufferTimeDemo {
private static final String SRC_FILE = "C:\\Users\\Administrator\\Downloads\\disk.flag.img";
private static final String DEST_FILE = "C:\\Users\\Administrator\\Downloads\\";
public static void main(String[] args) {
// copy01(); //使用低级字节流按照一个一个字节的形式复制文件 // 最慢
// copy02(); //使用低级字节流按照一个一个字节数组的形式复制文件 // 第二快
// copy03(); //使用缓冲流按照一个一个字节的形式复制文件 // 倒数第二慢
copy04(); //使用缓冲流按照一个一个字节数组的形式复制文件 // 最快
}
private static void copy04() {
long startTime = System.currentTimeMillis();
try(
InputStream is = new FileInputStream(SRC_FILE);
InputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream(DEST_FILE + "copy04-disk.flag.img");
OutputStream bos = new BufferedOutputStream(os);
) {
byte[] buffer = new byte[1024];
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');
}
/**
* 使用缓冲流按照一个一个字节的形式复制文件
*/
private static void copy03() {
long startTime = System.currentTimeMillis();
try(
InputStream is = new FileInputStream(SRC_FILE);
InputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream(DEST_FILE + "copy03-disk.flag.img");
OutputStream bos = new BufferedOutputStream(os);
) {
int len;
while((len = bis.read()) != -1) {
bos.write(len);
}
}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 + "copy02-disk.flag.img");
) {
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 copy01() {
long startTime = System.currentTimeMillis();
try(
InputStream is = new FileInputStream(SRC_FILE);
OutputStream os = new FileOutputStream(DEST_FILE + "copy01-disk.flag.img");
) {
int len;
while((len = is.read()) != -1) {
os.write(len);
}
}catch (Exception e){
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println(" 使用低级字节流按照一个一个字节的形式复制文件耗时:" + (endTime - startTime) / 1000.0 + 's');
}
}
字符缓冲流
package com.mochu.d8_CharBufferStream;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class CharBufferStreamDemo {
public static void main(String[] args) {
try(
Reader fr = new FileReader("File-IO-App/src/data.txt");
BufferedReader br = new BufferedReader(fr);
) {
// char[] buffer = new char[1024];
// int len;
// while((len = br.read(buffer)) != -1) {
// String rs = new String(buffer, 0, len);
// System.out.println(rs);
// }
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.mochu.d2_CharBufferStream;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.Writer;
public class CharBufferStreamDemo {
public static void main(String[] args) throws Exception {
Writer fw = new FileWriter("IO-App/src/data1.txt");
BufferedWriter bw = new BufferedWriter(fw);
bw.write(98);
bw.write('a');
bw.write('初');
bw.write("末初mochu7");
bw.newLine();
bw.close();
}
}
代码与文件编码不一致读取乱码问题、转换流
package com.mochu.d3_TransferStream;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class CharSetTest {
public static void main(String[] args) throws Exception {
try(
Reader fr = new FileReader("C:\\Users\\Administrator\\Downloads\\flag.txt");
BufferedReader bfr = new BufferedReader(fr);
) {
String line;
while((line = bfr.readLine()) != null) {
System.out.println(line);
}
}catch (IOException e){
e.printStackTrace();
}
}
}
package com.mochu.d3_TransferStream;
import java.io.*;
public class InputStreamReaderDemo {
public static void main(String[] args) throws Exception {
InputStream is = new FileInputStream("C:\\Users\\Administrator\\Downloads\\flag.txt");
Reader fr = new InputStreamReader(is, "GBK"); // 指定GBK转化字符输入流
BufferedReader br = new BufferedReader(fr);
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
package com.mochu.d3_TransferStream;
import java.io.*;
public class OutputStreamWriterDemo {
public static void main(String[] args) throws Exception{
OutputStream os = new FileOutputStream("IO-APP/src/test.txt");
Writer osw = new OutputStreamWriter(os, "GBK");
BufferedWriter bw = new BufferedWriter(osw);
bw.write("mochu7");
bw.write("末初");
bw.close();
}
}
对象序列化、反序列化
package com.mochu.d4_serialize;
import java.io.Serializable;
/**
* 对象要序列化需要实现Serializable接口
*/
public class Student implements Serializable {
private String name;
private String loginName;
private String passWord;
private int age;
.......
}
package com.mochu.d4_serialize;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class ObjectOutputStreamDemo{
public static void main(String[] args) throws Exception{
Student stu = new Student("mochu7", "mochu7", "mochu777", 22);
// 对象序列化,使用对象字节输出流管道
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("IO-App/src/obj.txt"));
oos.writeObject(stu);
oos.close();
}
}
package com.mochu.d4_serialize;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class ObjectInputStreamDemo {
public static void main(String[] args) throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("IO-App/src/obj.txt"));
// 调用对象字节输入流的反序列化方法
Student stu = (Student) ois.readObject();
System.out.println(stu);
}
}
如果不想类中的某个属性被序列化,使用transient
关键字:private transient String passWord;
// 声明序列化版本号码
// 序列化版本号与反序列化版本号必须一致才不会出错
private static final long serialVersionUID = 1;
打印流、Properties、commons-io框架
打印流:
- 作用:打印流可以实现方便、高效的打印数据到文件中去,打印流一般是指:
PrintStream
,PrintWriter
两个类
package com.mochu.d6_PrintStream;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class PrintStreamDemo {
public static void main(String[] args) throws Exception{
PrintStream ps = new PrintStream(new FileOutputStream("IO-App/src/ps.txt"));
// PrintStream ps = new PrintStream(new FileOutputStream("IO-App/src/ps.txt"), "GBK");
ps.print(97);
ps.println("mochu7");
ps.println(35.5);
ps.println("末初");
ps.close();
}
}
package com.mochu.d6_PrintStream;
import java.io.FileOutputStream;
import java.io.PrintWriter;
public class PrintStreamDemo {
public static void main(String[] args) throws Exception{
PrintWriter ps = new PrintWriter(new FileOutputStream("IO-App/src/ps1.txt"));
ps.print(97);
ps.println("mochu7");
ps.println(35.5);
ps.println("末初");
ps.close();
}
}
输出语句的重定向
package com.mochu.d6_PrintStream;
import java.io.PrintStream;
public class PrintDemo {
public static void main(String[] args) throws Exception{
System.out.println("mochu7");
System.out.println("Slevin");
// 改变输出语句的位置(重定向)
PrintStream ps = new PrintStream("IO-App/src/log.txt");
System.setOut(ps); // 把系统的打印流改成我们自己设定的
System.out.println("test");
System.out.println("test1");
}
}
Properties
package com.mochu.d7_Properties;
import java.io.FileWriter;
import java.util.Properties;
public class PropertiesDemo {
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
properties.setProperty("mochu7", "mochu777");
properties.setProperty("Slevin", "Slevin666");
properties.setProperty("Shinn", "Shinn888");
System.out.println(properties);
properties.store(new FileWriter("IO-App/src/users.properties"), "users properties");
}
}
package com.mochu.d7_Properties;
import java.io.FileReader;
import java.util.Properties;
public class PropertiesDemo01 {
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
properties.load(new FileReader("IO-App/src/users.properties"));
System.out.println(properties);
String rs = properties.getProperty("mochu7");
System.out.println(rs);
}
}
Commons-IO框架
Commons-IO: https://commons.apache.org/proper/commons-io/
package com.mochu.d8_CommonsIO;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
public class CommonsIODemo {
public static void main(String[] args) throws Exception {
// 文件复制
IOUtils.copy(new FileInputStream("IO-App/src/data.txt"), new FileOutputStream("IO-App/src/data2.txt"));
// 文件复制到文件夹
FileUtils.copyFileToDirectory(new File("IO-App/src/data.txt"), new File("C:/Users/Administrator/Downloads/"));
// 文件夹复制到文件夹
FileUtils.copyDirectoryToDirectory(new File("D:/Album/"), new File("C:/Users/Administrator/Downloads/"));
// 删除文件夹
FileUtils.deleteDirectory(new File("C:/Users/Administrator/Downloads/Album"));
// JDK 1.7 新增的一些关于文件操作的API:NIO
Files.copy(Path.of("IO-App/src/data.txt"), Path.of("IO-App/src/data3.txt"));
}
}
线程概述、线程的创建方式
线程创建方式一:继承Thread类
package com.mochu.d1_create;
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程输出:" + i);
}
}
}
package com.mochu.d1_create;
/**
* 多线程的创建方式一:继承Thread
*/
public class ThreadDemo {
public static void main(String[] args) {
Thread t1 = new MyThread();
t1.start();
for (int i = 0; i < 5; i++) {
System.out.println("[+]主线程输出:" + i);
}
}
}
线程创建方式二:实现Runmable接口
package com.mochu.d1_create;
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程:" + i);
}
}
}
package com.mochu.d1_create;
public class ThreadDemo2 {
public static void main(String[] args) {
// 创建一个任务对象,然后把人物对象交给线程对象
Runnable target = new MyRunnable();
Thread t = new Thread(target);
t.start();
for (int i = 0; i < 5; i++) {
System.out.println("[+]主线程输出:" + i);
}
}
}
package com.mochu.d1_create;
public class ThreadDemo2 {
public static void main(String[] args) {
// 创建一个任务对象,然后把人物对象交给线程对象
Runnable target = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程1输出:" + i);
}
}
};
// 简化
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程2输出:" + i);
}
}
}).start();
// 再简化
new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("子线程3输出:" + i);
}
}).start();
for (int i = 0; i < 5; i++) {
System.out.println("[+]主线程输出:" + i);
}
}
}
线程创建方式三:实现Callable、FutureTask接口
package com.mochu.d1_create;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class ThreadDemo3 {
public static void main(String[] args) {
// 创建Callable任务对象
Callable<String> call = new MyCallable(100);
// 把Callable任务对象封装成FutureTask对象
// FutureTask对象的作用:是Runnable对象(实现了Runnable接口)
// FutureTask对象的作用:可以在线程执行完毕之后,可以通过调用get方法得到线程执行完的结果
FutureTask<String> f1 = new FutureTask<>(call);
Thread t1 = new Thread(f1);
t1.start();
Callable<String> call1 = new MyCallable(200);
FutureTask<String> f2 = new FutureTask<>(call1);
Thread t2 = new Thread(f2);
t2.start();
try {
String rs1 = f1.get();
System.out.println("第一个结果:" + rs1);
} catch (Exception e) {
e.printStackTrace();
}
try {
String rs2 = f2.get();
System.out.println("第一个结果:" + rs2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class MyCallable implements Callable<String> {
private int n;
public MyCallable(int n) {
this.n = n;
}
// 实现Callable接口,声明线程执行完毕之后的返回类型
@Override
public String call() throws Exception {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
}
return "子线程执行的结果是:" + sum;
}
}
线程常用方法
package com.mochu.d2_api;
public class MyThread extends Thread{
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "子线程输出:" + i);
}
}
}
package com.mochu.d2_api;
public class ThreadDemo {
public static void main(String[] args) {
Thread t = new MyThread("1号");
// t.setName("一号");
t.start();
Thread t1 = new MyThread("2号");
// t1.setName("二号");
t1.start();
Thread m = Thread.currentThread();
System.out.println(m.getName());
for (int i = 0; i < 5; i++) {
System.out.println("主线程输出:" + i);
}
}
}
package com.mochu.d2_api;
public class ThreadDemo2 {
public static void main(String[] args) throws Exception {
for (int i = 1; i <= 5; i++) {
System.out.println("输出:" + i);
if(i == 3) {
// 进入休眠(毫秒)
Thread.sleep(3000);
}
}
}
}
线程安全问题
package com.mochu.d3_ThreadSecurity;
public class Account {
private String cardId;
private double money;
public Account() {
}
public Account(String cardId, double money) {
this.cardId = cardId;
this.money = money;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public void drawMoney(double money){
String name = Thread.currentThread().getName();
if(this.money >= money) {
System.out.println(name + "取钱\r\n金额:" + money);
this.money -= money;
System.out.println(name + "取钱后剩余:" + this.money);
}else {
System.out.println(name + "取钱,余额不足");
}
}
}
package com.mochu.d3_ThreadSecurity;
public class DrawThread extends Thread{
// 接收账户对象
private Account acc;
public DrawThread(Account acc, String name) {
super(name);
this.acc = acc;
}
@Override
public void run() {
acc.drawMoney(100000);
}
}
package com.mochu.d3_ThreadSecurity;
public class ThreadSecurityDemo {
public static void main(String[] args) {
Account acc = new Account("ICBC-1111", 100000);
// 创建两个线程对象
new DrawThread(acc, "小明").start();
new DrawThread(acc, "小红").start();
}
}
线程同步、同步代码块、同步方法、同步锁
同步代码块
public void drawMoney(double money){
String name = Thread.currentThread().getName();
// 同步代码块
synchronized ("mochu7") {
if(this.money >= money) {
System.out.println(name + "取钱\r\n金额:" + money);
this.money -= money;
System.out.println(name + "取钱后剩余:" + this.money);
}else {
System.out.println(name + "取钱,余额不足");
}
}
}
同步方法
public synchronized void drawMoney(double money){
String name = Thread.currentThread().getName();
if(this.money >= money) {
System.out.println(name + "取钱\r\n金额:" + money);
this.money -= money;
System.out.println(name + "取钱后剩余:" + this.money);
}else {
System.out.println(name + "取钱,余额不足");
}
}
Lock锁
private final Lock lock = new ReentrantLock();
public synchronized void drawMoney(double money){
String name = Thread.currentThread().getName();
lock.lock(); // 上锁
try {
if(this.money >= money) {
System.out.println(name + "取钱\r\n金额:" + money);
this.money -= money;
System.out.println(name + "取钱后剩余:" + this.money);
}else {
System.out.println(name + "取钱,余额不足");
}
} finally {
lock.unlock(); // 无论什么异常情况,都会解锁
}
}
线程通信
package com.mochu.d5_ThreadCommunication;
public class ThreadCommunicationDemo {
public static void main(String[] args) {
Account acc = new Account("ICBC-1122", 0);
new DrawThread(acc, "小明").start();
new DrawThread(acc, "小红").start();
new DepositThread(acc, "亲爹").start();
new DepositThread(acc, "干爹").start();
new DepositThread(acc, "岳父").start();
}
}
package com.mochu.d5_ThreadCommunication;
public class DrawThread extends Thread{
// 接收账户对象
private Account acc;
public DrawThread(Account acc, String name) {
super(name);
this.acc = acc;
}
@Override
public void run() {
while(true) {
acc.drawMoney(100000);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.mochu.d5_ThreadCommunication;
public class DepositThread extends Thread{
// 接收账户对象
private Account acc;
public DepositThread(Account acc, String name) {
super(name);
this.acc = acc;
}
@Override
public void run() {
while(true) {
acc.depositMoney(100000);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.mochu.d5_ThreadCommunication;
public class Account {
private String cardId;
private double money;
public Account() {
}
public Account(String cardId, double money) {
this.cardId = cardId;
this.money = money;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public synchronized void drawMoney(double money){
try {
String name = Thread.currentThread().getName();
if(this.money >= money) {
System.out.println(name + "取钱\r\n金额:" + money);
this.money -= money;
System.out.println(name + "取钱后剩余:" + this.money);
this.notifyAll();
this.wait();
}else {
this.notifyAll(); // 唤醒所有线程
this.wait(); // 锁对象,让当前线程进入等待
System.out.println(name + "取钱,余额不足");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void depositMoney(double money) {
try {
String name = Thread.currentThread().getName();
if(this.money == 0) {
this.money += money;
System.out.println(name + "存款:" + money + "余额:" + this.money);
this.notifyAll(); // 唤醒所有线程
this.wait(); // 锁对象,让当前线程进入等待
}else {
this.notifyAll(); // 唤醒所有线程
this.wait(); // 锁对象,让当前线程进入等待
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
线程池概述
线程池处理Runnable、Callable任务
package com.mochu.d8_ThreadPool;
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 1; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "输出:" + i);
}
}
}
package com.mochu.d8_ThreadPool;
import java.util.concurrent.*;
public class ThreadPoolDemo {
public static void main(String[] args) {
// 定义线程池对象
ExecutorService pool = new ThreadPoolExecutor(3, 5, 5, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
Runnable target = new MyRunnable();
pool.execute(target);
pool.execute(target);
pool.execute(target);
// 立即关闭,即使任务没有完成
pool.shutdownNow();
}
}
Executors的工具类构建线程池对象
定时器
package com.mochu.d9_time;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimeDemo {
public static void main(String[] args) {
// 创建Time对象
Timer timer = new Timer(); // 定时器本身就是单线程
// 调用方法,处理定时任务
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行AAA一次" + new Date());
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}, 0, 2000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行BBB一次" + new Date());
// System.out.println(10 / 0); // 当中间某个任务出现异常,整个定时器都会挂掉
}
}, 0, 2000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行CCC一次" + new Date());
}
}, 0, 2000);
}
}
package com.mochu.d9_time;
import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class TimerDemo02 {
public static void main(String[] args) {
// 创建ScheduledExecutorService线程池,做定时器
ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行输出:AAA " + new Date());
try {
Thread.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 0, 2, TimeUnit.SECONDS);
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行输出:BBB" + new Date());
System.out.println(10 / 0);
}
}, 0, 2, TimeUnit.SECONDS);
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行输出:CCC" + new Date());
}
}, 0, 2, TimeUnit.SECONDS);
}
}
线程并发、并行、线程生命周期的6种状态
网络通信三要素:IP及其类InetAddress、端口、协议
package com.mochu.d1_InetAddressDemo01;
import java.net.InetAddress;
public class InetAddressDemo {
public static void main(String[] args) throws Exception {
// 获取本机地址对象
InetAddress ip1 = InetAddress.getLocalHost();
System.out.println(ip1);
System.out.println(ip1.getHostName());
System.out.println(ip1.getHostAddress());
// 获取域名IP对象
InetAddress ip2 = InetAddress.getByName("www.baidu.com");
System.out.println(ip2);
System.out.println(ip2.getHostName());
System.out.println(ip2.getHostAddress());
// 判断是否互通,单位毫秒
System.out.println(ip2.isReachable(5000));
}
}
UDP快速入门、多发多收消息、广播、组播
package com.mochu.d2_udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class ClientDemo {
public static void main(String[] args) throws Exception {
System.out.println("=======客户端启动=======");
// 创建UDP发送端对象
DatagramSocket socket = new DatagramSocket();
// 创建一个数据包对象封装数据
byte[] buffer = "mochu7: Hello World".getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getLocalHost(), 8888);
// 发送数据
socket.send(packet);
socket.close();
}
}
package com.mochu.d2_udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ServerDemo {
public static void main(String[] args) throws Exception{
System.out.println("=======服务端启动=======");
// 创建服务端(接收端)对象
DatagramSocket socket = new DatagramSocket(8888);
// 创建一个数据包对象接收数据
byte[] buffer = new byte[1024 * 64];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// 接收数据
socket.receive(packet);
// 取出数据
int len = packet.getLength();
String rs = new String(buffer,0, len);
System.out.println("收到了:" + rs);
System.out.println("对方IP:" + packet.getSocketAddress().toString());
System.out.println("对方端口:" + packet.getPort());
socket.close();
}
}
package com.mochu.d2_udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class ClientDemo {
public static void main(String[] args) throws Exception {
System.out.println("=======客户端启动=======");
// 创建UDP发送端对象
DatagramSocket socket = new DatagramSocket();
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请输入:");
String msg = sc.nextLine();
if("exit".equals(msg)) {
System.out.println("退出成功");
socket.close();
break;
}
// 创建一个数据包对象封装数据
byte[] buffer = msg.getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getLocalHost(), 8888);
// 发送数据
socket.send(packet);
}
}
}
package com.mochu.d2_udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ServerDemo {
public static void main(String[] args) throws Exception{
System.out.println("=======服务端启动=======");
// 创建服务端(接收端)对象
DatagramSocket socket = new DatagramSocket(8888);
// 创建一个数据包对象接收数据
byte[] buffer = new byte[1024 * 64];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
// 接收数据
socket.receive(packet);
// 取出数据
int len = packet.getLength();
String rs = new String(buffer,0, len);
System.out.println("收到了:" + rs);
System.out.println("对方IP:" + packet.getSocketAddress().toString());
System.out.println("对方端口:" + packet.getPort());
}
}
}
UDP的接收端为什么可以接收很多发送端的消息?
- 接收端只负责接收数据包,无所谓是哪个发送端的数据包
客户端:DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("255.255.255.255"), 9999);
服务端:DatagramSocket socket = new DatagramSocket(9999);
客户端:DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("224.0.1.1"), 9999);
服务端:
// 创建服务端(接收端)对象
MulticastSocket socket = new MulticastSocket(9999);
// 把当前客户端加入组播组当中
// socket.joinGroup(InetAddress.getByName("224.0.1.1")); // jdk14过时了
socket.joinGroup(new InetSocketAddress(InetAddress.getByName("224.0.1.1"), 9999), NetworkInterface.getByInetAddress(InetAddress.getLocalHost()));
TCP通信快速入门
在Java中只要是使用java.net.Socket
类实现通信,底层即是使用了TCP协议
package com.mochu.d3_Socket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws Exception {
try {
System.out.println("=======服务端启动=======");
// 注册端口
ServerSocket serverSocket = new ServerSocket(7777);
// 调用accpet方法,等待客户端的Socket连接请求,建立Socket通信管道
Socket socket = serverSocket.accept();
// 从Socket管道中得到一个字节输入流
InputStream is = socket.getInputStream();
// 把字节流包装成成缓冲字节输入流进行消息接收
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String msg;
while((msg = br.readLine()) != null) {
System.out.println(socket.getRemoteSocketAddress() + ": " + msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.mochu.d3_Socket;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) {
try {
System.out.println("=======客户端启动=======");
// 创建Socket通信管道,请求有服务端的链接
Socket socket = new Socket("127.0.0.1", 7777);
// 从Socket通信管道中得到一个字节输出流
OutputStream os = socket.getOutputStream();
// 把低级的字节流包装成打印流
PrintStream ps = new PrintStream(os);
// 发送消息
ps.println("TCP链接申请");
ps.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
TCP通信实现、多发多收消息、实现同时接收多个客户端
package com.mochu.d3_Socket;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class ClientDemo {
public static void main(String[] args) {
try {
System.out.println("=======客户端启动=======");
// 创建Socket通信管道,请求有服务端的链接
Socket socket = new Socket("127.0.0.1", 7777);
// 从Socket通信管道中得到一个字节输出流
OutputStream os = socket.getOutputStream();
// 把低级的字节流包装成打印流
PrintStream ps = new PrintStream(os);
// 发送消息
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("请说:");
String msg = sc.nextLine();
ps.println(msg);
ps.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.mochu.d3_Socket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws Exception {
try {
System.out.println("=======服务端启动=======");
// 注册端口
ServerSocket serverSocket = new ServerSocket(7777);
// 调用accpet方法,等待客户端的Socket连接请求,建立Socket通信管道
Socket socket = serverSocket.accept();
// 从Socket管道中得到一个字节输入流
InputStream is = socket.getInputStream();
// 把字节流包装成成缓冲字节输入流进行消息接收
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String msg;
while((msg = br.readLine()) != null) {
System.out.println(socket.getRemoteSocketAddress() + ": " + msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
实现服务端可以同时处理多个客户端消息
package com.mochu.d3_Socket;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class ClientDemo {
public static void main(String[] args) {
try {
System.out.println("=======客户端启动=======");
// 创建Socket通信管道,请求有服务端的链接
Socket socket = new Socket("127.0.0.1", 7777);
// 从Socket通信管道中得到一个字节输出流
OutputStream os = socket.getOutputStream();
// 把低级的字节流包装成打印流
PrintStream ps = new PrintStream(os);
// 发送消息
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("请说:");
String msg = sc.nextLine();
ps.println(msg);
ps.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.mochu.d3_Socket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws Exception {
try {
System.out.println("=======服务端启动=======");
// 注册端口
ServerSocket serverSocket = new ServerSocket(7777);
while (true) {
// 调用accpet方法,等待客户端的Socket连接请求,建立Socket通信管道
Socket socket = serverSocket.accept();
System.out.println(socket.getRemoteSocketAddress() + "上线了");
// 每接收到一个客户端的Socket管道,交给一个独立的子线程负责读取消息
new ServerReaderThread(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.mochu.d3_Socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
public class ServerReaderThread extends Thread{
private Socket socket;
public ServerReaderThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
// 从Socket管道中得到一个字节输入流
InputStream is = socket.getInputStream();
// 把字节流包装成成缓冲字节输入流进行消息接收
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String msg;
while((msg = br.readLine()) != null) {
System.out.println(socket.getRemoteSocketAddress() + ": " + msg);
}
} catch (Exception e) {
System.out.println(socket.getRemoteSocketAddress() + "下线了");
}
}
}
TCP通信模型:线程池优化
package com.mochu.d3_Socket;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class ClientDemo {
public static void main(String[] args) {
try {
System.out.println("=======客户端启动=======");
// 创建Socket通信管道,请求有服务端的链接
Socket socket = new Socket("127.0.0.1", 6666);
// 从Socket通信管道中得到一个字节输出流
OutputStream os = socket.getOutputStream();
// 把低级的字节流包装成打印流
PrintStream ps = new PrintStream(os);
// 发送消息
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("请说:");
String msg = sc.nextLine();
ps.println(msg);
ps.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.mochu.d3_Socket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;
/**
* 实现服务端可以同时处理多个客户端的消息
*/
public class ServerDemo {
// 使用静态变量记住一个线程池对象
private static ExecutorService pool = new ThreadPoolExecutor(3, 5, 6, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) throws Exception {
try {
System.out.println("=======服务端启动=======");
// 注册端口
ServerSocket serverSocket = new ServerSocket(6666);
while (true) {
// 调用accpet方法,等待客户端的Socket连接请求,建立Socket通信管道
Socket socket = serverSocket.accept();
System.out.println(socket.getRemoteSocketAddress() + "上线了");
Runnable target = new ServerReaderRunnable(socket);
pool.execute(target);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.mochu.d3_Socket;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
public class ServerReaderRunnable implements Runnable{
private Socket socket;
public ServerReaderRunnable(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
// 从Socket管道中得到一个字节输入流
InputStream is = socket.getInputStream();
// 把字节流包装成成缓冲字节输入流进行消息接收
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String msg;
while((msg = br.readLine()) != null) {
System.out.println(socket.getRemoteSocketAddress() + ": " + msg);
}
} catch (Exception e) {
System.out.println(socket.getRemoteSocketAddress() + "下线了");
}
}
}
TCP实战案例:即时通信、BS架构模拟
package com.mochu.d3_Socket;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class ClientDemo {
public static void main(String[] args) {
try {
System.out.println("=======客户端启动=======");
// 创建Socket通信管道,请求有服务端的链接
Socket socket = new Socket("127.0.0.1", 9999);
// 创建一个独立的线程专门负责这个客户端的读消息(服务端随时可能转发消息过来)
new ClientReaderThread(socket).start();
// 从Socket通信管道中得到一个字节输出流
OutputStream os = socket.getOutputStream();
// 把低级的字节流包装成打印流
PrintStream ps = new PrintStream(os);
// 发送消息
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("请说:");
String msg = sc.nextLine();
ps.println(msg);
ps.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.mochu.d3_Socket;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
public class ClientReaderThread extends Thread{
private Socket socket;
public ClientReaderThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
// 从Socket管道中得到一个字节输入流
InputStream is = socket.getInputStream();
// 把字节流包装成成缓冲字节输入流进行消息接收
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String msg;
while((msg = br.readLine()) != null) {
System.out.println(socket.getRemoteSocketAddress() + ": " + msg);
}
} catch (Exception e) {
System.out.println(socket.getRemoteSocketAddress() + "下线了");
}
}
}
package com.mochu.d3_Socket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
/**
* 实现服务端可以同时处理多个客户端的消息
*/
public class ServerDemo {
// 定义一个静态的List集合存储当前全部在线的socket管道
public static List<Socket> allOnlineSockets = new ArrayList<>();
public static void main(String[] args) throws Exception {
try {
System.out.println("=======服务端启动=======");
// 注册端口
ServerSocket serverSocket = new ServerSocket(9999);
while (true) {
// 调用accpet方法,等待客户端的Socket连接请求,建立Socket通信管道
Socket socket = serverSocket.accept();
System.out.println(socket.getRemoteSocketAddress() + "上线了");
allOnlineSockets.add(socket); // 上线完成
// 创建一个线程来单独处理这个socket管道
new ServerReaderThread(socket).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.mochu.d3_Socket;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
public class ServerReaderThread extends Thread{
private Socket socket;
public ServerReaderThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
// 从Socket管道中得到一个字节输入流
InputStream is = socket.getInputStream();
// 把字节流包装成成缓冲字节输入流进行消息接收
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String msg;
while((msg = br.readLine()) != null) {
System.out.println(socket.getRemoteSocketAddress() + ": " + msg);
// 把这个消息进行端口转发给全部客户端socket管道
sendMsgToAll(msg);
}
} catch (Exception e) {
System.out.println(socket.getRemoteSocketAddress() + "下线了");
ServerDemo.allOnlineSockets.remove(socket);
}
}
private void sendMsgToAll(String msg) throws Exception {
for (Socket allOnlineSocket : ServerDemo.allOnlineSockets) {
PrintStream ps = new PrintStream(allOnlineSocket.getOutputStream());
ps.println(msg);
ps.flush();
}
}
}
BS架构模拟
package com.mochu.d4_BS;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;
public class BrowseServerDemo {
// 使用静态变量记住一个线程池对象
private static ExecutorService pool = new ThreadPoolExecutor(3, 5, 6, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) throws Exception {
try {
System.out.println("=======服务端启动=======");
// 注册端口
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
// 调用accpet方法,等待客户端的Socket连接请求,建立Socket通信管道
Socket socket = serverSocket.accept();
pool.execute(new ServerReaderRunnable(socket));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.mochu.d4_BS;
import java.io.PrintStream;
import java.net.Socket;
public class ServerReaderRunnable implements Runnable{
private Socket socket;
public ServerReaderRunnable(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
// 浏览器已经与本线程建立乐socket管道
// 响应消息给浏览器显示
PrintStream ps = new PrintStream(socket.getOutputStream());
// 必须响应HTTP格式数据
ps.println("HTTP1.1 200 OK");
ps.println("Content-Type: text/html;charset=UTF-8");
ps.println();
ps.println("<title>mochu7 page</title>");
ps.println("<h1>欢迎来到mochu7 page</h1>");
ps.println("Hello, I'm mochu7777");
ps.close();
}catch (Exception e) {
System.out.println(socket.getRemoteSocketAddress() + "下线了");
}
}
}
单元测试:Junit框架
package com.mochu.d1_JUnit;
public class UserService {
public String loginName(String loginName, String passWord) {
if("admin".equals(loginName) && "123456".equals(passWord)) {
return "登陆成功";
}else {
return "用户名或密码错误";
}
}
public void selectName() {
System.out.println(10/0);
System.out.println("查询全部用户名成功");
}
}
package com.mochu.d1_JUnit;
import org.junit.Assert;
import org.junit.Test;
public class TestUserService {
/**
* 测试方法
*/
@Test
public void testLoginName() {
UserService userService = new UserService();
String rs = userService.loginName("admin", "123456");
// 进行预期结果的正确性测试:断言
Assert.assertEquals("您的登录功能可能出现了bug", "登陆成功", rs);
}
@Test
public void testSelectName(){
UserService userService = new UserService();
userService.selectName();
}
}
package com.mochu.d1_JUnit;
import org.junit.*;
public class TestUserService {
@Before
public void before() {
System.out.println("=======brfore=======");
}
@After
public void after() {
System.out.println("=======after=======");
}
@BeforeClass
public static void beforeClass() {
System.out.println("=======BeforeClass=======");
}
@AfterClass
public static void afterClass() {
System.out.println("=======AfterClass=======");
}
@Test
public void testLoginName() {
UserService userService = new UserService();
String rs = userService.loginName("admin", "123456");
// 进行预期结果的正确性测试:断言
Assert.assertEquals("您的登录功能可能出现了bug", "登陆成功", rs);
}
@Test
public void testSelectName(){
UserService userService = new UserService();
userService.selectName();
}
}
反射概述、获取Class类对象
package com.mochu.d2_Reflect;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
// 调用Class类中的一个静态方法:forName
Class c = Class.forName("com.mochu.d2_Reflect.Student");
System.out.println(c);
// 通过类名.class
Class c1 = Student.class;
System.out.println(c1);
// 通过对象.getClass() 获取
Student stu = new Student();
Class c2 = stu.getClass();
System.out.println(c2);
}
}
反射获取Constructor、Field、Method对象
package com.mochu.d3_Reflect_Constructor;
import org.junit.Test;
import java.lang.reflect.Constructor;
public class TestStudent {
@Test
public void getContructors() {
// 获取类对象
Class c = Student.class;
// 获取类中的构造器,只能获取公开的构造器
Constructor[] constructors = c.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
}
}
@Test
public void getDeclareConstructors() {
// 获取类对象
Class c = Student.class;
// 获取类中的所有构造器
Constructor[] constructors = c.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
}
}
@Test
public void getConstructor() throws Exception {
// 获取类对象
Class c = Student.class;
// 获取类中的某一个构造器,只能拿public
Constructor constructor = c.getConstructor();
System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
}
@Test
public void getDeclareConstructor() throws Exception {
// 获取类对象
Class c = Student.class;
// 获取类中的任何一个构造器
Constructor constructor = c.getDeclaredConstructor();
System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
Constructor constructor1 = c.getDeclaredConstructor(String.class, int.class);
System.out.println(constructor1.getName() + "===>" + constructor1.getParameterCount());
}
}
package com.mochu.d3_Reflect_Constructor;
import org.junit.Test;
import java.lang.reflect.Constructor;
public class TestStudent {
@Test
public void getDeclareConstructor() throws Exception {
// 获取类对象
Class c = Student.class;
// 获取类中的任何一个构造器
Constructor constructor = c.getDeclaredConstructor();
System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
// 如果遇到了私有的构造器,可以暴力反射
constructor.setAccessible(true);
Student s = (Student) constructor.newInstance();
System.out.println(s);
Constructor constructor1 = c.getDeclaredConstructor(String.class, int.class);
System.out.println(constructor1.getName() + "===>" + constructor1.getParameterCount());
Student s1 = (Student) constructor1.newInstance("mochu7", 22);
System.out.println(s1);
}
}
package com.mochu.d4_Reflect_Field;
import org.junit.Test;
import java.lang.reflect.Field;
public class FieldDemo {
@Test
public void getDeclareedFields() {
// 创建class对象
Class c = Student.class;
// 获取全部成员变量
Field[] fileds = c.getDeclaredFields();
for (Field filed : fileds) {
System.out.println(filed.getName() + " ===> " + filed.getType());
}
}
@Test
public void getDeclareedField() throws Exception {
// 创建class对象
Class c = Student.class;
// 根据名称定位某个成员变量
Field filed = c.getDeclaredField("name");
// System.out.println(filed.getName() + " ==> " + filed.getType());
// 成员变量暴力赋值
filed.setAccessible(true);
Student s = new Student();
filed.set(s, "mochu7");
System.out.println(s);
String name = (String) filed.get(s);
System.out.println(name);
}
}
package com.mochu.d5_Reflect_Method;
public class Dog {
private String name;
public Dog(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dog(String name) {
this.name = name;
}
public void run() {
System.out.println("Dog running....");
}
private void eat() {
System.out.println("Dog eating...");
}
private String eat(String name) {
System.out.println("Dog eat " + name);
return "funny eat";
}
public static void inAddr() {
System.out.println("Singal dog~ Singal dog~");
}
}
package com.mochu.d5_Reflect_Method;
import org.junit.Test;
import java.lang.reflect.Method;
public class MethodDemo {
@Test
public void getDeclearedMethods() {
Class c = Dog.class;
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName() + " ==> " + method.getReturnType() + " ==> " + method.getParameterCount());
}
}
@Test
public void getDeclearedMethod() throws Exception {
Class c = Dog.class;
Method method = c.getDeclaredMethod("eat");
Method method2 = c.getDeclaredMethod("eat", String.class);
// 触发方法执行
method.setAccessible(true);
Dog d = new Dog();
method.invoke(d);
method2.setAccessible(true);
method2.invoke(d, "bone");
}
}
反射的作用:绕过编译阶段,做企业级通用框架
package com.mochu.d6_Reflect_Genericity;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
// 反射实现泛型擦除,加入其它类型的数据
ArrayList<String> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
System.out.println(list1.getClass());
System.out.println(list2.getClass());
System.out.println(list1.getClass() == list2.getClass());
System.out.println("----------------------------");
ArrayList<String> list3 = new ArrayList<>();
list3.add("mochu7");
list3.add("Slevin");
Class c = list3.getClass();
Method add = c.getDeclaredMethod("add", Object.class);
boolean rs = (boolean) add.invoke(list3, 77);
System.out.println(rs);
System.out.println(list3);
// 突破泛型约束的另一种方法
ArrayList list4 = list3;
list4.add(127);
list4.add(false);
System.out.println(list3);
}
}
package com.mochu.d7_Reflect_Framework;
/**
* 提供一个通用框架,支持保存所有对象信息
*/
public class ReflectDemo {
public static void main(String[] args) throws Exception{
Student s = new Student();
s.setName("mochu7");
s.setClassName("21345");
s.setAge(18);
s.setHobby("睡觉");
s.setSex('男');
MybatisUtil.save(s);
Teacher t = new Teacher();
t.setName("Slevin");
t.setSex('男');
t.setSalary(10000.0);
MybatisUtil.save(t);
}
}
package com.mochu.d7_Reflect_Framework;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
public class MybatisUtil {
/**
* 保存任意类对象
* @param obj
*/
public static void save(Object obj) throws Exception {
try(PrintStream ps = new PrintStream(new FileOutputStream("JUnit-Reflect-Annotation-Proxy-App/src/data.txt", true));) {
// 读取这个类的全部成员变量,使用反射
Class c = obj.getClass();
ps.println("===============" + c.getSimpleName() + "===============");
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
String name = field.getName();
// 提取本成员变量在obj对象中的值
field.setAccessible(true);
String value = field.get(obj) + "";
ps.println(name + "=" + value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
注解概述、自定义注解、元注解、注解解释
package com.mochu.d8_Annotaion;
import org.junit.Test;
import java.lang.reflect.Method;
import java.util.Arrays;
public class AnnoationDemo {
@Test
public void parseClass() throws Exception {
Class c = BookStore.class;
Method m = c.getDeclaredMethod("test");
if(m.isAnnotationPresent(Book.class)) {
// 获取该注解对象
Book book = (Book) m.getDeclaredAnnotation(Book.class);
System.out.println(book.value());
System.out.println(book.price());
System.out.println(Arrays.toString(book.author()));
}
}
}
package com.mochu.d8_Annotaion;
@Book(value = "《中国哲学史》", price = 45.9, author = {"test", "test1"})
public class BookStore {
@Book(value = "《认知驱动》", price = 24.5, author = {"a1", "a2"})
public void test() {
}
}
package com.mochu.d8_Annotaion;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Book {
String value();
double price() default 100;
String[] author();
}
注解的应用:模拟JUnit框架
package com.mochu.d8_Annotaion;
import java.lang.reflect.Method;
public class AnnoationDemo {
@MyTest
public void test1() {
System.out.println("===test1===");
}
public void test2() {
System.out.println("===test2===");
}
@MyTest
public void test3(){
System.out.println("===test3===");
}
public static void main(String[] args) throws Exception {
AnnoationDemo a1 = new AnnoationDemo();
Class c = AnnoationDemo.class;
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
if(method.isAnnotationPresent(MyTest.class)){
method.invoke(a1);
}
}
}
}
package com.mochu.d8_Annotaion;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
}
动态代理
代理主要是对对象的行为额外做一些辅助操作
package com.mochu.d9_Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Objects;
public class StarAgent {
public static Skill getProxy(Star obj) {
// newProxyInstance(ClassLoader loader,
// Class<?>[] interfaces,
// InvocationHandler h) {
// Objects.requireNonNull(h);
return (Skill) Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("触发代理对象");
Object rs = method.invoke(obj, args);
return rs;
}
});
}
}
package com.mochu.d10_Proxy2;
public class Test {
public static void main(String[] args) {
UserService userService = ProxyUtil.getProxy(new UserServiceImpl());
System.out.println(userService.login("admin", "123456"));
userService.deleteUsers();
userService.selectUsers();
userService.deleteById(1024);
}
}
package com.mochu.d10_Proxy2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil {
public static <T> T getProxy(T obj) {
return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTime = System.currentTimeMillis();
Object rs = method.invoke(obj, args);
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + "方法耗时:" + (endTime - startTime) / 1000.0);
return rs;
}
});
}
}
package com.mochu.d10_Proxy2;
public class UserServiceImpl implements UserService{
@Override
public String login(String loginName, String passWord) {
String rs = "用户名或者密码错误";
if("admin".equals(loginName) && "123456".equals(passWord)) {
rs = "登录成功";
}
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
return rs;
}
@Override
public void deleteUsers() {
try {
System.out.println("正在删除用户中.......");
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String selectUsers() {
String rs = "正在查询10000个用户";
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
return rs;
}
@Override
public void deleteById(int id) {
try {
System.out.println("根据用户身份证号" + id + ",删除了他");
Thread.sleep(1200);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.mochu.d10_Proxy2;
public interface UserService {
String login(String loginName, String passWord);
void deleteUsers();
String selectUsers();
void deleteById(int id);
}
XML、XML创建
XML文档约束
XML文件解析技术:Dom4j
- https://dom4j.github.io/
package com.mochu.d1_dom4j;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.io.InputStream;
public class Dom4jDemo {
@Test
public void parseXMLDdata() throws Exception {
// 创建一个Dom4j的解析器对象
SAXReader saxReader = new SAXReader();
InputStream is = Dom4jDemo.class.getResourceAsStream("/data.xml");
Document document = saxReader.read(is);
Element root = document.getRootElement();
System.out.println(root.getName());
}
}
package com.mochu.d1_dom4j;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class Dom4jDemo {
@Test
public void parseXMLDdata() throws Exception {
// 创建一个Dom4j的解析器对象
SAXReader saxReader = new SAXReader();
InputStream is = Dom4jDemo.class.getResourceAsStream("/data.xml");
Document document = saxReader.read(is);
Element root = document.getRootElement();
System.out.println(root.getName());
// 获取根元素下的全部子元素
List<Element> sonEles = root.elements();
for (Element sonEle : sonEles) {
System.out.println(sonEle.getName());
}
// 获取某个子元素
Element nameEle = root.element("name");
System.out.println(nameEle.getName());
// 获取某个子元素对象
System.out.println(nameEle.getText());
// 获取属性值
Attribute idAttr = nameEle.attribute("id");
System.out.println(idAttr.getName() + " => " + idAttr.getValue());
System.out.println(nameEle.attributeValue("id"));
}
}
package com.mochu.d1_dom4j;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class Dom4jDemo {
@Test
public void parseXMLDdata() throws Exception {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(Dom4jDemo.class.getResourceAsStream("/data.xml"));
Element root = document.getRootElement();
List<Element> contactEles = root.elements("contact");
List<Contact> contacts = new ArrayList<>();
for (Element contactEle : contactEles) {
Contact contact = new Contact();
contact.setId(Integer.valueOf(contactEle.attributeValue("id")));
contact.setName(contactEle.elementTextTrim("name"));
contact.setGender(contactEle.elementTextTrim("gender").charAt(0));
contact.setMail(contactEle.elementTextTrim("mail"));
contacts.add(contact);
}
for (Contact contact : contacts) {
System.out.println(contact);
}
}
}
XML文件的数据检索技术:XPath
- http://www.java2s.com/Code/Jar/j/Downloadjaxen112jar.htm
package com.mochu.d2_Xpath;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.List;
public class XpathDemo {
// 绝对路径
@Test
public void parse01() throws Exception{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/data.xml"));
List<Node> nameNodes = document.selectNodes("/contactList/contact/name");
for (Node nameNode : nameNodes) {
Element nameEle = (Element) nameNode;
System.out.println(nameEle.getTextTrim());
}
}
// 相对路径
@Test
public void parse02() throws Exception{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/data.xml"));
Element root = document.getRootElement();
List<Node> nameNodes = root.selectNodes("./contact/name");
for (Node nameNode : nameNodes) {
Element nameEle = (Element) nameNode;
System.out.println(nameEle.getTextTrim());
}
}
// 全文检索
@Test
public void parse03() throws Exception{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/data.xml"));
List<Node> nameNodes = document.selectNodes("//name");
for (Node nameNode : nameNodes) {
Element nameEle = (Element) nameNode;
System.out.println(nameEle.getTextTrim());
}
}
// 属性查找
@Test
public void parse04() throws Exception{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/data.xml"));
List<Node> nodes = document.selectNodes("//@id");
for (Node node : nodes) {
Attribute attr = (Attribute) node;
System.out.println(attr.getName() + " => " + attr.getValue());
}
}
}
补充知识:工厂模式、装饰模式
package com.mochu.d3_FactoryPattern;
public class Factory {
// 定义一个方法,创建对象返回
public static Computer createComputer(String info) {
switch (info){
case "Mac":
Computer c = new Mac();
c.setName("Mac15 Pro");
c.setPrice(15999);
return c;
case "Alien":
Computer c1 = new Alien();
c1.setName("Alien X17");
c1.setPrice(27999);
return c1;
default:
return null;
}
}
}
package com.mochu.d3_FactoryPattern;
public class FactoryDemo {
public static void main(String[] args) {
Computer c = Factory.createComputer("Alien");
c.start();
Computer c1 = Factory.createComputer("Mac");
c1.start();
}
}
package com.mochu.d4_decorator_pattern;
public abstract class InputStream {
public abstract int read();
public abstract int read(byte[] buffer);
}
package com.mochu.d4_decorator_pattern;
import java.util.Arrays;
public class FileInputStream extends InputStream{
@Override
public int read() {
System.out.println("读取了一个字节a");
return 97;
}
@Override
public int read(byte[] buffer) {
buffer[0] = 97;
buffer[1] = 98;
buffer[2] = 99;
System.out.println("读取了一个字节数组:" + Arrays.toString(buffer));
return 0;
}
}
package com.mochu.d4_decorator_pattern;
// 装饰类,扩展原始类的功能
public class BufferedInputStream extends InputStream{
private InputStream is;
public BufferedInputStream (InputStream is) {
this.is = is;
}
@Override
public int read() {
System.out.println("提供8KB缓冲区,提高数据性能");
return is.read();
}
@Override
public int read(byte[] buffer) {
System.out.println("提供8KB缓冲区,提高数据性能");
return is.read(buffer);
}
}
package com.mochu.d4_decorator_pattern;
public class DecoratorPattern {
public static void main(String[] args) {
InputStream is = new BufferedInputStream(new FileInputStream());
System.out.println(is.read());
System.out.println(is.read(new byte[3]));
}
}