Linux常用命令与shell语言 Li.050

user 用户相关命令 useradd username passwd username usermod -l usernewname username userdel usernewname # 强制删除用户usertest主目录和邮件池 userdel -rf usertest group 用户组相关命令 groupadd groupname # 查看用户所在的组 groups username # 更改组名 groupmod -n groupname groupnewname groupdel groupnewname 管理用户与组 # 往group1中添加用户test gpasswd -a test group1 # 删除group1中的test gpasswd -d test group1 # 查看组中有几个用户 cat /etc/group | grep groupname 时间 date date -d "2021-09-09 12:00:01" # 修改时间 date -s "2021-09-09 12:00:01" logname 显示登录用户名 su 切换用户 # 切换到root用户执行命令, 再切换回当前用户, 需要输入root密码 su -c ls root id 查看用户id 用户组id top 命令 实时监控进程 # 停止监控 q # 显示完整命令 top -c # 指定pid top -p 3550 PS # 当前正在运行 ps # 全部运行 ps -A # 查看更全的信息 ps -ef # 指定用户进程信息 ps -u username Kill # 杀掉进程 kill 999 # 彻底杀掉 kill -9 999 # 杀掉用户进程 kill -9 $(ps -ef | grep username) killall -u username shutdown # 关机 shutdown # 取消关机 shutdown -c # 立即关机 shutdown -h now # 警告 1分钟后关机 shutdown +1 "1分钟关机" # 警告 1分钟后重启 shutdown -r +1 "1分钟重启" who 当前登录系统的用户 who who -H timedatectl 设置时间 # 查看所有时区 timedatectl list-timezones # 设置野区 timedatectl set-timezone Asia/Shanghai # 禁用ntp timedatectl set-ntp false # 启用ntp timedatectl set-ntp true clear 清屏 command + L 同样能做到 clear ls ls # 显示文件夹(不隐藏的文件与文件夹详细信息) ls -l # 全部文件夹与文件(包含隐藏) ls -a ls -al pwd 打印目录 pwd cd 切换路径 Fasd 跳转比cd更快 ...

September 21, 2021 · 10 分钟 · Lizicai

Java的反射 Li.049

