File类概述和构造方法
File类的构造方法:均不需要改文件存在
File(String pathname)
File(String parent,String child)
File(File parent,String child)
File类的创建功能
注意 文件和文件夹(路径)不能重名,即不能同时有a.txt文件和文件夹
createNewFile() 创建文件
mkdir() 创建一级目录
mkdirs() 创建多级目录
File类的删除功能
delete() 删除此抽象路径名表示的文件或目录,删除目录时,需要先删除改目录下的内容(目录/文件)
File类的判断和获取 功能
isDirectory()
isFile()
exists() : 某个路径的File是否存在
getAbsolutePath() :返回绝对路径字符串
getPath() :返回路径名字符串
getName():拿到文件或目录的名称
list():拿到文件和目录的名称字符串数组,文件和目录名称均可以拿到
listFiles():返回文件和目录的File对象数组,只能拿到文件名称,不能拿到目录名称
递归
递归二要素:① 递归出口 ② 将要完成的大问题(可以是需求中的一部分问题,需k步完成)分解成若干个同问题的小问题(需k-i步完成),并且第k-i 步的问题也能由②的思想接着细分下去。
递归:输出给定文件夹下的所有文件路径 = 输出下一级目录下的所有文件路径
public static void main(){ File srcFile = new File("D://hd"); getAllFilePath(srcFile); } // 定义一个方法,用户获取给定目录下的所有文件或者目录的数组 public static void getAll FilePath(File srcFile) { // 获取改目录下所有的文件或者目录的File数组 File[] fileArray = srcFile.listFiles(); if(fileArray != null){ for (File file : fileArray){ if (file.isDirectory()){ // 如果是文件夹,继续递归 getAllFilePath(file); } else { // 递归出口:当拿到目录的最后一级:文件时 System.out.println(file.getAbsolutePath()); } } } }
IO流概述和分类
IO:输入、输出
流:一种抽象概念,是对数据传输的总称,也就是说数据在设备间的传输称为流,流的本质是数据传输
IO流就是用来处理设备间数据传输问题的
常见的应用:文件复制,文件上传,文件下载
IO流的分类:
字节流的应用
字节流写数据
写数据步骤
① 创建字节输出流对象(A:调用系统功能创建文件 B 创建字节输出流对象 C 让字节输出流对象指向文件)
② 调用字节输出流对象的写数据方法(write)
③ 释放资源(关闭文件输出流,释放与此流相关的资源)
字节写数据的三种方法:
write的三个重写方法
字节流换行:
write("\r\n".getBytes()) (Windows系统)
字节流追加写入
public FileOutputStream(String name , boolean append)
当第二个参数 未true,则字节将写入文件的末尾而非开头
写数据异常处理 -- 加入finally处理异常
字节流读数据
步骤:
1 创建字节输入流对象
2 调用字节输入流对象的读数据方法 (read)
3 释放资源
复制文本文件
public static void main(String[] args) throw IOException { // 根据数据源创建字节输入流对象 FileInputStream fis = new FileInputStream("E:\\itcast\\hd.txt"); // 根据目的地创建输出流对象 FileOutputStream fos = new FileOutputStream("D:\\java\hd.txt"); // 读写数据,复制文本文件 int by; while((by = fis.read())! = -1) { fos.write(by); } // 释放资源 fos.close(); fis.close(); }
// 复制图片 FileInputStream fis = new FileInputStream("E:\\itcast\\mn.jpg"); FileOutputStream fos = new FileOutputStream("hd\\mn.jpg"); byte[]bys = new byte[1024]; int len; while((len = fis.read(bys))!=-1){ fos.write(bys,0,len); } // 释放资源 fos.close(); fis.close();
字节缓冲流一次读写一个字节数组复制视频
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\hd")); BufferedOutputStream bos = new BufferedOutputStream(new FileInputStream("D:\\hd\\hh")); byte[] bys = new byte[1024]; int len while((len = bis.read(bys))!=-1){ bos.write(bys,0,len); } bos.close(); bis.close();
字符流的应用:
解决汉字问题:字符流 = 字节流+编码表
GBK编码,一个汉字占用2个字节。UTF-8编码,占用3个字节
IO流练习
集合到文件
ArrayList<String> array = new ArrayList<String>(); array.add("hello"); array.add("world"); BufferedWriter bw = new BufferedWriter("hd\\hh.txt"); for(String s : array){ bw.write(s); bw.newLine(); // 换行 bw.flush(); // 刷新 } bw.close();
集合到文件
BufferReader br = new BufferedReader(new FileReader("hd\\hd.txt")); ArrayList<String> array = new ArrayList<String>(); String line; while((line = br.readLine())!= null) { array.add(line); } br.close(); System.out.println(array);
Lambda表达式格式
(形式参数)-> {代码块}
形式参数,如果有多个,参数之间用','隔开
代码块:具体要做的事情,也就是以前方法体中的内容
①lambda表达式要和接口一起使用,并且接口中有且仅有一个抽象方法
② lambda表达式使用时不能单独使用,必须有上下文环境(1.局部变量的赋值 Runnable r = ()->System.out.println("lambda表达式") 2. 调用方法的参数 new Thread(()->System.out.println("lambda表达式")).start();)
useAddable((int x, int y)->{
return x - y;
})
注意点:
如果有多个参数,可以省略全部参数类型,或者全部不省略
如果只有一个参数,既可以省略掉参数类型,也可以省略掉小括号
如果代码块的语句只有一条,可以省略大括号和分号,甚至是return
Stream流
Stream流一般和lambda表达式相结合使用
对list集合过滤并输出
list.stream().filter(s -> s.startWith("张")).filter(s->s.length() == 3).forEach(s -> System.out.println(s));
Stream流的使用
生成流
通过数据源(集合,数组等)生成流
① Collection体系集合:list和set: 直接生成流。list.stream(); set.stream();
② Map体系的集合间接生成流:Map<String,Integer> map; map.keySet().stream; map.values().stream();map.entrySet().stream()
③ 数组体系通过Stream接口的静态方法of(T.. values)生成流
Stream.of(Array); Stream.of(10,20,30);
流的中间操作
①filter:过滤,其中放入一个lambda 表达式,用于过滤不符合改表达式的数据
②limit(long maxSize): 截取前maxSize个的数据
③skip(long n): 跳过前n个元素,返回其他的元素
④Stream.concat(s1,s2)合并流s1和s2的结果
⑤Stream.concat(s1,s2).distinct() 合并流 s1和s2,并保证数据的唯一性。
⑥sorted((s1,s2)->s1.length - s2.length).forEach(System.out.println()); // 按照长度排序
⑦ mapToInt : list.stream().mapToInt(Integer::parseInt).sum(); // 将值转成Int后再求和
⑧ map(..)将流转换成map中参数类型的对象
流的终结操作
① forEach() : 对此流的每个元素执行操作
② count() :返回此流中的元素数
流的收集操作
stream.collect(Collectors.toList()); // 将流收集成List
stream.collect(Collectors.toSet()); // 将流收集成set
stream.collect(Collectors.toMap(s -> s.split(",")[0], s->Integer.parseInt(s.split(",")[1]))); // 两个lambda表达式,一个针对key,一个针对value . 得到的集合,键为String,值为value
反射概述
java反射机制:是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展。
获取对象的三种方式
①Class<Student> c1 = Student.class;
②Student s = new Student(); Class<? extends Student> c3 = s.getClass();
③Class<?> c4 = Class.forName("com.hd.Student"); // Sudent类的资源路径
反射获取构造方法并使用
Class<?> c = Class.forName("com.hd.Student"); Constructor<?>[] cons = c.getConstrutors; // 得到所有的公共构造方法 Constructor<?>[] cons1 = c.getDeclaredConstructors(); // 拿到所有的构造方法,包括保护的和私有的 Constructor<?> con = c.getConstructor(); // 拿到一个构造方法 Object obj = con.newInstance(); // 返回无参构造方法对象,抽象类对应Object // getConstructor中的参数也是class,基本数据类型也可以通过.class得到对应的CLass类型 // 暴力反射 // 正常来说,其他类的私有构造方法是不能在本类中创建对象的。但是反射可以设置取消访问检查 Constructor<?> con = c.getDeclaredConstructor(String.class); con.setAccessible(true); //设置取消访问检查 Object obj = con.newInstance("hd"); // 得到构造方法对象
反射获取成员变量并使用
Class<?> c = Class.forName("com.hd.Student"); Field[] fields = c.getFields(); // 拿到所有公共的成员变量 Field[] fields = c.getDeclaredFields(); // 拿到所有的成员变量 // 拿到单个公共成员变量并对其赋值 Field nameField = c.getField("name"); // 获取无参构造方法并创建对象 Constructor<?> con = c.getConstructor(); Object obj = con.newInstance(); nameField.set(obj,"hd"); // 给obj的成员变量nameField赋值为hd // 对于私有成员变量 Field ageField = c.getDeclaredField("age"); // 赋值前需要暴力反射 ageField.setAccessible(true); // 对obj对象的ageField变量赋值 ageField.set(obj,"12");
反射获取成员方法并使用
Class<?> c = Class.forName("com.hd.Student"); // 拿到该类以及其父类的所有公共方法 Method[] methods = c.getMethods(); // 拿到该类的所有方法,不包含父类的 Method[] methods1 = c.getDeclaredMethods(); // 获取单个方法 Method m = c.getMethod("method1"); //其中method1是一个无参方法名 Constructor<?> con = c.getConstructor(); Object obj = con.newInstance(); // 获得无参构造对象 m.invoke(obj); // 在该对象中调用method1方法
反射练习
-
通过反射在List<Integer>list 中添加String类型的值并输出
-
通过反射运行配置文件指定的内容。
进程与线程
进程:正在运行的程序。打开资源管理器可以查看有哪些进程即哪些程序在运行。
线程:是进程中的单个顺序控制流,是一条执行路径
单线程:一个进程只有一条执行路径,则称为单线程程序。如记事本在编辑格式时不能编写记事本内容
多线程:一个进程如果有多条执行路径,则称为多线程程序。如在玩游戏时,游戏的操作和计时是两条路径,互不干扰,可以同时进行
多线程实现方式
方式一:继承Thread类
定义一个类MyThread继承Thread
在MyThread类中重写run方法
创建MyThread类的对象
启动线程start();
MyThread my1 = new MyThread(); MyThread my2 = new MyThread(); m1.start(); m2.start(); public class Mythread extends Thread{ @Override public void run(){ for(int i = 0; i<100;i++){ System.out.println(i); } } }
获取线程名称的三种方法:
构造方法中,无参构造+setName,getName。有参构造中参数即为名称。共两种,静态方法中共一种得到当前线程名称
线程优先级的设置
Thread.getPriority()和Thread.setPriority()
优先级范围:1-10,默认为5。数字越大,该线程获取时间片的几率越大。
线程的Sleep,join和Deamon
sleep:让线程休眠
join:设置线程优先执行,执行完后,其余线程才能执行
Deamon:设置线程为守护线程,当主线程执行完后,守护线程就会停止
Runnable实现线程
Runnable可以去extends其他的类,避免了Java单继承的局限性
synchronized同步代码块:解决多线程操作共享数据问题
缺点:每个线程都会加锁,会降低运行效率
synchronized 同步方法:解决多线程操作共享数据问题
同步普通方法的锁默认为this,同步静态方法的锁为类名.Class,即类的字节码对象-反射
线程安全的三个类:StringBuff,Vector,Hashtable
Lock锁
经典案例 - 生产者与消费者
Box类:
网络编程入门
在网络通信协议下,实现网络互联的不同计算机上运行的程序间可以进行数据交换
InetAddress
InetAddress address = InetAddress.getName("192.168.1.66");// 拿到主机名字
address.getHostName() ;// 获取Ip地址的主机名
address.getHostAddress(); // 返回文本显示中的Ip字符串
端口与协议
UDP发送数据
// ①创建发送端的Socker对象, // ②创建数据,并把数据打包 // ③调用DatagramSocket对象的方法发送数据 // ④关闭发送端 DatagramSocket ds = new DatagramSocket(); byte[] bys = "hello ,udp"; int length = bys.length; int port = 123456; DatagramPacket dp = new DatagramPacket(ds,bys,length,port); ds.send(dp); ds.close();
UDP接收数据
// ①创建接收端的Socker对象, // ②创建数据包,用于接收数据 // ③调用DatagramSocket对象的方法接收数据 // ④解析数据包 ,并把数据显示在控制台 // ④关闭接收端 DatagramSocket ds = new DatagramSocket(123456); byte[] bys = new byte[1024]; DatagramPacket dp = new DatagramPacket(ds,bys.length); ds.receive(dp); byte[]datas = dp.getData(); int len = dp.getLength(); String dataString = new String(data,0,len); sout(dataString); ds.close();
UDP通信程序练习
public class DataReceive { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(12345); while (true){ byte[] bys = new byte[1024]; DatagramPacket dp = new DatagramPacket(bys,bys.length); // 调用DatagramSocket对象的方法接收数据 ds.receive(dp); System.out.println("数据是:"+new String(dp.getData(),0,dp.getLength())); } } }
public class DataSend { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line; while ((line = br.readLine()) !=null){ if ("886".equals(line)){ break; } byte[]bys = line.getBytes(); DatagramPacket dp = new DatagramPacket (bys,bys.length, InetAddress.getByName("192.168.79.235"), 12345); ds.send(dp); } ds.close(); } }
TCP通信程序练习
public class ClientDemo { public static void main(String[] args) throws IOException { Socket s = new Socket("192.168.79.235",11000); OutputStream os = s.getOutputStream(); os.write("hello,tcp".getBytes()); s.close(); } }
public class ServiceDemo { public static void main(String[] args) throws IOException { // 创建服务端socket对象 ServerSocket ss = new ServerSocket(11000); // 侦听要来连接到此套接字并接受它 Socket s = ss.accept(); // 获取输入流读数据 InputStream is = s.getInputStream(); byte[] bys = new byte[1024]; int len = is.read(bys); String data = new String(bys,0,len); System.out.println("数据是:"+data); s.close(); ss.close(); } }
mysql的foreach