黑马程序员Java教程学习笔记(六)

发布时间:2025-12-09 19:23:32 浏览次数:4

学习视频: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类提供了诸如:定位文件、获取文件本身的信息、删除文件、创建文件(文件夹)等功能
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,也必须执行完这里才行,开发中不建议这里returnSystem.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 {@Overridepublic 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:NIOFiles.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{@Overridepublic 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{@Overridepublic 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() {@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println("子线程1输出:" + i);}}};// 简化new Thread(new Runnable() {@Overridepublic 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接口,声明线程执行完毕之后的返回类型@Overridepublic 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);}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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{@Overridepublic 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() {@Overridepublic 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() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "执行BBB一次" + new Date());// System.out.println(10 / 0); // 当中间某个任务出现异常,整个定时器都会挂掉}}, 0, 2000);timer.schedule(new TimerTask() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "执行输出:BBB" + new Date());System.out.println(10 / 0);}}, 0, 2, TimeUnit.SECONDS);pool.scheduleAtFixedRate(new TimerTask() {@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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 {/*** 测试方法*/@Testpublic void testLoginName() {UserService userService = new UserService();String rs = userService.loginName("admin", "123456");// 进行预期结果的正确性测试:断言Assert.assertEquals("您的登录功能可能出现了bug", "登陆成功", rs);}@Testpublic void testSelectName(){UserService userService = new UserService();userService.selectName();}}



package com.mochu.d1_JUnit;import org.junit.*;public class TestUserService {@Beforepublic void before() {System.out.println("=======brfore=======");}@Afterpublic void after() {System.out.println("=======after=======");}@BeforeClasspublic static void beforeClass() {System.out.println("=======BeforeClass=======");}@AfterClasspublic static void afterClass() {System.out.println("=======AfterClass=======");}@Testpublic void testLoginName() {UserService userService = new UserService();String rs = userService.loginName("admin", "123456");// 进行预期结果的正确性测试:断言Assert.assertEquals("您的登录功能可能出现了bug", "登陆成功", rs);}@Testpublic 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类中的一个静态方法:forNameClass c = Class.forName("com.mochu.d2_Reflect.Student");System.out.println(c);// 通过类名.classClass 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 {@Testpublic void getContructors() {// 获取类对象Class c = Student.class;// 获取类中的构造器,只能获取公开的构造器Constructor[] constructors = c.getConstructors();for (Constructor constructor : constructors) {System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());}}@Testpublic void getDeclareConstructors() {// 获取类对象Class c = Student.class;// 获取类中的所有构造器Constructor[] constructors = c.getDeclaredConstructors();for (Constructor constructor : constructors) {System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());}}@Testpublic void getConstructor() throws Exception {// 获取类对象Class c = Student.class;// 获取类中的某一个构造器,只能拿publicConstructor constructor = c.getConstructor();System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());}@Testpublic 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 {@Testpublic 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 {@Testpublic void getDeclareedFields() {// 创建class对象Class c = Student.class;// 获取全部成员变量Field[] fileds = c.getDeclaredFields();for (Field filed : fileds) {System.out.println(filed.getName() + " ===> " + filed.getType());}}@Testpublic 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 {@Testpublic void getDeclearedMethods() {Class c = Dog.class;Method[] methods = c.getDeclaredMethods();for (Method method : methods) {System.out.println(method.getName() + " ==> " + method.getReturnType() + " ==> " + method.getParameterCount());}}@Testpublic 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 {@Testpublic 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 {@MyTestpublic void test1() {System.out.println("===test1===");}public void test2() {System.out.println("===test2===");}@MyTestpublic 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() {@Overridepublic 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() {@Overridepublic 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{@Overridepublic 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;}@Overridepublic void deleteUsers() {try {System.out.println("正在删除用户中.......");Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}}@Overridepublic String selectUsers() {String rs = "正在查询10000个用户";try {Thread.sleep(3000);} catch (Exception e) {e.printStackTrace();}return rs;}@Overridepublic 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 {@Testpublic 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 {@Testpublic 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 {@Testpublic 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 {// 绝对路径@Testpublic 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());}}// 相对路径@Testpublic 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());}}// 全文检索@Testpublic 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());}}// 属性查找@Testpublic 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{@Overridepublic int read() {System.out.println("读取了一个字节a");return 97;}@Overridepublic 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;}@Overridepublic int read() {System.out.println("提供8KB缓冲区,提高数据性能");return is.read();}@Overridepublic 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]));}}


需要做网站?需要网络推广?欢迎咨询客户经理 13272073477