【Java总结】-【提高篇(第七周)】 后续每周总结一次
目录
I/O框架
什么是流
- 内存与存储设备之间传输数据的通道
流的分类
- 方向
- 输入流 : 将存储设备中的内容读入到内存中
- 输出流 : 将内存中的内容写入到存储设备中
- 单位
- 字节流 : 以字节为单位,可以读写所有数据
- 字符流 : 以字符为单位,只能读写文本数据
- 功能
- 节点流 : 具有实际传输数据的读写功能
- 过滤流 : 在节点流的基础上增强功能
字节流
- InputStream抽象类
- OutputStream抽象类
- 字节节点流
- FileInputStream
- FileOutputStream
- 字节过滤流
- BufferedOutputStream
- BufferedInputStream
- 提供了IO效率,减少访问磁盘的次数。数据存放在缓冲区中。flush()刷新缓冲区,提交数据
- 对象流
- ObjectInputStream
- ObjectOutputStream
- 增强读写8中基本数据类型和字符串功能
- 读写对象,可以实现对象的持久化存储
- 序列化和反序列化
- 必须实现接口Serializable
- 必须保证所有属性均支持序列化
- Transient修饰的为临时属性,不参与序列化
- 读取到文件末尾时:java.IO.EOFException
public class TestInputAndOutputStream {
List<String> testList = new ArrayList<String>();
static String path = "./src/txt/a.txt";
public static void main(String[] args) {
//testFileOutPut();
//testFileInput();
//testBufferedInput();
//testBufferedOutput();
testObjectInputStream();
testObjectOutputStream();
}
private static void testFileInput() {
try(
// 创建一个FileInputStream对象
InputStream inputStream = new FileInputStream(path);
) {
int n = 0;
byte[] bytes = testDataLength();
while((n=inputStream.read(bytes)) != -1) {
for (int i = 0; i < n; i++) {
System.out.print((char) bytes[i]);
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testFileOutPut() {
try(OutputStream op = new FileOutputStream(path,true);) {
op.write(testData());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void testBufferedInput() {
try (BufferedInputStream is = new BufferedInputStream(new FileInputStream(path)); ){
byte[] bytes = testData();
int n=0;
while ((n=is.read(bytes))!=-1) {
for (int i = 0; i < n; i++) {
System.out.print((char)bytes[i]);
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testBufferedOutput() {
try (OutputStream is = new BufferedOutputStream(new FileOutputStream(path,true)); ){
byte[] bytes = testData();
is.write(testData());
is.flush();
} catch (Exception e) {
// TODO: handle exception
e.getMessage();
}
}
private static void testObjectInputStream() {
try(ObjectInputStream iStream = new ObjectInputStream(new FileInputStream(path));) {
byte bytes[] = testDataLength();
// 常常用来反序列化
Object stream ;
while((stream = iStream.readObject())!=null) {
testSerializable t1 = (testSerializable)stream;
System.out.println(t1.toString());
}
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testObjectOutputStream() {
try(ObjectOutputStream iStream = new ObjectOutputStream(new FileOutputStream(path));) {
byte bytes[] = testDataLength();
// 常常用来反序列化
iStream.writeObject(new testSerializable("李敢敢",23));
iStream.writeObject(new testSerializable("赵岩岩",23));
iStream.flush();
} catch (Exception e) {
// TODO: handle exception
}
}
// 读取数据的容量大小
private static byte[] testDataLength() {
return new byte[1024];
}
// 准备数据
private static byte[] testData() {
byte[] bytes = new byte[] {'1','2','3','4','5','6','7','8','8','a','b','c'};
return bytes;
}
}
class testSerializable implements Serializable{
public String name;
public Integer age;
public testSerializable(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "testSerializable [name=" + name + ", age=" + age + "]";
}
}
字符编码
- GBK 简体中文、扩展
- UTF-8针对Unicode的可变字符编码
- GB2312简体中文
- 当编码和解码方式不一致时,会出现乱码
字符流
- 字符流的父类
- Reader
- Writer
- 字符节点流
- FileReader
- FileWriter
- 字符过滤流
- BufferedWriter/PrintWriter
- BufferedReader
- 支持写一行、读一行
public class TestReaderAndWriter {
static String path = "./src/txt/a.txt";
public static void main(String[] args) {
// ---
testFileWriter();
testFileReader();
// ---
testBufferedWriter();
testBufferedReader();
testPrintWriter();
testBufferedReader();
}
private static void testFileReader() {
try(Reader reader = new FileReader(path);) {
int n;
char[] bytes =dataLength();
while((n=reader.read(bytes))!=-1) {
for (int i = 0; i < n; i++) {
System.out.print(bytes[i]);
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testFileWriter() {
try(Writer w = new FileWriter(path);) {
w.write("I love you!");
w.flush();
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testBufferedWriter() {
try(BufferedWriter bfw = new BufferedWriter(new FileWriter(path));) {
bfw.write("基本没啥区别");
bfw.flush();
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testBufferedReader() {
try(BufferedReader br = new BufferedReader(new FileReader(path));) {
String str;
while((str=br.readLine())!=null) {
System.out.println(str);
}
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testPrintWriter() {
try(PrintWriter pw = new PrintWriter(new FileWriter(path));) {
pw.println("床前明月光");
pw.println("疑似地上霜");
pw.println("举头望明月");
pw.println("岩岩在身旁");
pw.flush();
} catch (Exception e) {
// TODO: handle exception
}
}
private static char[] dataLength() {
return new char[1024];
}
}
字符节点流
- 字符节点流
- 桥转换流
- InputStreamReader
- OutputStreamWriter
- 可将字节流转换为字符流。可设置编码方式,编码与解码一定要一致。
- 使用步骤
- 创建节点流
- 创建过滤流,设置字符编码
- 封装过滤流
- 读写数据
- 关闭流
- 桥转换流
public class TestConvertStream {
public static void main(String[] args) {
String path ="./src/txt/a.txt";
try( //1.创建字节流
FileInputStream is = new FileInputStream(path);
FileOutputStream os = new FileOutputStream(path,true);
//2.创建转换流
InputStreamReader isr = new InputStreamReader(is,"UTF-8");
OutputStreamWriter isw = new OutputStreamWriter(os,"UTF-8");
//3.创建字符流
BufferedReader br = new BufferedReader(isr);
PrintWriter pw = new PrintWriter(isw);
){
//1.读取
String string;
while((string = br.readLine())!=null) {
System.out.println(string);
}
//2.写入
pw.println("床前明月光\r\n" +
"疑似地上霜\r\n" +
"举头望明月\r\n" +
"岩岩在身旁\r\n" +
"");
// pw.flush();
}catch (Exception e) {
// TODO: handle exception
}
}
}
File
- FileFilter
- File类的构造方法
public class TestFile {
public static void main(String[] args) throws IOException {
File file = new File("./src");
file.canExecute();//是否可执行
file.canRead();//是否可读
file.canWrite();//是否可写
//file.createNewFile();// 创建一个文件
//file.mkdir();//创建文件夹
//file.mkdirs();//递归文件夹
//file.delete();//删除文件或文件夹
//file.exists();//判断文件是否存在
System.out.println(file.getAbsoluteFile());//获得文件绝对路径
System.out.println(file.getAbsolutePath());//获得文件绝对路径
System.out.println(file.getName());//获得文件名
System.out.println(file.getParent());//获得文件父目录
System.out.println(file.getParentFile());//获得文件父目录
file.isDirectory();//判断是否是目录
file.isFile();//判断是否是文件
System.out.println("---");
// 递归遍历
readfile(file.listFiles());
// 遍历一层
File[] files = file.listFiles((pathname)->{
if(pathname.isFile() && pathname.getName().endsWith(".java")) {
return true;
}
return false;
});
System.out.println("---------");
for (File file2 : files) {
System.out.println(file2);
}
}
private static void readfile(File[] files) {
if(files == null) {
return;
}
for (File file : files) {
if(file.isFile()) {
System.out.println(file.getName());
}else if(file.isDirectory()) {
readfile(file.listFiles());
}
}
}
}
网络编程
- 由点和线构成的,标识诸多对象间的相互联系 ##### 计算机网络- 实现资源共享和信息传递,通过通信线路连接起来的若干(Host)
- 互联网:点与点
- 万维网:端与端相连
- 物联网:物与物相连
- 网络编程:让计算机与计算机之间建立了链接、进行通信
网络模型
- 第一层:物理层(双绞线、光导纤维)
- 第二层:链路层(MAC)
- 第三层:网络层(IP地址)
- 第四层:传输层(TCP、UDP)
- 第五层:会话层(断点续传)
- 第六层:表示层(对数据转化以及加密)
- 第七层:应用层(HTTP、FTP、SMTP)
TCP/IP模型
- 一组用于实现网络互连的通信协议,分为四层
- 第一层:网络接口层(以太网、ADSL)
- 第二层:网络层(分配地址、传输数据、IP地址)
- 第三层:传输层(文本数据,协议是Tcp、UDP协议)
- 第四层:应用层(负责传送最终形态的数据,协议为HTTP、FTP)
TCP/UDP
- tcp:传输控制协议 :是一种面向连接、可靠的、基于字节流的传输层通信
数据大小无限制 - 建立连接的过程需要三次握手
- 断开连接的过程需要四次挥手
- UDP:用户数据报协议:是一种无连接的传输层协议,提供面向事务的简单、不可靠信息传送服务
- 每个包大小是64KB
IP
- 互联网协议/网际协议地址
- 分配给互联网设备的唯一数字标识
- IPV4
4字节32位正数,分成4段8位的二进制数
255.255.255.255 - IPV6
16字节128位正数,分成8段十六进制正数
FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF - 回环地址
127.0.0.1
localhost - Port(端口)
- 在通信实体上进行网络通讯的程序的唯一标识 0~65535
- Mysql:3306 Oracle:1521 Tomcat:8080
InetAddress
- 标识互联网协议(IP)地址对象。封装了与该IP地址对象相关的所有信息,并提供常用方法
- 无法直接创建对象,构造方法私有化,需要通过getXXX方法获得
public class TestInetAddress {
public static void main(String[] args) throws UnknownHostException {
//获取本地连接
InetAddress ia = InetAddress.getLocalHost();
// 获取本机地址
System.out.println(ia.getAddress());
// 获取本机的ip
System.out.println(ia.getHostAddress());
//获取本机名
System.out.println(ia.getHostName());
//获取本机名/ip
System.out.println(ia.getLocalHost());
}
}
基于TCP的网络编程
- Socket
- 是网络中的一个通讯节点
- 分为客户端Socket 服务端ServerSocket
- 通讯要求:IP地址和端口Port
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//创建客户端
Socket client = new Socket("127.0.0.1",9999);
//创建输入输出流
//创建输入输出流
PrintWriter pw = new PrintWriter(new OutputStreamWriter(client.getOutputStream(),"UTF-8"));
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream(),"UTF-8"));
pw.println("床前明月光");
pw.println("疑似地上霜");
pw.println("举头望明月");
pw.println("岩岩在身旁");
pw.flush();
String string;
while((string=br.readLine())!=null)
{
System.out.println(string);
}
pw.close();
br.close();
client.close();
}
}
public class Server {
public static void main(String[] args) throws IOException {
//配置服务器端口号
ServerSocket server = new ServerSocket(9999);
System.out.println("服务器启动");
//监听客户端
Socket client = server.accept();
//创建输入输出流
PrintWriter pw = new PrintWriter(new OutputStreamWriter(client.getOutputStream(),"UTF-8"));
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream(),"UTF-8"));
// 响应
pw.println("欢迎"+client.getInetAddress().getHostName()+"访问客户端");
pw.flush();
String string;
while((string=br.readLine())!=null)
{
System.out.println(string);
}
//----------------
pw.close();
br.close();
client.close();
server.close();
}
}
反射
类的对象
- 基于某个类new出来的对象,也称为实例对象public class TestA{
public static void main(String[] args){
TestA t = new TestA(); //t就是实例对象
}
}
类对象
- 类加载的产物
- 封装了一个类所有信息(类名、父类、接口、属性、方法、构造方法)
- 一个.class文件就代表一个类对象
获取类对象
- 通过类的对象,回去类对象
Student s = new Student();
Class c = s.getClass();
- 通过类名获取类对象
Class c = 类名.class
- 通过静态方法获取类对象
Class.forName("包名.类名")
常用方法
public String getName()//获取全路径类名
public Package getPackage();//获取全路径包名
public Class<? super T> getSuperclass();//获取父类返回Class
public Class<?>[] getInterfaces() // 获取接口返回数组
public Field[] getFields()//获取属性(自身加父类的公开属性) 必须是Public的
public Field[] getDeclaredFields()//获取自身所有属性不分权限
public Method[] getMethods()// 获取方法(自身的和父类的公共方法)必须是Public的
public Method[] getDeclaredMethods()//获取自身所有非构造方法
getReturnType() 方法返回值类型
public Constructor<?>[] getConstructors()
public Constructor<?>[] getDeclaredConstructors()
public T newInstance()
package com.review.reflect;
public class TestReflects {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//方法一
Student t = new Student();
Class c1 = t.getClass();
//方法二
Class c2 = Student.class;
//方法三
Class c3 = Class.forName("com.review.reflect.Student");
// 获取全路径类名
String name = c2.getName();
// 获取全路径报名
Package p = c2.getPackage();
//获取父类返回Class
Class cparent = c2.getSuperclass();
// 获取接口返回数组
Class[] ci = c2.getInterfaces();
//获取属性(自身加父类的公开属性) 必须是Public的
c2.getFields();
//获取自身所有属性不分权限
c2.getDeclaredFields();
// 获取方法(自身的和父类的公共方法)必须是Public的
c2.getMethods();
//获取自身所有非构造方法
c2.getDeclaredMethods();
// 获取构造函数
c2.getConstructors();
c2.getDeclaredConstructors();
// 实例化
Student student = (Student)c2.newInstance();
}
}
class Student{
private String name;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student [name=" + name + ", sex=" + sex + "]";
}
public Student(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
}
工厂设计模式
- 开发中有一个非常重要的原则,:“开闭原则”.对拓展开放、对修改关闭
- 工厂模式主要负责对象创建的问题
- 通过反射进行工厂模式的设计,完成动态的对象创建
public class TestFactory {
public static void main(String[] args) {
Object o = createObject("com.qfedu.review.reflect.Person");
Class c= o.getClass();
System.out.println(o.getClass().getTypeName());
}
private static Object createObject(String className) {
try{
Class sClass = Class.forName(className);
return sClass.newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
//使用反射技术执行任何方法
public static void invokeAny(Object obj,String methodName,Class[] types,Object...args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//类对象
Class c = obj.getClass();
//获得方法的对象Method
Method m = c.getDeclaredMethod(methodName, types);
//执行方法
m.invoke(c,args);
}
}
class Person{
}
单例模式
- 只允许创建一个该类的对象
- 方式1:饿汉式(类加载时创建,天生线程安全)
- 方式2:懒汉式(使用时创建,线程不安全,需要加锁)
- 方式3:懒汉式(使用时创建、线程安全,天生不需要加锁)
public class TestSingleton {
public static void main(String[] args) {
}
// 方式1
}
// 饿汉
class TestSingletonOne {
private final static TestSingletonOne tobj = new TestSingletonOne();
private TestSingletonOne() {}
public TestSingletonOne CreateObj() {
return tobj;
}
}
// 懒汉1
class TestSingletonTwo {
private static TestSingletonTwo tobj = null;
private TestSingletonTwo() {}
synchronized public TestSingletonTwo CreateObj() {
if(this.tobj == null) {
this.tobj = new TestSingletonTwo();
}
return tobj;
}
}
// 懒汉2
class TestSingletonThree {
private TestSingletonThree() {}
private static class Create{
final static TestSingletonThree tobj =new TestSingletonThree();
}
public TestSingletonThree CreateObj() {
return Create.tobj;
}
}