文件操作
1、转换File对象
//一个带路径的字符串可以转换为File对象,指向该文件路
String str = "E:/笔记/第五周/20220920.md";//该字符串为文件路径
//转换File对象
File f = new File(str);//或者 File f = new File("E:/笔记/第五周/20220920.md")
2、判断文件是否存在
2.1、exits方法
File f = new File("E:/笔记/第五周/20220920.md")
boolean exists = f.exists();//true存在 flase不存在
System.out.println("文件是否存在:"+exists);
3、判断是否是文件夹
3.1、isDirectory方法
File f = new File("E:/笔记/第五周/20220920.md")
boolean directory = f.isDirectory();
System.out.println("是否是文件夹"+ directory);
4、判断是否是文件
4.1、isFile方法
File f = new File("E:/笔记/第五周/20220920.md")
boolean file = f.isFile();
System.out.println("是否是文件:"+ file);
5、获取文件名
5.1、getName方法
File f = new File("E:/笔记/第五周/20220920.md")
String fileName = f.getName();
System.out.println("文件名是:"+ fileName);
6、获取文件大小
6.1、length方法
File f = new File("E:/笔记/第五周/20220920.md")
long length = f.length();
System.out.println("文件大小是:"+ length);
7、相关权限
7.1、文件可读read
boolean read = f.canRead();//是否可读
7.2、文件可写write
boolean write = f.canWrite();//是否可写
8、创建一个空文件
8.1、createNewFile方法
boolean r = f.createNewFile();
System.out.println(r);
File z = new File("E:/新笔记");
z.mkdir();//创建一个物理目录
9、删除文件夹(文件)
File z = new File("E:/新笔记");
z.delete();//删除,如果里面有内容,就不能删除
9.1、遍历删除文件夹目录下所有的文件
// 需求:定义方法,把素材3里面所有的目录和文件全部删除 (可使用递归算法,也可以通过框架的方法来实现)
public class Demo7 {
public static void show(File baseFileDir,int level){
File[] subFiles = baseFileDir.listFiles();
for (File subFile:subFiles) {
if (subFile.isFile()) {//是文件
subFile.delete();
System.out.println("删除成功"+ baseFileDir.getName());
}else {
for (int i = 0; i < level; i++) {
subFile.delete();
}
System.out.println(subFile+"删除成功"+ baseFileDir.getName());
show(subFile,level+1);
}
}
}
public static void main(String[] args) {
//获取根目录
File baseFileDir = new File("src/com/company/Day20/素材");
show(baseFileDir,1);
}
}
10、获取下一级文件目录
10.1、遍历文件夹目录
File f = new File("E:/笔记/第五周/20220920.md")
String[] list = f.list();
File[] fi = f.listFiles();
for (String l:list) {
System.out.println(fi.getClass());
}
public class Demo4 {
//需求:打印所有目录名称和文件名称
public static void printFile(String strPath) {
File dir = new File(strPath);//传参:将路径传给File对象
File[] files = dir.listFiles(); // 该文件夹目录下所有文件全部放入数组
if (files != null) {
for (int i = 0; i < files.length; i++) {//遍历所有文件
System.out.println("文件名:"+files[i].getName());
if (files[i].isDirectory()) { // 判断是文件还是文件夹
printFile(files[i].getAbsolutePath()); // 获取文件绝对路径
System.out.println("文件地址:"+files[i].getAbsolutePath() + "\t文件夹名:"+files[i].getName());
}
}
}
}
public static void main(String[] args) {
printFile("E:/hello/src/com/company/Day20/素材3");
}
}
11、获取时间
11.1、LocalDate方法
LocalDate localDatebirth = LocalDate.parse(birthday);
11.2、获取当前时间
LocalDate localDate = LocalDate.now();
11.3、获取年、月、日
int birthYear = localDatebirth.getYear();
int birthMonth = localDatebirth.getMonthValue();
int birthDay = localDatebirth.getDayOfMonth()
12、文件、图片、视频、MP3拷贝
12.1、Apache框架
/*
需求1:把小乔这个图片,拷贝到备份目录里面
*/
public class Demo3 implements Serializable{
public static void main(String[] args){
File srcFile = new File("E:/hello/src/com/company/Day20/素材2/images/小乔.jpg");
// File desFile = new File("E:/hello/src/com/company/Day20/素材2/备份");
// FileUtils.copyFileToDirectory(srcFile,desFile);//拷贝图片
// System.out.println("拷贝成功");
}
}
/*
写法一:
需求2:把所有图片全部拷贝在备份目录里面
*/
public class Demo3 implements Serializable{
public static void main(String[] args){
File srcFile = new File("E:/hello/src/com/company/Day20/素材2/images");
File desFile = new File("E:/hello/src/com/company/Day20/素材2/备份");
FileUtils.copyDirectory(srcFile,desFile);//copyDirectory拷贝目录下所有的文件
System.out.println("拷贝成功");
}
/*
写法二:
需求2:把所有图片全部拷贝在备份目录里面
*/
public class Demo3 implements Serializable{
public static void main(String[] args){
try {
BufferedReader reader = new BufferedReader(new FileReader("E:/hello/src/com/company/Day20/素材2/images"));
String str = null;
while ((str = reader.readLine()) != null){
}
}catch (Exception e){
e.printStackTrace();
}
}
}
13、文件读取
13.1、读取文件里没有交作业的人员
//写一个查询没有交作业的人员程序
@Test
public void ZuoYe() throws IOException {
try {
//老师写的
//1、读取人员名单【因为是文件一个又一个字节组成的,所以用BufferedReader】
BufferedReader bufferedReader = new BufferedReader(new FileReader("E:/hello/src/com/company/Day20/素材1/人员名单.txt"));
//存放人员名单
List<String> personList = new ArrayList<>();
//一行一行的读
String tx= null;
while ((tx = bufferedReader.readLine()) != null){
personList.add(tx);
}
//2、获取文件夹里面的所有文件
//创建一个File对象得到作品清单物理地址
File dir = new File("E:/hello/src/com/company/Day20/素材1/作业情况");
//获取下一级目录,就是已交作业的名单
String[] list = dir.list();//获取文件,如陆小凤_作业.txt
System.out.println("已交作业的名单:");
//获取已提交作业的名单
for (String s:list) {
System.out.println(s.substring(0,s.indexOf("_")));//截取文件名,比如陆小凤_作业.txt从第一个字符截取到_之前就结束
}
//获取未提交作业的名单
System.out.println("未交作业清单:");
List<String> unworkList = new ArrayList<>();
for (String person:personList) {
boolean r = true;//未提交作业的是true,提交作业的就是false
for (String s1 : list) {
if (person.equals(s1.substring(0, s1.indexOf("_")))) {
r = false;
break;
}
}
if (r) {
unworkList.add(person);
}
}
System.out.println(unworkList);
bufferedReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
13.2、读取人员名单中的人员,并且拷贝该些人的证件照
//写一个查询没有交作业的人员程序
@Test
public void ZuoYe() throws IOException {
try {
//老师写的
//1、读取人员名单【因为是文件一个又一个字节组成的,所以用BufferedReader】
BufferedReader bufferedReader = new BufferedReader(new FileReader("E:/hello/src/com/company/Day20/素材1/人员名单.txt"));
//存放人员名单
List<String> personList = new ArrayList<>();
//一行一行的读
String tx= null;
while ((tx = bufferedReader.readLine()) != null){
personList.add(tx);
}
//2、获取文件夹里面的所有文件
//创建一个File对象得到作品清单物理地址
File dir = new File("E:/hello/src/com/company/Day20/素材1/作业情况");
//获取下一级目录,就是已交作业的名单
String[] list = dir.list();//获取文件,如陆小凤_作业.txt
System.out.println("已交作业的名单:");
//获取已提交作业的名单
for (String s:list) {
System.out.println(s.substring(0,s.indexOf("_")));//截取文件名,比如陆小凤_作业.txt从第一个字符截取到_之前就结束
}
//获取未提交作业的名单
System.out.println("未交作业清单:");
List<String> unworkList = new ArrayList<>();
for (String person:personList) {
boolean r = true;//未提交作业的是true,提交作业的就是false
for (String s1 : list) {
if (person.equals(s1.substring(0, s1.indexOf("_")))) {
r = false;
break;
}
}
if (r) {
unworkList.add(person);
}
}
System.out.println(unworkList);
bufferedReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// try {
// //读取人员名单
// BufferedReader bufferedReader = new BufferedReader(new FileReader("E:/hello/src/com/company/Day20/素材3/人员名单.txt"));
// //创建人员集合
// ArrayList<String>personList = new ArrayList<>();
// //定义一个字符串,值为null
// String str = null;
// //读取出人员名单里的内容
// while ((str = bufferedReader.readLine()) != null){
// personList.add(str);
// }
// System.out.println(personList);
// File srcFile = new File("E:/hello/src/com/company/Day20/素材3/images");
// File desFile = new File("E:/hello/src/com/company/Day20/素材3/备份");
// ArrayList<String>list =new ArrayList<>();
// String[] lists = srcFile.list();
// for (String s:personList) {
//
// boolean r = false;
// for (String s1:lists) { System.out.println(s.substring(0,s.indexOf(".")));
// if(personList.contains(s1.substring(0,s.indexOf(".")))){
// r = true;
// break;
// }if(r){
// list.add(s);
//
//
// }FileUtils.copyDirectory(srcFile,desFile,r);
// }
//
//
// System.out.println(list);
//
//
// } System.out.println("拷贝成功");
// }catch (Exception e){
// e.printStackTrace();
// }
}
}
14、常用的FileUtils
cleanDirectory:清空目录,但不删除目录。
contentEquals:比较两个文件的内容是否相同。
copyDirectory:将一个目录内容拷贝到另一个目录。可以通过FileFilter过滤需要拷贝的 文件。
**copyFile**:将一个文件拷贝到一个新的地址。
**copyFileToDirectory**:将一个文件拷贝到某个目录下。
copyInputStreamToFile:将一个输入流中的内容拷贝到某个文件。
deleteDirectory:删除目录。
deleteQuietly:删除文件。
listFiles:列出指定目录下的所有文件。
openInputSteam:打开指定文件的输入流。
readFileToString:将文件内容作为字符串返回。
readLines:将文件内容按行返回到一个字符串数组中。
size:返回文件或目录的大小。
write:将字符串内容直接写到文件中。
writeByteArrayToFile:将字节数组内容写到文件中。
writeLines:将容器中的元素的toString方法返回的内容依次写入文件中。
writeStringToFile:将字符串内容写到文件中。
网络编程
1、网络编程三要素
1.1、IP地址
含义:如何定位到某台服务器
1.2、端口
含义:如何定位到某个程序
注意:端口最好不要用3306(数据库)、8080、8086
1.3、传输协议
1.3.1、TCP/IP
在Java中类名以Socker开头,是长连接,中途不可断开,传输可靠,但是比较消耗资源。
1.3.2、UDP
在Java在类名以Datagram开头,底层都是用的UDP
1.3.3、Http
超文本传输协议,Web架构,是基本TCP协议的应用层传输协议,简单说就是客户端和服务器端之间的一种数据传规则
1.3.4、其他自定义加密协议
2、网络编程核心API
2.1、服务器端(ServerSocket)
2.1.1、常用方法
- accept方法:等待客服端的连接,同时产生一个Socket对象和客户端建立一个通信管道
- 语法:Socket s = 对象名.accecp()
- 特点:该方法会阻塞(解决办法:利用多线程),直到客户端连接成功才执行下一句代码
- 如果要连接多个客户端,直接有循环就可以了
2.1.2、创建方式
-
语法:ServerSockt server = new ServerSoket(端口口);//默认的是自己本机地址,如果不想默认,则双引号+IP地址
-
调用bind方法,绑定IP和端口号(SocketAddress)
SocketAddress address = new InetSocketAddress("127.0.0.1",8888);//服务器端ServerSocket server = new ServerSocket(); //把IP和端口与服务器进行绑定 server.bind(address);
2.2、客户端(Socket)
2.2.1、常用方法
- getInputStream:从管道里面获取一个输入流,里面的数据是服务端发送过来的
- getOutStream:从管道俩民获取一个输出流,里面的数据是客服端发送过去的
- close:关闭和服务器端的连接
2.3、IP+端口
2.3.1、InetAddress
2.3.2、Inet4Address
2.3.3、Inet6Address
2.3.4、SocketAddress
3、线程
3.1、程序、进程、线程的理解
3.1.1、程序:就是一个完成的程序系统,如QQ
3.1.2、进程:进来一个程序,让其运行起来
3.1.3、线程:列如一个聊天程序可以给A发消息,也可以给B发消息,也可以接受消息
3.2、线程的作用
作用:可以解决只能处理一件事(实现一个功能),可以同时跑多个程序
3.3、线程的创建(main方法是主线程,JVM创建的)
3.3.1、通过Thread类来创建
/*
main方法里面打印1-100的偶数,新开一个线程打印1-100的奇数
*/
/*
方式一:通过Thread类来创建
*/
class PrintTask implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i % 2 != 0){
try {
Thread.sleep(100);//延时100毫秒
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
}
public class Thread2 {
public static void main(String[] args) {
//开一个线程:一个线程也是一个对象Thread
Thread t = new Thread(new PrintTask(),"子线程");
t.start();//调start方法的同时,会自动调PrintTask的run方法
//启动之前要告诉它要完成什么工作
for (int i = 0; i < 100; i++) {
//打印1-100偶数
if(i % 2 == 0){
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
}
3.3.2、通过Extend继承创建
/*
main方法里面打印1-100的偶数,新开一个线程打印1-100的奇数
*/
/*
方式二
通过继承创建新的线程
*/
public class ThreadExtendDemo extends Thread{
//继承Thread,调用Thread里面的run方法
@Override
public void run(){
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
}
public static void main(String[] args) {
ThreadExtendDemo t = new ThreadExtendDemo();
t.run();//调run方法
t.start();//启动线程,自动调run方法
}
}
3.3.3、通过线程池(ThreadPool)submit创建、
/*
main方法里面打印1-100的偶数,新开一个线程打印1-100的奇数
*/
/*
方式三:通过线程池创建管理线程
*/
public static void main(String[] args) {
/*
JUC:代表java.util.concurrent,这个包全部是线程相关的API
*/
//含义:创建一个按需增长的线程池,说白了就是里面线程很多,只管用就是了
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(new PrintTask());//自动帮我们创建1个线程来执行PrintTask任务
//在线程池里管理线程的执行任务
executorService.submit(() ->{
for (int i = 0; i < 100; i++) {
if(i % 2 ==0){
System.out.println(i);
}
}
});
executorService.submit(new PrintTask()::run);//把现有的方法,通过引用
executorService.shutdown();//关闭线程池,必须加上这句代码
}
}
3.4、线程的生命周期
3.4.1、新建状态
Thread t = new Thread((-> {方法体}));
3.4.2、就绪状态
start()方法:start方法,线程处于就绪状态,但是不会立即调用run方法,执行由CPU决定
3.4.3、运行状态
3.4.4、死亡(中断)状态
interrupt()方法:该方法让线程中断(死亡)
Thread.currentThread().interrupt();
3.4.5、阻塞(休眠)状态
sleep()方法:该方法让线程运行时处于阻塞(休眠)状态,当时间到了,线程则重新处于就绪状态
该方法的父类是native本地方法,是由底层c/c++构成的,不能开源,所以要放在try catch异常里
Thread thread2 = new Thread(() ->{
for (char i = 'a'; i <= 'z'; i++) {
//线程休眠状态
try {
Thread.sleep(100);//native:本地方法,不能开源
System.out.println(Thread.currentThread().getName()+(char)i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"打印的小写字母:");
3.4、线程调度
3.4.1、获取优先级
setPriority方法
thread1.setPriority(Thread.MAX_PRIORITY)
优先级提供了3个数字:1(最低) 5(中等) 10(最高)
3.4.2、休眠
sleep方法
sleep无参:就是直到优先级高的先执行完,再执行低的线程。
sleep有参:就是该线程休眠的时间
3.4.3、join方法
在线程A运行中,让线程B加入,那就调用join方法,之后B线程运行,线程A则阻塞,等到B执行完之后,线程A继续执行
3.5、线程之间的的数据共享
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zv2GIibn-1664280498602)(E:\笔记\第五周\QQ截图20220923163347.png)]
1)main方法在创建一个及以上的线程对象
1)外部类创建一个锁对象
2)在run方法在对其线程可能发生阻塞现象的代码块加锁以及解锁
案例:
public class Demo3 {
/*
共享数据
用锁
*/
//创建一个锁对象
public static class PrintTask implements Runnable {
int i = 1;
ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
/*
方式一:
如果不加锁的话,线程A、B会出现
*/
//
// while (i<=100){
// //加锁
// lock.lock();
// System.out.println(Thread.currentThread().getName()+i);
// i++;
// } lock.unlock();//解锁
/*
方式二:
*/
while (1 <= 100){
if(i <= 100){//推荐写法 synchronized(this) 或者 synchronized(类名.class)
synchronized (PrintTask.class){
System.out.println(Thread.currentThread().getName()+i);
i++;
}
}
}
/*
方式三:
*/
// while (i <= 100) {
// synchronized (PrintTask.class) {
// this.notify();//当前线程唤醒已阻塞
// synchronized (this) {//Demo7.class,类名.class;
// System.out.println(Thread.currentThread().getName() + i);
// i++;
// try {
// this.wait();//当前线程阻塞
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// // }
// }
// }
// }
}
public static void main(String[] args) {
PrintTask printTask = new PrintTask();
Thread t1 = new Thread(printTask, "线程A");
Thread t2 = new Thread(printTask, "线程B");
t1.start();
t2.start();
}
}
}
3.6、线程之间的同步
3.6.1、synchronizes关键字加锁和释锁机制
在可能出现线程阻塞出的代码块添加synchronizes关键字进行锁机制
synchronized (PrintTask.class){方法体}//推荐写法:推荐写法 synchronized(this) 或者 synchronized(类名.class)
注意:synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类。
3.6.2、同步方法
public synchronized void syn() {
System.out.println("这是同步方法...");
}
3.6.3、同步代码块
即有synchronized关键字修饰的语句块。被该关键字修饰的语句块会自动被加上内置锁,从而实现同步。
3.7、线程之间的通信
3.7.1、wait
wait方法:当前持有锁的该线程等待,直至该对象的另一个持锁线程调用
3.7.2、notify
notify方法:通知持有该对象锁的所有线程中的的随意一个线程被唤醒
3.7、可重入锁ReentrantLock
ReentrantLock lock = new ReentrantLock();//创建锁对象
4、网络编程相关案例
4.1、客户端发送文字给服务器端
代码:
//线程处理阻塞的问题
//线程:因为第一个客户端发送的数据如果没有被读取到,
// 那么第二个客户端发送的数据也服务器也接受不到,
// 因此把读写数据的代码新开辟一个路径,就是线程的实现
public class Server3 {
public static void main(String[] args) throws IOException {
Scanner input = new Scanner(System.in);
SocketAddress address = new InetSocketAddress("127.0.0.1",9091);
ServerSocket server = new ServerSocket();
server.bind(address);
System.out.println("服务器已挂起...");
//---------------*以下代码是接受客户端发生的数据*----------------
while (true){
Socket s = server.accept();
System.out.println("客户端连接成功"+s.toString());
Thread t = new Thread(()->{
InputStream in = null;
try {
in = s.getInputStream();
byte[] bufs = new byte[1024];
int len = -1 ;
if((len = in.read(bufs)) != -1) {
String msg = new String(bufs, 0, len);
System.out.println("收到客户端发的消息:" + msg);
}
System.out.println("准备给客户端发生数据了");
//数据回传给客户端,回答对方
//write方法也会阻塞,如果客户端没有读,那么会阻塞在这里
//无论read还是write都会发生阻塞
s.getOutputStream().write("收到".getBytes(StandardCharsets.UTF_8));;
s.getOutputStream().flush();
} catch (IOException e) {
e.printStackTrace();
}
});
}
}
}
public class Cilent3 {
public static void main(String[] args) throws IOException {
Scanner input = new Scanner(System.in);
Socket s =new Socket("127.0.0.1",9091);
OutputStream out = s.getOutputStream();
System.out.println("连接服务器成功...");
System.out.print("请输入要发送的字母:"); ;
String msg= input.next();
out.write(msg.getBytes(StandardCharsets.UTF_8));
out.flush();
System.out.println("发生"+msg+"成功");
//客户端接受服务器端发的数据
InputStream in = s.getInputStream();
byte[] bufs = new byte[1024];
int len = in.read(bufs,0, args.length);
String m = new String(bufs,0,len);
System.out.println(m);
s.close();
}
}
4.2、服务器端信息回传到客户端
代码:
/*
客服端转发到服务器端
*/
public class Server5 {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(9091);
System.out.println("等待客户端连接。。。");
Socket s = server.accept();
System.out.println("和客户端建立连接了。。。");
InputStream in = s.getInputStream();
byte[] bufs = new byte[1024];
int len = -1; // 返回读取的字节个数
String msg = null;
if( (len = in.read(bufs)) != -1) {
msg = new String(bufs,0,len); // 字节数组转换未字符串
System.out.println(msg);
}
s.getOutputStream().write(msg.toUpperCase().getBytes(StandardCharsets.UTF_8));
System.out.println("发送成功!");
s.getOutputStream().flush();
}
}
/*
客服端转发到服务器端
*/
public class Cilent5 {
public static void main(String[] args) throws IOException {
Scanner input = new Scanner(System.in);
Socket s = new Socket("127.0.0.1",9091);
System.out.println("输入一段字母:");
String words = input.next();
s.getOutputStream().write(words.getBytes(StandardCharsets.UTF_8));
System.out.println("发送成功!");
s.getOutputStream().flush();
InputStream in = s.getInputStream();
byte[] bufs = new byte[1024];
int len = -1; // 返回读取的字节个数
String msg = null;
if( (len = in.read(bufs)) != -1) {
msg = new String(bufs,0,len); // 字节数组转换未字符串
System.out.println(msg);
}
s.close();
}
}
4.3、客户端上传图片到服务器
代码:
/*
客服端转发到服务器端
*/
public class Server5 {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(9091);
System.out.println("等待客户端连接。。。");
Socket s = server.accept();
System.out.println("和客户端建立连接了。。。");
InputStream in = s.getInputStream();
byte[] bufs = new byte[1024];
int len = -1; // 返回读取的字节个数
String msg = null;
if( (len = in.read(bufs)) != -1) {
msg = new String(bufs,0,len); // 字节数组转换未字符串
System.out.println(msg);
}
s.getOutputStream().write(msg.toUpperCase().getBytes(StandardCharsets.UTF_8));
System.out.println("发送成功!");
s.getOutputStream().flush();
}
}
/*
客服端转发到服务器端
*/
public class Cilent5 {
public static void main(String[] args) throws IOException {
Scanner input = new Scanner(System.in);
Socket s = new Socket("127.0.0.1",9091);
System.out.println("输入一段字母:");
String words = input.next();
s.getOutputStream().write(words.getBytes(StandardCharsets.UTF_8));
System.out.println("发送成功!");
s.getOutputStream().flush();
InputStream in = s.getInputStream();
byte[] bufs = new byte[1024];
int len = -1; // 返回读取的字节个数
String msg = null;
if( (len = in.read(bufs)) != -1) {
msg = new String(bufs,0,len); // 字节数组转换未字符串
System.out.println(msg);
}
s.close();
}
}
4.4、客户端上传单文件到服务器
代码:
public class Server4 {
public static void main(String[] args) throws IOException {
//简写,不用IP地址,默认本机IP地址
ServerSocket server = new ServerSocket(8888);
//等待客户连接进来,通过s和客户端连接
Socket s = server.accept();
/*
核心代码:一边读、一边写
*/
new Thread(() ->{
try {
InputStream in= s.getInputStream();
File target = new File("人员名单.txt");
FileOutputStream out = new FileOutputStream(target);
byte[] bufs = new byte[1024];
int len = -1;
while ((len = in.read(bufs)) != -1){
String n = new String(bufs,0,len); s.getOutputStream().write(n.getBytes(StandardCharsets.UTF_8));
out.write(bufs,0,len);
}
out.close();
System.out.println("保存文件成功!");
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
public class Cilent4 {
public static void main(String[] args) throws IOException {
System.out.print("文件路径:");
String path = new Scanner(System.in).next();
File f = new File(path);
if(!f.isFile()){
System.out.println("文件不存在");
return;
}
Socket s = new Socket("127.0.0.1",8888);
//从客户端的磁盘把文件读取到内存中来
FileInputStream in = new FileInputStream(f);
byte[] bufs = new byte[1024];
int len = -1;
while ((len = in.read(bufs)) != -1){
//String n = new String(bufs,0,len);
//s.getOutputStream().write(n.getBytes(StandardCharsets.UTF_8));
s.getOutputStream().write(bufs,0,len);
}
System.out.println("发生文件成功!");
in.close();
s.close();
}
}
4.5、实现在线聊天
代码:
/*
服务端
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8888);
System.out.println("服务器已挂起,等待客户端连接...");
Socket s = server.accept();
System.out.println("客户端:"+s.toString()+"连接成功!");
InputStream in = s.getInputStream();
byte[] bufs = new byte[1024];
int len = -1;
String msg = null;
while ((len = in.read(bufs)) != -1){
msg = new String(bufs,0, len);
System.out.println("来自客服端的信息:"+msg);
}
s.getOutputStream().write(msg.getBytes(StandardCharsets.UTF_8));
System.out.println("发送成功");
in.close();
System.out.println("服务器已中断...");
}
}
/*
客户端
*/
public class Cilent {
public static void main(String[] args) throws IOException {
Scanner input = new Scanner(System.in);
Socket s = new Socket("127.0.0.1",8888);
System.out.println(s.toString());
OutputStream out = s.getOutputStream();
while (true){
System.out.print("请输入要发送的内容(N退出):");
String chooes = input.next();
if (chooes.equalsIgnoreCase("N")){
out.close();
System.out.println("程序退出!");
break;
}else {
out.write(chooes.getBytes(StandardCharsets.UTF_8));
System.out.println("发送成功");
}
}
}
}