1.只创建对象不创建文件
2.过滤器
使用匿名内部类实现FileFilter接口,实现过滤;
递归实现遍历目录及子目录下的后缀为。txt文件
public class ioRee { public static void main(String[] args) throws IOException { File file =new File("D:\\A"); info(file); } public static void info(File file){ if (file.isDirectory()){ File [] arr =file.listFiles(); for (File f:arr) { info(f); } } else if (file.getName().endsWith(".txt")){ System.out.println(file); } } }
3.字节流
那如何想把内存中的数据读到内存中,我们通过InputStream可以实现。InputStream此抽象类,是表示字节输入流的所有类的超类。定义了字节输入流的基本共性功能方法。
output类似
字节流转换时,读数据使用
FileInputStream fileInputStream = new FileInputStream("D:\\A\\ABC.txt"); int len =0; byte [] bytes =new byte[1024]; while ((len=fileInputStream.read(bytes))!=-1) System.out.println(new String(bytes, 0, len));
写数据
String s =new String(bytes);
byte [] b = s.getBytes(StandardCharsets.UTF_8);
o.write(b);
使用byte数组非常方便
4.字符流
字符流输入直接用String型,从文件中时不用使用辅助数组,将len直接强转char即可读取使用。
5.转换流
- 字节流到字符流的转换:
- 转换流如
InputStreamReader
和OutputStreamWriter
,分别用于将字节输入流转换为字符输入流,以及将字节输出流转换为字符输出流。这种转换使得开发者可以更方便地按照字符而不是字节的方式来读取和写入数据。
- 转换流如
- 编码转换:
- 在进行字符数据的读写时,经常需要指定字符编码(如UTF-8、GBK等)。转换流允许开发者在构造时指定字符编码,从而解决因编码不一致导致的乱码问题。
6.序列化
用来存储一整个对象,输出对象
7.线程(多线程实现方法一,使用Thread)
创建一个类继承线程类
Thread
名称 get、setname
休眠 Thread.sleep(2000)
守护线程 thread.setDaemon(true);
thread.join(), 当前线程暂停, 等待指定的线程执行结束后, 当前线程再继续;
Thread.yield() static void yield() 暂停当前正在执行的线程对象,并执行其他线程。
8.runnable方法(多线程实现方法一,使用Thread)
callable
相比于runnable run()变成了call()并且可以有返回值
支持泛型返回值
可以抛出异常
1. 创建Callable
对象
Callable<Integer> myCallable = new MyCallable(); |
这里创建了一个MyCallable
的实例,MyCallable
实现了Callable<Integer>
接口。与Runnable
接口不同,Callable
接口允许任务完成时返回一个结果。在这个例子中,MyCallable
的call
方法会计算0到99的整数和,并返回这个和。
2. 使用FutureTask
包装Callable
对象
FutureTask<Integer> ft = new FutureTask<Integer>(myCallable); |
FutureTask
是一个实现了Runnable
和Future
接口的类,它用于包装Callable
或Runnable
对象。在这个例子中,它被用来包装myCallable
对象。FutureTask
提供了一种机制来启动和取消计算,查询计算是否完成,以及检索计算结果。
3. 在主线程中执行循环,并在特定条件下启动新线程
for (int i = 0; i < 1000; i++) { | |
// ... | |
if (i == 30) { | |
Thread thread = new Thread(ft); | |
thread.start(); | |
} | |
} |
主线程执行一个循环,当循环变量i
等于30时,它创建一个新的线程,并将之前创建的FutureTask
对象ft
作为这个线程的Runnable
目标。这意味着新线程将执行ft
的run
方法,而FutureTask
的run
方法会调用其内部Callable
对象的call
方法。
4. 等待新线程完成并获取结果
try { | |
int sum = ft.get(); | |
System.out.println("sum = " + sum); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} catch (ExecutionException e) { | |
e.printStackTrace(); | |
} |
在主线程中,调用ft.get()
会阻塞当前线程(即主线程),直到FutureTask
的call
方法执行完成并返回结果。如果call
方法成功完成,
class MyCallable implements Callable<Integer> { // 与run()方法不同的是,call()方法具有返回值 @Override public Integer call() { int sum = 0; for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + " " + i); sum += i; } return sum; } }get
方法将返回其结果。如果call
方法抛出异常,则get
方法将抛出ExecutionException
。如果等待过程中当前线程被中断,则get
方法将抛出InterruptedException
。
5. 线程执行流程
- 主线程执行循环,当
i
等于30时,启动一个新线程来执行FutureTask
的run
方法。 - 新线程执行
FutureTask
的run
方法,该方法调用Callable
对象的call
方法,计算0到99的和。 - 同时,主线程继续执行循环直到完成,然后调用
ft.get()
等待新线程完成并获取结果。 - 当新线程完成
call
方法的执行后,它设置FutureTask
的结果,然后主线程通过get
方法获取这个结果并打印出来。
6. 注意事项
- 在这个例子中,主线程和新线程之间存在明显的竞争条件。主线程可能在新线程完成之前就尝试获取结果,但由于
get
方法的阻塞特性,它会等待直到结果可用。 - 如果不需要在
call
方法执行期间在主线程中执行其他任务,可以考虑直接在主线程中调用ft.run()
(但这样会失去异步执行的好处)。然而,由于FutureTask
的run
方法被设计为供线程执行,直接调用它通常不是最佳实践。正确的做法是让另一个线程执行它,如示例中所示。
9.同步
多线程共享数据不安全
线程同步两种方式
1.同步代码块
使用Object lock = new Object();
同步锁object,把想同步的代码块方进synchronized (lock){} 中,即可实现同步
2.同步方法
将synchronized关键字加到方法声明上,接可以省略掉object锁
10.线程组、池
使用线程组时,需要这样定义线程:thread(线程组名,runnable实例名,线程名),默认创建线程都在main方法下;
池:
11.UDP
发送信息时需要注意:
DatagramePacket(打包数据){数据名称,数据长度,目标地址, 目标端口号 }
DatagrameSocket(发送数据){发送端端口号}
发送Socket.send(数据包Packet)
发送端:
接收端:
实现持续发送:
此处与下文有区别!
1.直接从控制台读取和输入容器使用DatagramPacket datagramPacket 即可,初始化使用datagramPacket=new DatagramPacket (bytes,bytes.length, InetAddress.getLocalHost(),456);
此处定义接收端口;使用byte【】接收
2.若从文件中读取,是用转换流为容器,初始化写明socket.getOutputStream()字符输入流和字符集;使用char 【】 接收;
outputStreamWriter=new OutputStreamWriter(socket.getOutputStream(),"UTF-8");
public class 网络编程sender { public static void main(String[] args) { DatagramPacket datagramPacket=null; DatagramSocket datagramSocket=null; Scanner scanner = new Scanner(System.in); String str =""; try { datagramSocket=new DatagramSocket(123); while (!str.equals("end")){ System.out.println("聊天中,输入end以结束聊天!"); str=scanner.next(); byte [] bytes =str.getBytes(StandardCharsets.UTF_8); datagramPacket=new DatagramPacket (bytes,bytes.length, InetAddress.getLocalHost(),456); datagramSocket.send(datagramPacket); } } catch (SocketException e) { throw new RuntimeException(e); } catch (UnknownHostException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); }finally { if (datagramSocket!=null){ datagramSocket.close(); } } } }
=========================================================================
public class 网络编程receiver { public static void main(String[] args) { DatagramPacket datagramPacket=null; DatagramSocket datagramSocket=null; try { datagramSocket=new DatagramSocket(456); while (true){ byte [] bytes =new byte[1024];//定义数据容器 datagramPacket=new DatagramPacket(bytes, bytes.length);//定义包的大小 datagramSocket.receive(datagramPacket);//使用接口接收数据包 bytes =datagramPacket.getData();//数据放入容器 System.out.println(new String(bytes,0, datagramPacket.getLength() //使用datagramPacket.getLength()防止出现未初始化的字符));//输出 } } catch (SocketException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } }
12.TCP
需要一个服务端 SeverSocket
【1.定义serverPocket】
【2.pocket=serverPocket.accept】
【3.用转换流接收客户端传来的packet将字节流转为字符流:inputstreamReader =
new inputstreamReader(socket.getInputStream,"UTF-8")】
【4.选择输出方向,控制台输出则直接用数组接收,写入文件则需要用outputstreamWriter转换流转换FileinputStream文件字符流输入文件:outputstreamWriter=new outputstreamWriter (FileoutPutstream (文件位置,"UTF-8"))】
注:转换流接收的是char数组,返回int值
和若干个客户端 Socket
OUTPUT最好加上编码类型 getoutstream(new FileoutputStream , "UTF-8");
================================服务器端==================================
serverSocket=new ServerSocket(123);//定义服务端接口 socket=serverSocket.accept();//定义套接字 //读写操作 inputStreamReader=new InputStreamReader(socket.getInputStream(),"UTF-8");//字节流转换为字符流 outputStreamWriter=new OutputStreamWriter(new FileOutputStream("D:\\A\\a.txt"),"UTF-8");//保存到本地 char [] chars =new char[1024]; int len; while ((len=inputStreamReader.read(chars))!=-1){ outputStreamWriter.write(new String(chars,0,len)); }
=================================客户端==================================
inputStreamReader=new InputStreamReader(new FileInputStream("D:\\A\\student.txt"));//read socket=new Socket(InetAddress.getLocalHost(),123);//creat bag outputStreamWriter=new OutputStreamWriter(socket.getOutputStream(),"UTF-8"); char [] datas =new char[1024]; int len; while ((len=inputStreamReader.read(datas))!=-1){ String s =new String(datas,0,len); outputStreamWriter.write(s); outputStreamWriter.flush();//刷新数据,不然传不过去 }
============================多线程实现=====================================
=============================服务器端====================================
public class serverSocket { public static void main(String[] args) { ServerSocket serverSocket=null; Socket socket=null; InputStreamReader inputStreamReader=null; OutputStreamWriter outputStreamWriter=null; Object obj =new Object(); try { serverSocket=new ServerSocket(123);//定义服务端接口 while (true){ //加while循环保证服务器一直处于打开的状态,以便于接收多个客户端的数据传输 synchronized (obj){ //加互斥锁保证多个客户端互斥访问创建文件代码 socket=serverSocket.accept();//定义套接字 //读写操作 inputStreamReader=new InputStreamReader(socket.getInputStream(),"UTF-8"); //字节流转换为字符流 outputStreamWriter=new OutputStreamWriter(new FileOutputStream("D:\\A\\ABC\\"+new Random().nextInt(20))); //保存到本地 char [] chars =new char[1024]; int len; while ((len=inputStreamReader.read(chars))!=-1){ outputStreamWriter.write(new String(chars,0,len)); } outputStreamWriter.flush(); //及时刷新输出流可以将数据更新进文件 } } } catch (IOException e) { throw new RuntimeException(e); // }finally { // if (serverSocket!=null){ // try { // serverSocket.close(); // } catch (IOException e) { // throw new RuntimeException(e); // } // } // if (socket!=null){ // try { // socket.close(); // } catch (IOException e) { // throw new RuntimeException(e); // } // } // if (inputStreamReader!=null ){ // try { // inputStreamReader.close(); // } catch (IOException e) { // throw new RuntimeException(e); // } // } // if (outputStreamWriter!=null){ // try { // outputStreamWriter.close(); // } catch (IOException e) { // throw new RuntimeException(e); // } // } // } } }}
=================================客户端==================================
new Thread(){
@Override
public void run() {
Socket socket=null;
InputStreamReader inputStreamReader=null;
OutputStreamWriter outputStreamWriter=null;
try {
inputStreamReader=new InputStreamReader(new FileInputStream("D:\\A\\tcp.txt"));//read
socket=new Socket(InetAddress.getLocalHost(),123);//creat bag
outputStreamWriter=new OutputStreamWriter(socket.getOutputStream(),"UTF-8");
char [] datas =new char[1024];
int len;
while ((len=inputStreamReader.read(datas))!=-1){
String s =new String(datas,0,len);
outputStreamWriter.write(s);
outputStreamWriter.flush();//刷新数据,不然传不过去
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
if (socket!=null){
try {
socket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (inputStreamReader!=null){
try {
inputStreamReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}.start();
new Thread(){
@Override
public void run() {
Socket socket=null;
InputStreamReader inputStreamReader=null;
OutputStreamWriter outputStreamWriter=null;
try {
inputStreamReader=new InputStreamReader(new FileInputStream("D:\\A\\tcp1.txt"));//read
socket=new Socket(InetAddress.getLocalHost(),123);//creat bag
outputStreamWriter=new OutputStreamWriter(socket.getOutputStream(),"UTF-8");
char [] datas =new char[1024];
int len;
while ((len=inputStreamReader.read(datas))!=-1){
String s =new String(datas,0,len);
outputStreamWriter.write(s);
outputStreamWriter.flush();//刷新数据,不然传不过去
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
if (socket!=null){
try {
socket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (inputStreamReader!=null){
try {
inputStreamReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}.start();