线程池 Lambda表达式(第7天)
一 线程池
1.线程间通信概念:
多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同(需要协作)
2.为什么要处理线程间通信:
多个线程并发执行时, 在默认情况下CPU是随机切换线程的,当我们需要多个线程来共同完成一件任务,并且我们
希望他们有规律的执行, 那么多线程之间需要一些协调通信,以此来帮我们达到多线程共同操作一份数据。
3.如何保证线程间通信有效利用资源:
多个线程在处理同一个资源,并且任务不同时,需要线程通信来帮助解决线程之间对同一个变量的使用或操作。就
是多个线程在操作同一份数据时, 避免对同一共享变量的争夺。也就是我们需要通过一定的手段使各个线程能有效
的利用资源。而这种手段即—— 等待唤醒机制
4.等待唤醒机制:
这是多个线程间的一种协作机制。谈到线程我们经常想到的是线程间的竞争(race),比如去争夺锁,但这并不是故事的全部,线程间也会有协作机制。就好比在公司里你和你的同事们,你们可能存在在晋升时的竞争,但更多时候你们更多是一起合作以完成某些任务。就是在一个线程进行了规定操作后,就进入等待状态(wait()), 等待其他线程执行完他们的指定代码过后 再将其唤(notify());在有多个线程进行等待时, 如果需要,可以使用 notifyAll()来唤醒所有的等待线程。
wait/notify 就是线程间的一种协作机制
PS:
如果能获取锁,线程就从 WAITING 状态变成 RUNNABLE 状态;否则,从 wait set 出来,又进入 entry set,线程就从 WAITING 状态又变成 BLOCKED 状态,等待唤醒机制就是用于解决线程间通信的问题
4程序池
线程池概念:其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,
无需反复创建线程而消耗过多资源。
5线程池的好处:
·降低资源消耗
·提高响应速度
·提高线程的课管理性
6 Java.util.concurrent.Executors类: 线程池工厂类,用于管理线程池
·静态方法:
static ExecutorService newFixedThreadPool(int nThreads): 创建固定数量线程的线程池(常用)
java.util.concurrent.ExecutorService接口: 真正执行任务的线程池服务
·成员方法:
Future submit(Runnable task): 提交一个Runnable任务
void shutdown(): 通知线程执行完任务后关闭. 如不调此方法, 则线程执行完任务后仍在运行以便重复使用
7线程池的创建和使用步骤:
· 使用Executors的静态方法 newFixedThreadPool(intnThreads) 创建线程池ExecutorService
· 创建一个任务类, 实现Runnable接口, 重写run()方法
· 调用ExecutorService对象的 submit(Runnable task) 方法, 传递任务给线程池, 执行任务
·调用ExecutorService对象的 shutdown() 方法, 销毁线程池 (不建议执行)
二.Lambda表达式
1.函数式: 在数学中, 函数就是有输入量, 输出量的一套计算方案, 也就是"拿什么东西做什么事情"
面向对象: 强调"用哪个对象的哪个方法"来做事 (注重语法形式) 函数式: 强调做事 (不关心用什么对象, 重写什么方法),简写实现接口的匿名内部类,
函数式编程的好处: 简化代码编写
2.Lambda的标准格式
Lambda表达式的3个部分:
1>. 一些参数 () 接口中抽象方法的参数列表. 没参数就空着; 有参数就写, 多个参数用逗号分隔
2>. 一个箭头 -> 将参数传递给方法体
3>. 一段代码 {} 重写接口抽象方法的方法体
格式: // 写成一行 (参数列表) -> {一些重写方法的代码} // 写成多行 (参数列表) -> { 一些重写方法的代码 }
3.Lambda的省略格式和使用前提
省略原则:可推导的都可省略 (凡是能根据前后代码能猜测出来的代码, 都可以省略不写) 可以省略的部分:
1>. (参数列表): 参数"类型"可以省略
2>. (参数列表): 如果参数只有1个, 则"类型"和"小括号"都可以省略a -> sout(a)
3>. {一些代码}: 如果只有一条代码,则"大括号","return", "分号"都可以"一起省略"
4*函数式接口: 函数式接口"有且仅有一个抽象方法" 但函数式接口对于哪些方法算作抽象方法有特殊规定:
1>. 有方法体的方法"不算作"抽象方法, 如默认方法, 静态方法, 私有方法
2>. 抽象方法与java.lang.Object类中的方法定义相同的, 也"不算作"抽象方法因为任何实现本接口的实现类, 都会直接或间接继承java.lang.Object类的public的方法, 所以在创建 实现类时其实不用重写该抽象方法, 也就不算作抽象方法
5Lambda表达式的使用前提:
1>. Lambda只能用于接口, 且"接口中有且仅有一个抽象方法"(也称为"函数式接口") 普通类, 抽象类不能用
2>. 使用Lambda必须具有上下文推断 方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例 (简而言之: 作为参数类型的接口, 必须是函数式接口)
File类、递归(第8天)
一 File类
1.1概述: 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作.注 : File :把路径名用String字符串的形式表现了出来.
1.2 构造方法
public File(Stringpathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
public File(Stringparent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。
File(File parent,String child) :从父抽象路径名和子路径名字符串创建新的 File实例。
1.3问题汇总:
1. 什么是绝对路径?回答: 从盘符开始,路径一直到所选择的文件名称.
2. 什么是相对路径?回答: 所选择的文件名称或者文件名相对于上一个文件夹名. 这个所选择的文件名称就是相对路径.
3. 什么是父子路径?回答: 在一个完整路径中,从哪里截取,在完整路径中截取的前半段就是父路径,截取的后半段就是子路径.
1.4注意事项:
1. 文件返回的大小,用字节数表示(int 数字). 文件有具体的大小,文件夹没有,所以返回的结果是0(不能获取目录的大小)
2. 一个File对象代表硬盘中实际存在的一个文件或者目录.
3. 无论该路径下是否存在文件或者目录,都不影响File对象的创建
1.5常用方法
·获取功能的方法:
File getAbsoluteFile() 返回此抽象路径名的绝对路径名形式。
String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。
String getName() 返回由此抽象路径名表示的文件或目录的名称。
String getParent() 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。
File getParentFile() 返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。
String getPath()将此抽象路径名转换为一个路径名字符串。
·判断功能的方法 :
public boolean exists() :此File表示的文件或目录是否实际存在。
public boolean isDirectory() :此File表示的是否为目录。
public boolean isFile() :此File表示的是否为文件(不要与文件夹混淆,只是文件)。
·创建删除功能的方法:
public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。public boolean delete() :删除由此File表示的文件或目录,删除目录里必须没有文件,才能删除。
public boolean mkdir() :创建由此File表示的目录
public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录
1.6目录的遍历
public String[ ] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
public File[ ] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。
区别在于: list只打印当前的文件或文件夹名称listFiles打印完整的路径名称,从盘符开始.
二 递归
2.1 概述:指在当前方法内调用自己的这种现象.
递归的使用前提:调用方法时, 方法的主体不变, 但每次传递的参数值不同, 可以使用递归代码示例:
2.2 递归累和:
递归求和练习题:解题思路:根据递归的思想,找出问题的规律,从而根据规律总结出解决问题的公式,利用公式把参数套进去.需求: 求5~1的和 5+4+3+2+1求5~1的和 = 5 + 4~1的和4~1的和 =4 + 3~1的和3~1的和 = 3 + 2~1的和2~1的和 = 2 + 1~1的和1~1的和 = 1
n不是1时公式:求n~1的和 = n +(n-1)~1的和n是1时的公式:求1~1的和 = 1;
求5~1的和 = 5 + 104~1的和 = 4 + 63~1的和 = 3 + 32~1的和 = 2 + 11~1的和 = 1
把要解决的问题定义为方法:求5~1的和求4~1的和求3~1的和求2~1的和求1~1的和.
求n~1的和 -> 要定义的方法返回值类型: int 和参数列表: int n
public static int sum(int n) {
if (n == 1) {// 公式: = 1return 1;
} else {
// 公式:
n + (n-1)~1的和return n + sum(n-1);}
}
2.3问题汇总:
1. 什么是绝对路径?回答: 从盘符开始,路径一直到所选择的文件名称.
2. 什么是相对路径?回答: 所选择的文件名称或者文件名相对于上一个文件夹名. 这个所选择的文件名称就是相对路径.
3. 什么是子路径?. 什么是父路径?回答: 在一个完整路径中,从哪里截取,在完整路径中截取的前半段就是父路径,截取的后半段就是子路径.
目录的遍历public String[] list() : 返回一个String数组,表示该File目录中的所有子文件或目录。public File[] listFiles() : 返回一个File数组,表示该File目录中的所有的子文件或目录。
2.4递归的分类:
递归分为两种,直接递归和间接递归。 直接递归称为方法自身调用自己。 间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。
注意事项:
递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。 在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。 构造方法,禁止递归
3.2 文件过滤器优化
3.21 java.io.FileFilter 是一个接口,是File的过滤器。 该接口的对象可以传递给File类的
listFiles(File Filter) 作为参数, 接口中只有一个方法。
boolean accept(File pathname) :测试pathname是否应该包含在当前File目录中,符合则返回true。
分析:
1. 接口作为参数,需要传递子类对象,重写其中方法。我们选择匿名内部类方式,比较简单。
2. accept 方法,参数为File,表示当前File下所有的子文件和子目录。保留住则返回true,过滤掉则返回 false。保留规则: 1. 要么是.java文件。 2. 要么是目录,用于继续遍历。 3. 通过过滤器的作用, listFiles(FileFilter) 返回的数组元素中,子文件对象都是符合条件的,可以直接打印。
代码实现:
[mw_shl_code=applescript,true]public class DiGuiDemo4 {
public static void main(String[] args) {
File dir = new File("D:\\aaa");
printDir2(dir); }
public static void printDir2(File dir) {
// 匿名内部类方式,创建过滤器子类对象
File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) { return pathname.getName().endsWith(".java")||pathname.isDirectory(); } });
// 循环打印
for (File file : files) {
if (file.isFile()) {
System.out.println("文件名:" + file.getAbsolutePath());
} else {
printDir2(file); } } } }
3.3 Lambda优化
分析: FileFilter 是只有一个方法的接口,因此可以用lambda表达式简写。
IO流(第9,10天)
IO体系框架
一.分类
1.按照流向分类:
1>输入流:字节输入流 InputStream(抽象类) FileInputStream , ObjectInputStream(对象输入流)
字符输入流 Reader(抽象类) FileReader, BufferedReader, InputStreamReader(将字 节输入流转换成字符输入流)
2>输出流:字节输出流 OutputStream(抽象类) FileOutputStream , ObjectOutputStream(对象输出流)
字符输出流 Writer(抽象类) FileWriter, BufferedWriter(高效输入流,包装类), OutputStreamWriter(字节流输出流转出字符输出流),PrintWrirer(打印流)
2.按照数据类型分类:
1>字节流:字节输入流 InputStream(抽象类) FileInputStream , ObjectInputStream(对象输入流)
字节输出流OutputStream(抽象类) FileOutputStream ,ObjectOutputStream(对象输出流)
2>字符流:字符输入流 Reader(抽象类)FileReader, BufferedReader, OutputStreamReader(将字节输入流转换成字符输入流)
字符输出流 Writer(抽象类) FileWriter, BufferedWriter(高效输入流,包装类),,包装类 OutputStreamWriter(字节流输出流转出字符输出流), PrintWrirer(打印流)
注意:有一些文件底层就是字节,例如图片和视频,二进制文件只能使用字节进行复制(使用windows自带的记事本打开读不懂的文本文件的复制,即可使用字符流,也可使用字节流)
二.介绍每个IO流的特性
①字节输入流
1>InputStream(抽象类):
构造方法:InputStream()
普通方法:
abstract int read():一次读取一个字节;
int read(byte[] b):一次读一个字符数组;返回读取的字节长度
int read(byte[] b,int off, int len);将输入流中最多len个数据字节读入byte数组,返回读取长度;
2>FileInputStream(InputStream的子类):
构造方法:
FileInputStream(File file)
FileInputStream(String name)如果文件存在则会清空数据
普通方法:和InputStream一样;
3> ObjectInputStream(对象输入流,InputStream的子类,包装类,序列化流):
构造方法:
ObjectInputStream();
ObjectInputStream(InputStream in);
普通方法:
readObject();一般就只定义一个对象,读取的时候只读取一次,因为结束打印完,是通过报错EOFException终止循环,(方法不太理想,所以只定义一个对象,只读取一次)
注意:要实现Serializable:序列号,是一个标识接口,只起标识作用,没有方法
当一个类的对象需要IO流的进行读写的时候,这个类必须实现该接口.
4>BufferedInputStream(高效字节输入换冲流)
构造方法:
BufferedInputStream(InputStream?in): 使用基本流创建一个缓冲字节输入流
BufferedInputStream(InputStream?in, int size): 使用基本流创建一个缓冲字节输入流, 设置缓冲区大小
②字节输出流:
1>OutputStream(抽象类)
构造方法:
OutputStream()
普通方法:
void close() 关闭此输出流并释放与此流有关的所有系统资源。
void flush() 刷新此输出流并强制写出所有缓冲的输出字节。
void write(byte[] b) 一次写出一个指定的字节数组;
void write(byte[] b, int off, int len) 将指定 byte 数组中从off 开始的 len 个字节写入此输出流。
abstract void write(int b) 将指定的字节写入此输出流。
2>FileOutputStream(OutputStream的子类);
构造方法:
FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(File file, boolean append),可叠加
FileOutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流。
FileOutputStream(String name, boolean append) 可叠加
普通方法:
void write(byte[] b) 一次写入一个字节数组
void write(byte[] b, int off, int len) 将指定 byte 数组中从off 开始的 len 个字节写入此文件输出流。
void write(int b) 将指定字节写入此文件输出流。
3>ObjectOutputStream(对象输入流,OutputStream的子类):只能将支持 java.io.Serializable 接口的对象写入流中。
使用 ObjectInputStream 读取(重构)对象
构造方法:
ObjectOutputStream()
ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream
普通方法
void writeObject(Object obj) 将指定的对象写入 ObjectOutputStream。
注意:要实现Serializable:序列号,是一个标识接口,只起标识作用,没有方法
当一个类的对象需要IO流的进行读写的时候,这个类必须实现该接口.
序列化操作
1. 一个对象要想序列化,必须满足两个条件:
1>该类必须实现java.io.Serializable 接口, Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出 NotSerializableException 。 该类的所有属性必须是可序列化的。
2>如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用 transient 关键字修饰。
3>如果要将集合序列化,那么集合中存储的对象也必须实现序列化
2.transient瞬态关键字: 避免属性序列化
static修饰的成员变量属于类不属于对象, 所以不能序列化 transient 修饰的成员变量, 不能被序列化.
如果对象的某个属性不希望被序列化, 可以使用transient修饰, 这样就不会被对象流写到文件中
3.InvalidClassException异常: 原因和解决方案
serialVersionUID序列号的作用: 序列化操作时, 会根据类生成一个默认的 serialVersionUID 属性, 写入到文件中. 该版本号是根据类中成员计算出来的一个数值. 当类的成员发生改变时, 序列版本号也会发生变化 当代码中的类和读取的对象序列版本号不一致时, 就会抛出InvalidClassException
为了避免这种问题, 我们可以手动写死这个序列号, 这样无论成员如何变化, 序列版本号都是一样的
4>BufferedOutputStream(高效的字节输出流,包装流)
构造方法
BufferedOutputStream(OutputStream out)创建一个新的字节高效缓冲流,已将数据写入指定的底层的输出流
BufferedOutputStream(OutputStream out,int size)使用基本流创建一个缓冲字节输出流, 设置缓冲区大小,int size设置
5>PrintStream(打印流):可以定义编码表
构造方法:
PrintStream(File file) 使用指定文件创建不具有自动行刷新的新 PrintWriter。
PrintStream(File file, String csn)创建具有指定文件和字符集且不带自动刷行新的新 PrintStream。
PrintStream(String fileName) 创建具有指定文件名称且不带自动行刷新的新 PrintWriter。
PrintStream(String fileName, String csn) 创建具有指定文件名称和字符集且不带自动行刷新的新 PrintStream。
PrintStream(OutputStream out) 根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。
PrintStream(OutputStream out, boolean autoFlush) 通过现有的 OutputStream 创建新的 PrintStream。
PrintStream(Writer out) 创建不带自动行刷新的新 PrintWriter。
PrintStream(Writer out, boolean autoFlush) 创建新 PrintWriter。 带自动刷新.
普通方法:
void println(Object x) 打印 Object,然后终止该行。
void print(Object obj) 打印对象。
PrintStream特点: 1. 只有输出流, 没有输入流 2.PrintStream永远不会抛出IOException 3. 有特殊方法 print(), println(), 可以输出任意类型的值
注意事项: 如果用 write() 方法, 会查编码表
如果用 print(),println(), 则原样输出
java.lang.System类: // 静态方法 static void setOut(PrintStreamout): 设置System.out的输出目的地为参数的打印流
③字符输入流:
1>Reader(用于读取字符流的抽象类)
普通方法
int read() 读取单个字符。
int read(char[] cbuf) 将字符读入数组。
abstract int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。
2>FileReader(用来读取字符文件的便捷类,Reader的子类)
构造方法:
FileReader(File file) 在给定从中读取数据的 File 的情况下创建一个新 FileReader。
FileReader(String fileName) 在给定从中读取数据的文件名的情况下创建一个新 FileReader。
普通方法:和Reader的一样;
3> BufferedReader(高效输入流) 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。(包装流)
构造方法:
BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader?in, int size): 使用基本流创建一个缓冲字符输入流, 设置缓冲区大小
普通方法:
String readLine();一次读取一行;当不等于null的时候;
4>OutputStreamReader:(将字节输入流转换成字符输入流),可以定义编码表(包装流)
构造方法:
InputStreamReader(InputStream in) 将字节输入流转换成字符输入流
InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集(编码表)的 InputStreamReader。
④字符输出流
1>Writer(抽象类)
普通方法:
void write(char[] cbuf) 写入字符数组。
abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。
void write(int c) 写入单个字符。
void write(String str) 写入字符串。
void write(String str, int off, int len) 写入字符串的某一部分。
abstract void close() 关闭此流,但要先刷新它。
abstract void flush()刷新该流的缓冲。
2> FileWriter(用来写入字符文件的便捷类,Writer的子类)
构造方法:
FileWriter(File file) 根据给定的 File 对象构造一个 FileWriter 对象
FileWriter(File file, boolean append)
FileWriter(String fileName) 根据给定的文件名构造一个 FileWriter 对象。
FileWriter(String fileName, boolean append)
普通方法:和Writer一样
3>BufferedWriter(将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入,包装流)
构造方法:
BufferedWriter(Writer out)使用基本流创建一个缓冲字符输出流
BufferedWriter(Writer?out, int size): 使用基本流创建一个缓冲字符输出流, 设置缓冲区大小
普通方法:
void newLine();换行.写一个换行符
4>OutputStreamWriter:(将字节输出流转换成字符输出流),可以定义编码表
构造方法:
OutputStreamWriter(OutputStream out) 将字节输出流转换成字符输出流
OutputStreamWriter(OutputStream out, StringcharsetName) 创建使用指定字符集(编码表)的 OutputStreamWriter。
5>PrintWriter(打印流):可以定义编码表
构造方法:
PrintWriter(File file) 使用指定文件创建不具有自动行刷新的新 PrintWriter。
PrintWriter(File file, String csn)创建具有指定文件和字符集且不带自动刷行新的新PrintWriter。
PrintWriter(String fileName) 创建具有指定文件名称且不带自动行刷新的新 PrintWriter。
PrintWriter(String fileName, String csn)创建具有指定文件名称和字符集且不带自动行刷新的新 PrintWriter。
PrintWriter(OutputStream out) 根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。
PrintWriter(OutputStream out, boolean autoFlush) 通过现有的 OutputStream 创建新的 PrintWriter。
PrintWriter(Writer out) 创建不带自动行刷新的新 PrintWriter。
PrintWriter(Writer out, boolean autoFlush) 创建新 PrintWriter。 带自动刷新.
普通方法:
void println(Object x) 打印 Object,然后终止该行。
void print(Object obj) 打印对象。
注意:
1.只能输出不能输入,不能输出字节,但是可以输出其他的任意类型,可以自动换行println();通过魔偶写配置 可以实现自动刷新,只有在调用print, println,或format的时候才能用.
也是包装流,不具备写出功能,把字节流转换成字符流.
2.创建FileWriter对象时boolean参数是是否追加,而创建打印流对象的boolean类型的参数是是否自动刷新
特点:
1.自动换行
2.自动刷新.
二.标准输入流
System:
static PrintStreamin;"标准"输入流
static PrintStreamout;"标准输出流"
static voidsetOut(PrintStream out): 设置System.out的输出目的地为参数的打印流
三 IO异常处理
1.IO流操作中的异常处理
IO流的标准格式
JDK7和JDK9中IO异常处理的不同方式
解决乱码问题
1.内存和硬盘之间的流动
内存中的内容写入到硬盘中字符先按照指定的编码表将文字转换成字节,硬盘会用指定编码表将字节转换成我们能看懂的字符.
硬盘中的文件内容读入到内存中,字符先按照"文本"默认的编码表转换成字节,然后内存接收,内存会用默认的编码表转换成我们能看懂的字符
2.用OutputStreamReader和InputStreamWriter用指定的编码表去解码.它们是字节和字符的桥梁
3.乱码问题: FileReader读取GBK编码
乱码原因: 读写编码不一致 GBK文件中存储的是"你好"在GBK中对应的byte 而IDEA中使用FileReader读取文件时, 是将byte按照UTF-8编码表查找字符, 结果找不到, 就显示了问号
乱码原理: 字符流和转换流的关系
字符编码和字符集
编码: 字符 -> 字节 'a' -> 97
解码: 字节 -> 字符 97 -> 'a'
编码表: 字符和二进制数字的对应规则 字符集和编码表: 字符集包含编码表
ASCII字符集
ASCII编码表
ISO-8859-1字符集:
Latin-1: 拉丁字符. 没有中文. 每个字符由1个byte组成
GB字符集
GB2312编码表: 每个字符由2个byte组成
GBK编码表: 每个字符由2个byte组成
GB18030编码表: 每个字符由1, 2,4个byte组成
Unicode
UTF-8: ASCII字符占1个byte, 拉丁字符占2个byte, 中文占3个byte, Unicode辅助字符占4个byte
UTF-16
UTF-32 ANSI: 表示使用系统默认编码表 |
-
123.png
(71.21 KB, 下载次数: 14)
-
234.png
(125.71 KB, 下载次数: 21)
-
111.png
(466.7 KB, 下载次数: 16)
-
11.png
(43.77 KB, 下载次数: 15)
-
12.png
(39.88 KB, 下载次数: 21)
-
13.png
(31.22 KB, 下载次数: 16)
-
21.png
(53.04 KB, 下载次数: 14)
-
22.png
(481.42 KB, 下载次数: 21)
-
23.png
(130.28 KB, 下载次数: 14)
-
11.png
(71.25 KB, 下载次数: 17)
 组图打开中,请稍候......
|