反射 反射概述 Java的反射机制是在运行状态中, 对于任意一个类, 都能知道这个类的所有属性和方法 对于任意一个对象, 都能够调用它的任意一个方法和属性 这种动态获取信息以及动态调用对象的方法的功能称为Java语文的反射机制 想要解剖一个类, 必需先要获取到该类的字节码文件对象 而解剖使用的就是Class类中的方法, 所以先要获取到每一个字节码文件对应的Class类型的对象 反射的三种方式 Object烦的getClass()方法, 判断2个对象是否是同一个字节码文件 静态属性class, 锁对象(Person.class) Class类中静态方法forName(), 读取配置文件 import com.lizicai.bean.Person; public class Demo1_Reflect { public static void main(String[] args) throws ClassNotFoundException { Class clazz1 = Class.forName("com.lizicai.bean.Person"); Class clazz2 = Person.class; Person p = new Person(); Class clazz3 = p.getClass(); System.out.println(clazz1 == clazz2); System.out.println(clazz2 == clazz3); } } 反射(Class.forName()读取配置文件举例) import java.io.*; public class Demo2_Reflect { public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { // nouseReflect(); String str = null; BufferedReader br = new BufferedReader(new FileReader("config.properties")); str = br.readLine(); Class clazz = Class.forName(str); Fruit f = (Fruit) clazz.newInstance(); Juier j = new Juier(); j.run(f); } private static void nouseReflect() { Juier j = new Juier(); Apple apple = new Apple(); j.run(apple); j.run(new Orange()); } } interface Fruit{ public void squeeze(); } class Apple implements Fruit { @Override public void squeeze(){ System.out.println("苹果汁"); } } class Orange implements Fruit{ @Override public void squeeze(){ System.out.println("橙汁"); } } class Juier{ public void run(Fruit fruit){ fruit.squeeze(); } public void run(Orange orange){ orange.squeeze(); } } com.lizicai.reflect.Orange 通过反射获取带参构造方法并使用 构造函数必须public, 否则报NoSuchMethodException 异常. import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Demo3_Reflect { public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { Class clazz = Class.forName("com.lizicai.bean.Person"); // Person p = (Person) clazz.newInstance(); Constructor c = clazz.getConstructor(String.class, int.class); Person p = (Person) c.newInstance("张三",23); System.out.println(p); } } public class Person { private String name; private int age; public Person(String name, int age){ this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public boolean equals(Object obj) { return super.equals(obj); } @Override public int hashCode() { return super.hashCode(); } @Override public String toString() { return this.getName() + this.getAge(); } } 通过反射获取成员变量并使用 import com.lizicai.bean.Person; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; public class Demo4_Reflect { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException { Class clazz = Class.forName("com.lizicai.bean.Person"); Constructor c = clazz.getConstructor(String.class, int.class); Person p = (Person) c.newInstance("张三",23); // Field f = clazz.getField("name"); // 暴力反射 Field f = clazz.getDeclaredField("name"); // 去除私有权限 f.setAccessible(true); f.set(p,"李四"); System.out.println(p); } } 通过反射获取方法并使用 import com.lizicai.bean.Person; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Demo5_Reflect { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException, InvocationTargetException { Class clazz = Class.forName("com.lizicai.bean.Person"); Constructor c = clazz.getConstructor(String.class, int.class); Person p = (Person) c.newInstance("张三",23); Method m = clazz.getMethod("eat"); m.invoke(p); Method m2 = clazz.getMethod("eat", int.class); m2.invoke(p,10); } } 通过反射越过泛型检查 泛型编译时检查, 运行时没有检查 import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; public class Test1 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(2); Class clazz = Class.forName("java.util.ArrayList"); Method m = clazz.getMethod("add",Object.class); m.invoke(list,"test"); System.out.println(list); } } 通过反射写一个通用的设置某个对象的某个属性为指定的值 Person对象仍然是上面的 import java.lang.reflect.Field; public class Tool { public void setProperty(Object obj, String propertyName, Object value) throws NoSuchFieldException, IllegalAccessException { Class clazz = obj.getClass(); Field f = clazz.getDeclaredField(propertyName); f.setAccessible(true); f.set(obj,value); } } import com.lizicai.bean.Person; public class Test2 { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { Person p = new Person("小明",23); System.out.println(p); Tool t = new Tool(); t.setProperty(p,"name","小红"); System.out.println(p); } } 练习 import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test3 { public static void main(String[] args) throws IOException, ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException { File file = new File("demo.properties"); BufferedReader br = new BufferedReader(new FileReader(file)); String clazzName = br.readLine(); br.close(); Class clazz = Class.forName(clazzName); DemoClass dc = (DemoClass) clazz.newInstance(); Method m = clazz.getMethod("run"); m.invoke(dc); } } public class DemoClass { public void run(){ System.out.println("大王叫我来巡山"); } } com.lizicai.test.DemoClass 动态代理的概述和实现 写好了代理, 就能在所有类前后进行一些处理 public interface User { public void add(); public void delete(); } public class UserImp implements User{ @Override public void add() { // System.out.println("权限校验"); System.out.println("添加"); // System.out.println("日志记录"); } @Override public void delete() { // System.out.println("权限校验"); System.out.println("删除"); // System.out.println("日志记录"); } } import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object target){ this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("权限检验"); method.invoke(target,args); System.out.println("日志记录"); return null; } } import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { User ui = new UserImp(); ui.add(); ui.delete(); MyInvocationHandler m = new MyInvocationHandler(ui); User u = (User) Proxy.newProxyInstance(ui.getClass().getClassLoader(), ui.getClass().getInterfaces(),m); u.add(); u.delete(); } } 模版(Template)设计模式概述和使用 模版设计模式概述 模版方法模式就是定义一个算法模版, 而将具体的算法延迟到子类中实现 优点 缺点 使用模版方法模式, 在定义骨架的同时, 可以很灵活实现具体的方法, 满足用户灵活多变的需求 如果算法有修改, 则需要修改抽象类 public class Demo1_Template extends TestTime{ public static void main(String[] args) { Demo1_Template d = new Demo1_Template(); System.out.println(d.getTime()); } @Override public void code() { for(int i=0;i<100000;i++){ System.out.println(i); } } } abstract class TestTime{ final public long getTime(){ long start = System.currentTimeMillis(); code(); long end = System.currentTimeMillis(); return end - start; } public abstract void code(); } 自己实现枚举类 概述 是指将变量的值一一列举出来, 变量的值仅限于列举出来的值的范围内 单例模式, 只有一个实例 多例类就是一个类有多个实例, 但不是无限多个实例, 是有限个数的实例, 这才是枚举类. 枚举类有下例3种形式 public class Week { final static Week MON = new Week(); final static Week TUE = new Week(); final static Week WED = new Week(); private Week(){} } public class Week2 { final static Week2 MON = new Week2("星期一"); final static Week2 TUE = new Week2("星期二"); final static Week2 WED = new Week2("星期三"); String name; private Week2(String name){ this.name = name; } @Override public String toString() { return this.name; } } public abstract class Week3 { final static Week3 MON = new Week3("星期一"){ @Override public void show() { System.out.println("星期一"); } }; final static Week3 TUE = new Week3("星期二"){ @Override public void show() { System.out.println("星期二"); } }; final static Week3 WED = new Week3("星期三") { @Override public void show() { System.out.println("星期三"); } }; String name; private Week3(String name){ this.name = name; } @Override public String toString() { return this.name; } public abstract void show(); } public class Demo1_Enum { public static void main(String[] args) { Week mon = Week.MON; System.out.println(mon); Week2 Mon = Week2.MON; Week2 Tue = Week2.TUE; Week2 Wed = Week2.WED; System.out.println(Mon); System.out.println(Tue); System.out.println(Wed); Week3 MON = Week3.MON; Week3 TUE = Week3.TUE; Week3 WED = Week3.WED; MON.show(); TUE.show(); WED.show(); } } 通过enum实现枚举类 public enum Week { MON,TUE,WED; } public enum Week2 { MON("星期一"),TUE("星期二"),WED("星期三"); private String name ; Week2(String name){ this.name = name; } public String getName() { return name; } } public enum Week3 { MON("星期一"){ @Override public void show() { System.out.println("星期一"); } },TUE("星期二"){ @Override public void show() { System.out.println("星期二"); } },WED("星期三"){ @Override public void show() { System.out.println("星期三"); } }; private String name ; Week3(String name){ this.name = name; } public String getName() { return name; } public abstract void show(); } public class Demo1_Enum { public static void main(String[] args) { Week mon = Week.MON; Week tue = Week.TUE; System.out.println(mon); System.out.println(tue); Week2 Mon = Week2.MON; Week2 Tue = Week2.TUE; System.out.println(Mon); System.out.println(Tue.getName()); Week3 MON = Week3.MON; Week3 TUE = Week3.TUE; Week3 WED = Week3.WED; System.out.println(MON); System.out.println(TUE.getName()); System.out.println(WED.getName()); } } switch 使用枚举 public static void demo1(){ Week2 MON = Week2.TUE; switch (MON){ case MON: System.out.println("星期一"); break; case TUE: System.out.println("星期二"); break; case WED: System.out.println("星期三"); break; } } 常用的枚举方法 public final int ordinal() 获取枚举的位置 public final int compareTo(E o) 比较枚举位置, 返回差 public final String name() 获取枚举实例的名字 public static <T extends Enum> T valueOf(Class enumType, String name) 字节码对象获取枚举项 values 获取枚举的数组 public class Demo2_Enum { public static void main(String[] args) { Week2 mon = Week2.MON; Week2 tue = Week2.TUE; Week2 wed = Week2.WED; System.out.println(mon.ordinal()); System.out.println(tue.ordinal()); System.out.println(wed.ordinal()); System.out.println(mon.compareTo(tue)); System.out.println(mon.compareTo(wed)); System.out.println(mon.name()); System.out.println(tue.name()); System.out.println(mon); System.out.println(tue.toString()); // 字节码对象获取枚举项 Week2 TUE = Week2.valueOf(Week2.class,"TUE"); System.out.println(TUE); Week2[] arr = Week2.values(); for(Week2 w:arr){ System.out.println(w); } } } JDK 1.7 新增内容 switch支持字符串 异常catch多个异常, 用|隔开 try-whith-resources 自动关流 import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class Demo3_AutoClose { public static void main(String[] args) { File file = new File("config.properties"); //资源放在try()中, 会自动关闭资源, 不用在finally 中关闭了 try ( FileInputStream fis = new FileInputStream(file)){ int b; while ( ( b = fis.read() ) != -1){ System.out.println(b); } } catch (IOException e){ System.out.println(e.getMessage()); } } } JDK 1.8 新增内容 接口可以支持default修饰, 有方法体 接口也可以有静态方法了 内部类可访问的变量默认是final修饰 public class Demo4_JKD18 { // JDK1.8新特性 public static void main(String[] args) { Demo d = new Demo(); d.show(); Inter.test(); d.run(); } } interface Inter{ public default void show(){ System.out.println("显示"); } public static void test(){ System.out.println("测试"); } } class Demo implements Inter{ public void run(){ // num 默认是final int num = 20; class Inner{ public void fun(){ System.out.println("fun"); } } Inner i = new Inner(); i.fun(); } }

September 19, 2021&nbsp;·&nbsp;7 分钟&nbsp;·&nbsp;Lizicai

Java的网络编程 Li.048

网络通信 ip 电脑地址 UDP TCP 端口号 socket 插座, 数据流间的插座, 用来联通 类似电脑是港口ip, socket是航线用来发货, 端口号是港口停放船的泊位, UDP TCP是小船还是大船来运送数据箱子 DatagramSocket 与 DatagramPacket DatagramSocket 创建一条航线 DatagramPacket 指定电脑ip(港口), 端口号(泊位), 运送的数据(集装箱) import java.io.IOException; import java.net.*; import java.nio.charset.StandardCharsets; public class Demo1_Send { public static void main(String[] args) throws IOException { String msg = "中午一起吃饭"; DatagramSocket datagramSocket = new DatagramSocket(); DatagramPacket datagramPacket = new DatagramPacket (msg.getBytes(StandardCharsets.UTF_8),msg.getBytes().length, InetAddress.getByName("127.0.0.1"),2000); datagramSocket.send(datagramPacket); datagramSocket.close(); } } import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class Demo2_Receive { public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(2000); DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); socket.receive(packet); byte[] arr = packet.getData(); int len = packet.getLength(); System.out.println(new String(arr,0,len)); socket.close(); } } 能够不断录入的版本 import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.nio.charset.StandardCharsets; import java.util.Scanner; public class Demo3_Send { public static void main(String[] args) throws IOException { Scanner sc = new Scanner(System.in); DatagramSocket datagramSocket = new DatagramSocket(); while (true){ String msgLine = sc.nextLine(); if( "quit".equals(msgLine)){ break; } System.out.println(msgLine); DatagramPacket packet = new DatagramPacket (msgLine.getBytes(StandardCharsets.UTF_8), msgLine.getBytes().length, InetAddress.getByName("127.0.0.1"), 2000); datagramSocket.send(packet); } datagramSocket.close(); } } import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class Demo3_Receive { public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(2000); DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); while (true){ socket.receive(packet); byte[] arr = packet.getData(); int len = packet.getLength(); System.out.println("信息" + new String(arr,0,len)); } } } 多线程发送和接收信息 import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.nio.charset.StandardCharsets; import java.util.Scanner; public class Demo4_MoreThread { public static void main(String[] args) { MyReceive myReceive = new MyReceive(); MySend mySend = new MySend(); myReceive.start(); mySend.start(); } } class MyReceive extends Thread{ @Override public void run() { try { DatagramSocket socket = null; socket = new DatagramSocket(2000); DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); while (true){ socket.receive(packet); byte[] arr = packet.getData(); int len = packet.getLength(); System.out.println("信息" + new String(arr,0,len)); } } catch (IOException e) { e.printStackTrace(); } } } class MySend extends Thread{ @Override public void run() { Scanner sc = new Scanner(System.in); DatagramSocket datagramSocket = null; try { datagramSocket = new DatagramSocket(); while (true){ String msgLine = sc.nextLine(); if( "quit".equals(msgLine)){ break; } DatagramPacket packet = new DatagramPacket (msgLine.getBytes(StandardCharsets.UTF_8), msgLine.getBytes().length, InetAddress.getByName("127.0.0.1"), 2000); datagramSocket.send(packet); } } catch (IOException e) { e.printStackTrace(); } datagramSocket.close(); } } GUI 聊天 import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.Date; public class Demo5_GUIChat extends Frame{ private TextField textField; private TextArea viewText; private TextArea sendText; private Button send; private Button log; private Button clear; private Button shake; private DatagramSocket socket; // private BufferedReader br; private FileInputStream fis; private BufferedWriter bw; public Demo5_GUIChat() throws SocketException,IOException{ init(); southPanel(); centerPanel(); event(); Receive r = new Receive(); r.start(); this.setVisible(true); } public void event() { this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { try { bw.close(); } catch (IOException ex) { ex.printStackTrace(); } socket.close(); System.exit(0); } }); send.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { send(); } catch (SocketException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } } }); log.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { logFile(); } catch (IOException ex) { ex.printStackTrace(); } } }); clear.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { viewText.setText(""); } }); shake.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // shake(); try { send(new byte[]{-1},textField.getText()); } catch (IOException ex) { ex.printStackTrace(); } } }); sendText.addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent e) { if(e.getKeyCode() == KeyEvent.VK_ENTER ){ try { send(); } catch (IOException ex) { ex.printStackTrace(); } } } }); } public void shake(){ int x = this.getX(); int y = this.getY(); for(int i=0;i<20;i++){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } if(i % 2 == 0){ this.setLocation(x+3,y+3); } else { this.setLocation(x,y); } } } public void logFile() throws IOException { // br = new BufferedReader(new InputStreamReader(new FileInputStream("chat.log"))); // br = new BufferedReader(new FileReader("chat.log")); // viewText.setText(""); // int len ; // char [] arr = new char[1024]; // while ( ( len =br.read(arr)) != -1){ // viewText.append(new String(arr,0,len)); // } // br.close(); fis = new FileInputStream("chat.log"); ByteArrayOutputStream bos = new ByteArrayOutputStream(); int len; byte[] arr = new byte[8192]; while ( (len = fis.read(arr)) != -1){ bos.write(arr,0,len); } viewText.setText(bos.toString()); bos.close(); } public void send(byte[] arr,String ip) throws IOException { DatagramPacket packet = new DatagramPacket(arr, arr.length, InetAddress.getByName(ip), 9999); socket.send(packet); } public void send() throws IOException { String msg = sendText.getText(); if( "".equals(msg.trim()) || null ==msg){ return; } else { String ip = textField.getText(); if( ip.equals(null) || ip.trim().equals("")){ ip = "255.255.255.255"; } String time = getTime(); send(msg.getBytes(StandardCharsets.UTF_8),ip); String chatlog = time+" "+"我对:"+(ip.equals("255.255.255.255")? "所有人":ip)+"说:"+"\n"+ msg +"\n"+"\n"; viewText.append(chatlog); bw.write(chatlog); bw.flush(); sendText.setText(""); } } public String getTime(){ Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); return sdf.format(date); } public void centerPanel() { Panel center = new Panel(); viewText = new TextArea(); sendText = new TextArea(5,2); viewText.setEditable(false); viewText.setBackground(Color.WHITE); center.setLayout( new BorderLayout()); center.add(sendText, BorderLayout.SOUTH); center.add(viewText, BorderLayout.CENTER); sendText.setFont(new Font("xxx", Font.PLAIN,20)); viewText.setFont(new Font("xxx", Font.PLAIN,16)); this.add(center, BorderLayout.CENTER); } public void southPanel() { Panel south = new Panel(); textField = new TextField(15); textField.setText("127.0.0.1"); send = new Button("发送"); log = new Button("记录"); clear = new Button("清除"); shake = new Button("振动"); south.add(textField); south.add(send); south.add(log); south.add(clear); south.add(shake); this.add(south, BorderLayout.SOUTH); } private void init() throws IOException { this.setLocation(500,10); this.setSize(500,800); socket = new DatagramSocket(); // bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("chat.log",true))); bw = new BufferedWriter(new FileWriter("chat.log",true)); } public static void main(String[] args) throws SocketException,IOException { Demo5_GUIChat guiChat = new Demo5_GUIChat(); } private class Receive extends Thread{ //发送 接收同时进行 @Override public void run() { try { DatagramSocket socket = new DatagramSocket(9999); DatagramPacket packet = new DatagramPacket(new byte[8192], 8192); while (true){ socket.receive(packet); byte[] arr = packet.getData(); int length = packet.getLength(); if( length == 1 && arr[0] == -1){ shake(); continue; } String msg = new String(packet.getData(), 0, packet.getLength()); String chatlog = getTime()+" "+textField.getText()+" "+"对我说:"+"\n"+msg+"\n\n" ; viewText.append(chatlog); bw.write(chatlog); bw.flush(); } } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } } TCP协议 (重要) TCP 三次握手 import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.StandardCharsets; public class Demo2_Server { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(2000); Socket socket = server.accept(); InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); os.write("明天还上班不".getBytes(StandardCharsets.UTF_8)); byte[] arr = new byte[8192]; int len; len = is.read(arr); System.out.println(new String(arr,0,len)); } } import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.nio.charset.StandardCharsets; public class Demo1_Client { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.01",2000); InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); byte[] arr = new byte[8192]; int len = is.read(arr); os.write("吃了".getBytes(StandardCharsets.UTF_8)); System.out.println(new String(arr,0,len)); } } 服务端 客户端TCP 优化 import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.StandardCharsets; public class Demo2_Server { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(2000); Socket socket = server.accept(); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); OutputStream out; PrintStream ps = new PrintStream(socket.getOutputStream()) ; ps.println("快乐, 放假了"); System.out.println(br.readLine()); ps.println("出来玩吧"); System.out.println(br.readLine()); } } import java.io.*; import java.net.Socket; public class Demo2_Client { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.01",2000); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintStream ps = new PrintStream(socket.getOutputStream()) ; System.out.println( br.readLine()); ps.println("是的, 放假了"); System.out.println( br.readLine()); ps.println("起飞"); } } 服务增加多线程 import java.io.*; import java.net.ServerSocket; import java.net.Socket; public class Demo2_Server { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(2000); while (true){ final Socket socket = server.accept(); new Thread(){ @Override public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); OutputStream out; PrintStream ps = new PrintStream(socket.getOutputStream()) ; ps.println("快乐, 放假了"); System.out.println(br.readLine()); ps.println("出来玩吧"); System.out.println(br.readLine()); } catch (IOException e) { e.printStackTrace(); } } }.start(); } } } 服务端反转字符并写给客户端 import java.io.*; import java.net.ServerSocket; import java.net.Socket; public class Demo3_Server { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(2000); while (true){ final Socket socket = server.accept(); new Thread(){ @Override public void run() { while (true){ try { BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintStream ps = new PrintStream(socket.getOutputStream()) ; StringBuilder sb = new StringBuilder( br.readLine()); ps.println(sb.reverse()); } catch (IOException e) { e.printStackTrace(); } } } }.start(); } } } import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; public class Demo3_Client { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.01",2000); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintStream ps = new PrintStream(socket.getOutputStream()) ; Scanner sc = new Scanner(System.in); String s = null; while (true){ s = sc.nextLine(); ps.println(s); System.out.println( br.readLine()); } } } 上传文件到服务端 import java.io.*; import java.net.ServerSocket; import java.net.Socket; public class Demo4_Server_SaveFiles { public static void main(String[] args) throws IOException{ ServerSocket server = new ServerSocket(2000); while (true){ final Socket socket = server.accept(); new Thread(){ @Override public void run() { while (true){ try { InputStream is = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); PrintStream ps = new PrintStream(socket.getOutputStream()) ; File dir = new File("update"); if(!dir.exists()){ dir.mkdir(); } String fileName = br.readLine(); System.out.println(fileName); File file = new File(dir, fileName); if( file.exists()){ ps.println("已存在"); return; }else { ps.println("不存在"); } byte[] arr = new byte[8192]; int len; FileOutputStream fos = new FileOutputStream(file); while ( ( len = is.read(arr)) != -1){ fos.write(arr,0,len); } fos.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }.start(); } } } import java.io.*; import java.net.Socket; import java.util.Scanner; public class Demo4_Client { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.01",2000); InputStream is = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); PrintStream ps = new PrintStream(socket.getOutputStream()) ; Scanner sc = new Scanner(System.in); String s = null; int len; byte[] arr = new byte[8192]; while (true){ s = sc.nextLine(); File file = new File(s); if( !file.exists()){ System.out.println("文件不存在"); } else if( file.isDirectory()){ System.out.println("文件夹, 请重新输入文件"); } else if (file.isFile()){ ps.println(s); String flag = br.readLine(); if( "已存在".equals(flag)){ System.out.println(flag); return; } else { InputStream inputStream = new FileInputStream(file); while ( (len = inputStream.read(arr)) != -1){ ps.write(arr,0,len); } ps.flush(); } } } } }

September 17, 2021&nbsp;·&nbsp;8 分钟&nbsp;·&nbsp;Lizicai

Java的多线程二 Li.047

单例设计模式(重要) 保证类在内存中只有一个对象 饿汉式, 空间换时间, 类创建的时候就创建对象, 线程安全的 懒汉式, 双叫单例加载模式, 使用的时候才创建对象, 存在线程安全问题 区别, 饿汉式空间换时间, 懒汉式时间换空间, 多线程访问时, 饿汉式不会创建多个对象, 懒汉式可能创建多个对象 public class Demo1_Singleton { public static void main(String[] args) { Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1); System.out.println(s2 == s1); } } class Singleton{ // 1. 私有化构造函数, 就不能随意实例类了 private Singleton (){} // 2. 创建实例 private static Singleton s = new Singleton(); // 3. 饿汉式 public static Singleton getInstance() { return s; } } class SingletonLazy{ private SingletonLazy (){} private static SingletonLazy s ; public static SingletonLazy getInstance() { if(s == null){ s = new SingletonLazy(); } return s; } } class SingletonFinal{ private SingletonFinal(){} public static final SingletonFinal s = new SingletonFinal(); } Runtime 类 Process exec(String command) throws IOException 执行命令 import java.io.IOException; public class Demo2_Runtime { public static void main(String[] args) throws IOException { Runtime runtime = Runtime.getRuntime(); runtime.exec("ls"); } } Timer ( 可以被ScheduledExecutorService取代 ) 一种工具, 线程用其安排以后在后台线程中执行的任务, 可安排任务执行一次, 或者定期重复执行 private static void demo1() { Timer t = new Timer(); // t.schedule(new MyTimerTask(), new Date(121,8,13,11,8,01); // 定时 执行 // 循环执行, 每3秒执行一次 t.schedule(new MyTimerTask(), new Date(121,8,13,11,8,01),3000); while (true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(new Date()); } } ScheduledExecutorService Time的缺陷, 单线程多个任务排队, 一个任务执行时间长了, 后面任务受影响, 一个任务挂了, 后面的任务无法执行, 强依赖系统时间, 系统时间更改则会更改 ScheduledExecutorService 多线程, 则没有上述问题 ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) 延时initialDelay, 开始周期delay执行 import java.util.Date; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class Demo3_Timer { public static void main(String[] args) throws InterruptedException { // 一个任务出现 异常, 不影响其他任务 ScheduledExecutorService ses = Executors.newScheduledThreadPool(2); ses.scheduleAtFixedRate( new Runnable() { @Override public void run() { System.out.println("===" + Thread.currentThread().getName() + "==="); } } , 0, 3, TimeUnit.SECONDS); ses.scheduleAtFixedRate( new Runnable() { @Override public void run() { int i = 1/0; System.out.println("***" + Thread.currentThread().getName() + "***"); } } , 0, 3, TimeUnit.SECONDS); } private static void demo2(){ // 一个任务执行时间长了, 也不会任务其他任务 ScheduledExecutorService ses = Executors.newScheduledThreadPool(2); ses.scheduleAtFixedRate( new Runnable() { @Override public void run() { System.out.println("===" + Thread.currentThread().getName() + "==="); try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } , 0, 3, TimeUnit.SECONDS); ses.scheduleAtFixedRate( new Runnable() { @Override public void run() { System.out.println("***" + Thread.currentThread().getName() + "***"); } } , 0, 3, TimeUnit.SECONDS); } private static void demo1() { Timer t = new Timer(); // t.schedule(new MyTimerTask(), new Date(121,8,13,11,8,01); // 定时 执行 // 循环执行, 每3秒执行一次 t.schedule(new MyTimerTask(), new Date(121,8,13,11,8,01),3000); while (true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(new Date()); } } } class MyTimerTask extends TimerTask{ @Override public void run() { System.out.println("起来上班"); } } 多个线程的通信(重要) this.notify() 随机唤醒单个等待线程 public class Demo1_Notify { public static void main(String[] args) { Printer p = new Printer(); new Thread(){ @Override public void run() { while (true){ try { p.method1(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ @Override public void run() { while (true){ try { p.method2(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } class Printer{ private int flag = 1; public void method1() throws InterruptedException { synchronized (this){ if(flag != 1){ this.wait(); } System.out.println("aaaa"); flag = 2; this.notify(); } } public void method2() throws InterruptedException { synchronized (this){ if(flag != 2){ this.wait(); } System.out.println("bbbbbbbb"); flag = 1; this.notify(); } } } 三个或三个以上间的线程通信 public class Demo2_Notify3 { public static void main(String[] args) { Printer2 p = new Printer2(); new Thread(){ @Override public void run() { while (true){ try { p.method1(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ @Override public void run() { while (true){ try { p.method2(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ @Override public void run() { while (true){ try { p.method3(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } class Printer2{ private int flag = 1; public void method1() throws InterruptedException { synchronized (this){ while (flag != 1){ this.wait(); } System.out.println("aaaa"); flag = 2; this.notifyAll(); } } public void method2() throws InterruptedException { synchronized (this){ while (flag != 2){ this.wait(); } System.out.println("bbbbbbbb"); flag = 3; this.notifyAll(); } } public void method3() throws InterruptedException { synchronized (this){ while (flag != 3){ this.wait(); } System.out.println("cccccccccccccc"); flag = 1; this.notifyAll(); } } } 线程间通信注意的问题 1.在同步代码块中,用哪个对象锁,就用哪个对象调用wait方法 2.为什么wait方法和notify方法定义在Object这类中? 因为锁对象可以是任意对象,Object是所有的类的基类,所以wait方法和notify方法需要定义在Object这个类中 3.sleep方法和wait方法的区别? a,sleep方法必须传入参数,参数就是时间,时间到了自动醒来 wait方法可以传入参数也可以不传入参数,传入参数就是在参数的时间结束后等待,不传入参数就是直接等待 b,sleep方法在同步函数或同步代码块中,不释放锁,睡着了也抱着锁睡 wait方法在同步函数或者同步代码块中,释放锁 互斥锁(重要) ReentrantLock Condition import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Demo3_ReentrantLock { public static void main(String[] args) { Printer3 p = new Printer3(); new Thread(){ @Override public void run() { while (true) { try { p.method1(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ @Override public void run() { while (true) { try { p.method2(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ @Override public void run() { while (true) { try { p.method3(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } class Printer3{ private int flag = 1; private ReentrantLock r = new ReentrantLock(); Condition c1 = r.newCondition(); Condition c2 = r.newCondition(); Condition c3 = r.newCondition(); public void method1() throws InterruptedException { r.lock(); if (flag != 1){ c1.await(); } System.out.println("aaaa"); flag = 2; c2.signal(); r.unlock(); } public void method2() throws InterruptedException { r.lock(); if (flag != 2){ c2.await(); } System.out.println("bbbbbbbb"); flag = 3; c3.signal(); r.unlock(); } public void method3() throws InterruptedException { r.lock(); if(flag != 3){ c3.await(); } System.out.println("cccccccccccccc"); flag = 1; c1.signal(); r.unlock(); } } 线程组 public class Demo4_ThreadGroup { public static void main(String[] args) { // demo1(); ThreadGroup threadGroup = new ThreadGroup("自造线程组"); Mythread mythread = new Mythread(); Runnable target; Thread t1 = new Thread(threadGroup, mythread); Thread t2 = new Thread(threadGroup,mythread,"线程1"); Thread t3 = new Thread(threadGroup,mythread,"线程2"); System.out.println(t1.getName()); System.out.println(t2.getName()); System.out.println(t3.getName()); System.out.println(t1.getThreadGroup().getName()); System.out.println(t2.getThreadGroup().getName()); System.out.println(t3.getThreadGroup().getName()); System.out.println(t1.getThreadGroup().getParent().getName()); } private static void demo1() { Mythread mythread = new Mythread(); Thread t1 = new Thread(mythread); Thread t2 = new Thread(mythread); ThreadGroup tg1 = t1.getThreadGroup(); ThreadGroup tg2 = t2.getThreadGroup(); System.out.println(tg1.getName()); System.out.println(tg2.getName()); } } class Mythread implements Runnable{ @Override public void run() { } } 线程的5种状态 新建线程.start() -> 线程就绪状态, 有执行权->抢到CPU执行权限执行->死亡状态, run执行完了 抢到CPU执行权限执行->wait或sleep线程阻塞->叫醒线,程线程就绪状态, 有执行权 线程池 程序创建一个线程成本比较高, 为了方便使用线程池, 使用后再返给JVM import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Demo5_Executors { public static void main(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(2); pool.submit(new Mythread()); pool.submit(new Mythread()); pool.shutdown(); } } 实现Callable的线程 import java.util.concurrent.*; public class Demo6_Callable { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService pool = Executors.newFixedThreadPool(2); Future<Integer> f1 = pool.submit(new MyCallable(10)); Future<Integer> f2 = pool.submit(new MyCallable(20)); System.out.println(f1.get()); System.out.println(f2.get()); pool.shutdown(); } } class MyCallable implements Callable<Integer>{ private int num; public MyCallable(int num){ this.num = num; } @Override public Integer call() throws Exception { int sum = 0; for(int i=1;i<num;i++){ sum = sum + i; } return sum; } } 简单工厂模式 概述 静态工厂方法模式, 它定义一个具体的工厂类负责创建一些类的实例 优点 客户端不负责对象的创建, 从而明确各类的职责 缺点 静态工厂负责所有类的创建, 如果有新的对象或者新对象创建方式不同, 就需要不断修改工厂类, 不利于后期维护. public abstract class Animal { public void eat(){}; } public class AnimalFactory { public static Dog createDog(){ return new Dog(); } public static Cat createCat(){ return new Cat(); } public static Animal createAnimal(String animal){ if( "dog".equals(animal)){ return new Dog(); } else if( "cat".equals(animal)){ return new Cat(); } return null; } } public class Cat extends Animal{ @Override public void eat() { System.out.println("猫吃鱼"); } } public class Dog extends Animal{ @Override public void eat() { System.out.println("单身狗儿吃狗粮"); } } `` ...

September 12, 2021&nbsp;·&nbsp;9 分钟&nbsp;·&nbsp;Lizicai

Java的多线程一 Li.046

多线程增加效率 并行, 就是多个任务同时进行, 多核cpu同时执行 并发, 多个任务轮流进行, cpu一个一个的执行 证明 JVM 是多线程的 垃圾回收和main线程间隔执行 public class Demo1_Thread { public static void main(String[] args) { for(int i=0; i < 10000000 ;i++){ new Demo(); } for(int i=0; i < 10000 ; i++){ System.out.println("主线程"); } } } class Demo{ @Override protected void finalize() throws Throwable { System.out.println("垃圾被回收了"); } } 继承Thread 开启一个线程 实际run() 方法 start() 开启线程 public class Demo2_ExtendsThread { public static void main(String[] args) { MyThread mt = new MyThread(); // mt.run(); mt.start(); for (int i=0; i <10000 ; i++){ System.out.println(i+"bbbbbbbbbbbbb"); } } } class MyThread extends Thread{ @Override public void run() { for(int i=0; i < 10000 ;i++){ System.out.println(i+"aaaaaaaaaaaaaaa"); } } } 实际 Runnable 接口的类 实际Runnable类, 类作为参数传递给线程, start() 开启线程 public class Demo3_Runnable { public static void main(String[] args) { MyRunnable d = new MyRunnable(); Thread t = new Thread(d); t.start(); for(int i=0; i < 10000 ;i++){ System.out.println(i+"bbbbbbbbbbbbbbb"); } } } class MyRunnable implements Runnable{ @Override public void run() { for(int i=0; i < 10000 ;i++){ System.out.println(i+"aaa"); } } } 多线程的2种区别 继承 Thread: 由于子类重写了Thread类的run()方法, 当调用start()时, 直接找子类的run()方法 实际 Runnable: 构造函数中传入了Runnable的引用, 成员变量记住了它, start()调用run() 方法时内部判断成员变量Runnable的引用是否为空, 不为空看的Runnable的run(), 运行时是子类的run()方法. 继承Thread实现简单, 方便使用, 有父类则不能使用这种方法 有父类时可以实际Runnable 接口实现多线程, 对继承Thread的补充, 使用时必须获取线程对象, 使用复杂 匿名内类实现多线程的方法 public class Demo4_NoNameThread { public static void main(String[] args) { new Thread(){ @Override public void run() { for(int i=0; i<100000 ;i++){ System.out.println("aaaaaa"); } } }.start(); Thread t = new Thread(new Runnable() { @Override public void run() { for(int i=0;i<10000;i++){ System.out.println("bbbbbbbbbbbbbbbbbbb"); } } }); t.start(); } } 匿名内部类设置线程名字 public class Demo5_ThreadName { public static void main(String[] args) { // demo1(); Thread t = new Thread(){ @Override public void run() { // this.setName("小明"); System.out.println(this.getName()+"aaaaa"); } }; t.setName("李明"); t.start(); new Thread(){ @Override public void run() { this.setName("小明"); System.out.println(this.getName()+"aaaaa"); } }.start(); } private static void demo1() { new Thread("小明"){ @Override public void run() { System.out.println(this.getName()+ "aaaaa"); } }.start(); new Thread("小红"){ @Override public void run() { System.out.println(this.getName()+ "bbbbbb"); } }.start(); } } 也可调用setName更改名称 获取本类的引用Thread.currentThread() ...

September 10, 2021&nbsp;·&nbsp;6 分钟&nbsp;·&nbsp;Lizicai

Java的递归 Li.045

递归练习, 计算文件夹大小 import java.io.File; import java.util.Scanner; public class Demo1_FolderSize { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String strFolder = null; long size = 0; while (true){ if( sc.hasNext()){ strFolder = sc.nextLine(); break; } } if( strFolder.equals(null)){ System.out.println("不能为空"); } else { File folder = new File(strFolder); if(folder.isFile()){ size = folder.length(); } else if(folder.isDirectory()){ size = getSize(folder); } else if(! folder.exists()){ System.out.println("文件夹不存在"); } } System.out.println(size); } public static long getSize(File folder){ long len = 0; File [] files = folder.listFiles(); for(File subFile:files){ if(subFile.isFile()){ len = len + subFile.length(); } else{ len = len + getSize(subFile); } } return len; } } 递归删除文件夹 删除文件内的文件 删除文件夹本身 import java.io.File; import java.util.Scanner; public class Demo2_DeleteFolder { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String strFolder = null; strFolder = getDir(sc); if( strFolder.equals(null)){ System.out.println("不能为空"); } else { File folder = new File(strFolder); if(folder.isFile()){ folder.delete(); } else if(folder.isDirectory()){ deleteFolder(folder); } else if(! folder.exists()){ System.out.println("文件夹不存在"); } } } private static void deleteFolder(File folder) { File[] files = folder.listFiles(); for (File f : files){ if(f.isFile()){ f.delete(); } else if(f.isDirectory()){ deleteFolder(f); f.delete(); } } folder.delete(); } public static String getDir(Scanner sc) { String strFolder; while (true){ if( sc.hasNext()){ strFolder = sc.nextLine(); break; } } return strFolder; } } 复制文件到指定文件夹下 源文件夹, 目标文件夹 在目标文件夹中创建源文件夹 遍历源文件夹, 文件则调用stream 复制到目标文件夹/源文件夹, 文件夹则递归调用 import java.io.*; public class Demo3_MvFolder { public static void main(String[] args) throws IOException { File folderSrc = new File("test"); File folderDes = new File("des"); copyFile3(folderSrc, folderDes); } public static void copyFile3(File folderSrc, File folderDes) throws IOException { if(! folderDes.isDirectory()){ System.out.println("请复制到文件夹中"); return; } File newFolder = new File(folderDes, folderSrc.getName()); newFolder.mkdir(); for(File f : folderSrc.listFiles()){ if( f.isFile()){ fileStream(f.getAbsolutePath(), newFolder.getAbsolutePath()+"/"+f.getName()); } else{ copyFile3(f, newFolder); } } } public static void copyFile2(File folderSrc, File folderDes) throws IOException{ if(! folderDes.isDirectory()){ System.out.println("请复制到文件夹中"); return; } File tempFolder = new File(folderDes.getAbsolutePath()+"/"+folderSrc.getName()); if( folderSrc.isDirectory()){ tempFolder.mkdir(); } for( File f : folderSrc.listFiles()){ if( f.isFile()){ fileStream(f.getAbsolutePath(), tempFolder.getAbsolutePath()+"/"+f.getName()); } else { copyFile2(f, tempFolder); } } } public static void copyFile(File folderSrc, File folderDes) throws IOException { if(! folderDes.isDirectory()){ System.out.println("请复制到文件夹中"); return; } if( folderSrc.isDirectory()){ new File(folderDes.getAbsolutePath()+"/"+folderSrc).mkdir(); } for(File f: folderSrc.listFiles()){ if ( f.isFile()){ fileStream(f.getAbsolutePath(), (folderDes.getAbsolutePath()+"/"+f.getPath())); } else if( f.isDirectory()){ copyFile(f, folderDes); } } } public static void fileStream(String src, String desc) throws IOException{ FileInputStream fis = new FileInputStream(src); int len; byte[] arr = new byte[1024*100]; FileOutputStream fos = new FileOutputStream(desc); while ( (len = fis.read(arr)) != -1){ fos.write(arr,0,len); } fis.close(); fos.close(); } } 打印文件夹的内文件, 保持层级 import java.io.File; public class Demo4_PrintFolder { public static void main(String[] args) { File folder = new File("test"); int lev = 0; printFolder(folder, lev); } public static void printFolder(File folder , int lev){ System.out.println(folder.getPath()); for ( File f : folder.listFiles()){ for (int i=0;i<=lev;i++){ System.out.print("\t"); } if(f.isFile()){ System.out.println(f.getPath()); } else { // lev不能用lev++或++lev, 改变了lev值 printFolder(f, lev+1); } } } } 斐波那契数列 public class Demo5_TwoZi { public static void main(String[] args) { System.out.println(twoZi(6)); } public static int twoZi(int month){ int sum = 0; if(month > 2){ sum = twoZi(month-1) + twoZi(month-2); } else if(month == 2){ sum = 1; } else if(1 == month){ sum = 1; } return sum; } } 1000的阶乘, 其中所有0和尾部0的个数 import java.math.BigInteger; public class Demo6_1000JieChen { public static void main(String[] args) { BigInteger bi = new BigInteger("1"); for(int i=1;i<=1000;i++) { BigInteger tmepBi = new BigInteger(i + ""); bi = bi.multiply(tmepBi); } int sum = 0; String str = String.valueOf(bi); for(int i=0;i<str.length();i++){ if('0'== (str.charAt(i))){ sum++; } } int num = 0; for(int j=str.length()-1;j>=0;j--){ if( '0' == str.charAt(j)){ num++; } else { break; } } System.out.println(sum); System.out.println(num); } } 约瑟夫环 import java.util.ArrayList; import java.util.Iterator; public class Demo7_LuckYue { public static void main(String[] args) { int num = 8; System.out.println(getLuck(num)); System.out.println(getLuck2(num)); } public static int getLuck2(int num) { ArrayList<Integer> arrayList = new ArrayList<>(); for(int i=1;i<= num;i++){ arrayList.add(i); } int sum = 1; for(int i=0; arrayList.size()!=1;i++){ if( i == arrayList.size() ){ i = 0; } if(0 == sum % 3){ arrayList.remove(i--); } sum ++; } return arrayList.get(0); } public static int getLuck(int num){ ArrayList<Integer> arrayList = new ArrayList<>(); for(int i=1;i<= num;i++){ arrayList.add(i); } int sum = 0; while (arrayList.size() > 1){ Iterator<Integer> iterator = arrayList.iterator() ; while (iterator.hasNext()){ Integer i = iterator.next(); // next()和remove方法依赖关系 sum++; if(0 == sum % 3){ iterator.remove(); } } } return arrayList.get(0); } }

September 8, 2021&nbsp;·&nbsp;4 分钟&nbsp;·&nbsp;Lizicai

Java的IO其他流(及Properties) Li.044

序列流 SequenceInputStream 关闭时会关闭所有流 public class Demo1_Stream { public static void main(String[] args) throws IOException { FileInputStream fr1 = new FileInputStream("read1.md"); FileInputStream fr2 = new FileInputStream("read2.md"); SequenceInputStream sis = new SequenceInputStream(fr1,fr2); FileOutputStream fos = new FileOutputStream("read3.md"); int b ; while ( ( b = sis.read()) != -1){ fos.write(b); } sis.close(); fos.close(); } public static void demo1() throws IOException { FileInputStream fr1 = new FileInputStream("read1.md"); FileOutputStream fos = new FileOutputStream("read3.md"); int b; while ((b = fr1.read()) != -1) { fos.write(b); } fr1.close(); FileInputStream fr2 = new FileInputStream("read2.md"); while ((b = fr2.read()) != -1) { fos.write(b); } fr2.close(); fos.close(); } } IO 流整合多个 public class Demo1_Stream { public static void main(String[] args) throws IOException { Vector<FileInputStream> v = new Vector<>(); FileInputStream fr1 = new FileInputStream("read1.md"); FileInputStream fr2 = new FileInputStream("read2.md"); v.add(fr1); v.add(fr2); Enumeration<FileInputStream> en = v.elements(); SequenceInputStream sis = new SequenceInputStream(en); FileOutputStream fos = new FileOutputStream("read3.md"); int b ; while ( (b = sis.read()) != -1){ fos.write(b); } sis.close(); fos.close(); } } ByteArrayOutputStream 获取数据 ByteArrayOutputStream 的 toString 可直接转为默认或指定的字符 import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; public class Deom2_ByteArrayOutputStream { public static void main(String[] args) throws IOException { FileInputStream fi = new FileInputStream("read1.md"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int b ; while ( (b = fi.read()) != -1){ baos.write(b); } fi.close(); System.out.println(baos.toString()); System.out.println(baos.toString("utf-8")); } private static void Demo1() throws IOException { FileInputStream fi = new FileInputStream("read1.md"); byte[] arr = new byte[3]; int len; while ( ( len = fi.read(arr)) != -1){ System.out.println(new String(arr,0,len)); } fi.close(); } } 内存输出 import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; public class Demo3_Test { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("read1.md"); byte[] arr = new byte[5]; int len; ByteArrayOutputStream bos = new ByteArrayOutputStream(); while ( (len = fis.read(arr)) != -1){ bos.write(arr,0,len); } fis.close(); System.out.println(bos.toString()); bos.close(); } } 随机读和存 RandomAccessFile import java.io.IOException; import java.io.RandomAccessFile; public class Demo4_RandomAccessFile { public static void main(String[] args) throws IOException { // Demo1(); Demo2(); } public static void Demo2() throws IOException{ RandomAccessFile raf = new RandomAccessFile("random.txt","rw"); int b; while ( (b = raf.read()) != -1){ System.out.println(b); } raf.close(); } private static void Demo1() throws IOException { RandomAccessFile raf = new RandomAccessFile("random.txt","rw"); raf.write(97); raf.seek(10); raf.write(98); raf.close(); } } 对象操作流 ObjecOutputStream 输出对象流, 序列化 import com.lizicai.bean.Person; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class Demo5_ObjectOutputStream { public static void main(String[] args) throws IOException { Person p1 = new Person("小明", 23); Person p2 = new Person("小红", 23); ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("person.txt")); oos.writeObject(p1); oos.writeObject(p2); oos.close(); } } 读取对象流 import com.lizicai.bean.Person; import java.io.*; public class Deom6_ObjectInputStream { public static void main(String[] args) throws IOException, ClassNotFoundException { ObjectInputStream oos = new ObjectInputStream(new FileInputStream("person.txt")); Person p1 = (Person) oos.readObject(); System.out.println(p1.getName()+p1.getAge()); Person p2 = (Person) oos.readObject(); System.out.println(p2.getName()+p2.getAge()); } } 对象操作优化 对象放入集合中, 集合输出到流 import com.lizicai.bean.Person; import java.io.*; import java.util.ArrayList; public class Demo7_OptimeObjectStream { public static void main(String[] args) throws IOException, ClassNotFoundException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("hashSetPerson.txt")); ArrayList<Person> arrayList = new ArrayList<>(); arrayList.add(new Person("小明",25)); arrayList.add(new Person("小红",23)); arrayList.add(new Person("小王",26)); oos.writeObject(arrayList); oos.close(); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("hashSetPerson.txt")); ArrayList<Person> personArrayList = ( ArrayList<Person> ) ois.readObject(); for(Person p : personArrayList){ System.out.println(p.getName() + p.getAge()); } } } IO 流增加 id 号 更改Person属性时更改serialVersionUID 可以准备知道原来Persion和现在Persion属性区别 import java.io.Serializable; public class Person implements Serializable { private static final long serialVersionUID= 1L; private String name; private int age; public Person(){} public Person(String name, int age) { this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } } IO 基本数据流, DataInputStream DataOutputStream import java.io.*; public class Demo8_DataInputStream { public static void main(String[] args) throws IOException { Demo1(); DataOutputStream dos = new DataOutputStream(new FileOutputStream("outData.txt")); dos.writeInt(997); dos.writeInt(998); dos.writeInt(999); dos.close(); DataInputStream dis = new DataInputStream(new FileInputStream("outData.txt")); int x = dis.readInt(); int y = dis.readInt(); int z = dis.readInt(); System.out.println(x); System.out.println(y); System.out.println(z); dis.close(); } private static void Demo1() throws IOException { FileOutputStream fos = new FileOutputStream("output.txt"); fos.write(997); fos.close(); } private static void Demo2() throws IOException { FileInputStream fis = new FileInputStream("output.txt"); int b = fis.read(); fis.close(); } } 打印流的概述和特点 PrintStream 和 PrintWriter 分别是打印的字节流和字符流 只操作数据目的 自动刷出作用不大 import java.io.*; public class Demo9_PrintStream { public static void main(String[] args) throws IOException { // Demo2(); PrintWriter pw = new PrintWriter(new FileOutputStream("printWriter.txt"), true); pw.println(97); } private static void Demo2() throws FileNotFoundException { PrintWriter pw = new PrintWriter("printWriter.txt"); pw.println(97); pw.write(97); pw.flush(); pw.close(); } private static void demo1() { PrintStream p = System.out; p.println("Hello World!"); p.write(97); p.close(); } } 标准输入输出流概述和输出语句 标准输入只有1个, 未关联到文件, 不用关闭, 关闭后无法打开了 标准输出流未关联文件, 也不用关闭 import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; public class Demo10_SystemInOut { public static void main(String[] args) throws IOException { // demo1(); System.setIn(new FileInputStream("systemin.txt")); System.setOut(new PrintStream("systemout.txt")); InputStream is = System.in; PrintStream ps = System.out; int b; while ( ( b = is.read()) != -1){ ps.write(b); } is.close(); ps.close(); } private static void demo1() throws IOException { InputStream is = System.in; int x = is.read(); System.out.println(x); is.close(); InputStream is2 = System.in; int y = is2.read(); System.out.println(y); } } 练习, 复制文件, 增加使用数组, 增加复制速度 import java.io.*; public class Demo11_SystemInOutTest { public static void main(String[] args) throws IOException { System.setIn(new FileInputStream("systemin.txt")); System.setOut(new PrintStream("systemout.txt")); InputStream is = System.in; PrintStream ps = System.out; byte [] arr = new byte[1024]; int len; while ( ( len = is.read(arr)) != -1){ ps.write(arr,0,len); } is.close(); ps.close(); } } 2种键盘录入方式 import java.util.Scanner; public class Demo12_SystemIn { public static void main(String[] args) throws IOException { // demo1(); Scanner sc = new Scanner(System.in); String s = null; if(sc.hasNext()){ s = sc.nextLine(); } System.out.println(s); } private static void demo1() throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line = br.readLine(); System.out.println(line); } } Properties的概述和作为Map集合的使用 Object setProperty(String key, String value) 添加键值对 Enumeration<?> propertyNames() 获取 key值枚举 String getProperty(String key) 根据key 值获取 value import java.util.Enumeration; import java.util.Properties; public class Demo13_Properties { public static void main(String[] args) { // demo1(); Properties pp = new Properties(); pp.setProperty("name", "小明"); pp.setProperty("tel", "12310001000"); System.out.println(pp); Enumeration <String> en = (Enumeration<String>) pp.propertyNames(); while ( en.hasMoreElements()){ String key = en.nextElement(); System.out.println(key+pp.getProperty(key)); } } private static void demo1() { Properties p = new Properties(); p.put("intA", 12); System.out.println(p); } } Properties 读和存 void load(InputStream inStream) throws IOException 读取文件 void store(OutputStream out, String comments) throws IOException 写到文件, comments 加入注释 import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Properties; public class Demo13_Properties { public static void main(String[] args) throws IOException { Properties pp = new Properties(); System.out.println(pp); pp.load(new FileInputStream("config.properties")); System.out.println(pp); pp.setProperty("qq","123"); System.out.println(pp); pp.store(new FileOutputStream("config.properties"), "utf-8"); } }

September 6, 2021&nbsp;·&nbsp;5 分钟&nbsp;·&nbsp;Lizicai

Java的Reader和Writer类 Li.043

FileReader 读取文件 import java.io.FileReader; import java.io.IOException; public class Demo1_FileReader { public static void main(String[] args) throws IOException { // Demo1(); FileReader fr = new FileReader("m.txt"); int b ; while ( (b = fr.read()) != -1){ System.out.println((char)b); } fr.close(); } private static void Demo1() throws IOException { FileReader fr = new FileReader("m.txt"); int x = fr.read(); System.out.println(x); System.out.println((char)x); } } FileWriter 字符写入文件 import java.io.FileWriter; import java.io.IOException; public class Demo2_FileWriter { public static void main(String[] args) throws IOException { FileWriter fw = new FileWriter("output.txt"); String s = "这只羊叫Leon"; fw.write(s); fw.flush(); fw.close(); } } 字符复制 import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo3_ReaderWriter { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("input.txt"); FileWriter fw = new FileWriter("output.txt"); int b ; while ( (b = fr.read()) != -1){ fw.write(b); } fr.close(); fw.close(); } } 什么情况使用使用字符流 字符流也能复制文件, 但不推荐, 字节->字符, 字符->字节 多一步转换 程序需要读取一段文本, 或都需要写入一段文本的时候可以使用字符流 读取的时候按字符读出, 不会出现半个中文 写出时可直接字符串写出, 不用转换为字节数组 图片类文件不能使用字符流复制, 丢失数据 自定义数组复制 import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo4_ReaderWriter { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("input.txt"); FileWriter fw = new FileWriter("output.txt"); char[] arr = new char[1024]; int len; while ( (len = fr.read(arr)) != -1){ fw.write(arr, 0 , len); } fr.close(); fw.close(); } } BufferedReader 和 BufferedWriter 读取写入字符 import java.io.*; public class Demo5_BufferedReader { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader("input.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt")); int b ; while ( (b=br.read()) != -1){ bw.write(b); } br.close(); bw.close(); } } BufferedReader readLine()方法, BufferedWriter 的newLine方法 newLine 没有放在write(line)后, 并写在循环内, 这样写多写一个空行 import java.io.*; public class Demo6_ReadLine { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader("input.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt")); String line ; if( (line = br.readLine() ) != null ){ bw.write(line); } while ( (line = br.readLine()) != null){ bw.newLine(); bw.write(line); } br.close(); bw.close(); } } 练习, 读取行, 并行数反向输出 流, 最好晚开早关 import java.io.*; import java.util.ArrayList; public class Demo7_ReverseLine { public static void main(String[] args) throws IOException { ArrayList<String> arrayList = new ArrayList<>(); String str ; BufferedReader br = new BufferedReader(new FileReader("input.txt")); while( ( str=br.readLine()) != null){ arrayList.add(str); } br.close(); BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt")); for(int i= arrayList.size()-1;i>=0 ;i--){ bw.write(arrayList.get(i)); if( i == 0 ){ break; } bw.newLine(); } bw.close(); } } LineNumberReader import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; public class Demo8_LineNumberReader { public static void main(String[] args) throws IOException { LineNumberReader lnr = new LineNumberReader(new FileReader("input.txt")); String line; lnr.setLineNumber(3); while ( (line = lnr.readLine()) != null){ System.out.println(lnr.getLineNumber() + " "+line); } lnr.close(); } } 装饰设计模式 使用被装饰的类, 对类中方法升级增加内容 好处 耦合性不强, 被装饰类的变化与装饰类的变化无关 public class Demo9_Wrap { public static void main(String[] args) { JiuCai j = new JiuCai(new Student()); j.code(); } } class Student { private String name; private int age; public void code(){ System.out.println("C"); System.out.println("Java"); } } interface Coder{ public void code(); } class JiuCai implements Coder{ JiuCai (Student stu){ this.stu = stu; } private Student stu; @Override public void code() { stu.code(); System.out.println("JavaEE"); System.out.println("SprintBoot"); } } 使用指定被码表读写字符 utf8格式写到gbk中, 乱码 ...

September 2, 2021&nbsp;·&nbsp;4 分钟&nbsp;·&nbsp;Lizicai