java入门-文件与IO流

File类

提供一些方法(api)来操纵文件和获取文件的信息

File常用API

属性

获取系统分隔符

不同操作系统的分隔符

windows的目录分割符号是用向右的斜线,java中\ 表示转义字符,所以向右的斜线需要写两个 \;

linux目录分割符号是向左的斜线: /

private static final FileSystem fs = DefaultFileSystem.getFileSystem();
public static final char separatorChar = fs.getSeparator();
public static final String pathSeparator = "" + pathSeparatorChar; 

程序案例:

System.out.println("File.pathSeparator:" + File.pathSeparator);
System.out.println("File.separatorChar:" + File.separatorChar);

程序运行结果:

File.pathSeparator:;
File.separatorChar:\

方法

获取文件/文件夹名称

程序案例:

File file = new File("D:\\java-workspace");
System.out.println("文件夹/文件名: " + file.getName());
System.out.println("绝对路径:" + file.getAbsolutePath());
System.out.println("路径: " + file.getPath());

程序运行结果:

文件夹/文件名: \java-workspace
绝对路径:D:\\java-workspace
路径: D:\\java-workspace
文件夹/文件

程序案例:

File file = new File("D:\\java-workspace");
System.out\.println("是否是文件: " + file.isDirectory());
System.out\.println("是否是文件: " + file.isFile());

程序运行结果:

是否是文件: true
是否是文件: false 
文件操作

程序案例:

File file = new File("D:\\newFile.txt");

if (file.exists()) {
	file.delete(); // 删除当前文件,如果是文件夹,要确保文件夹内容为空。
}
boolean f = file.createNewFile();

if (f) {// 如果文件创建成功
    System.out\.println("是否是隐藏问: " + file.isHidden());
    System.out\.println("最后一次修改时间: " + new Date(file.lastModified()));
    System.out\.println("是否可读: " + file.canRead());
    System.out\.println("是否可写: " + file.canWrite());
    System.out\.println("是否可执行: " + file.canExecute());
    System.out\.println("磁盘总空间大小: "+ file.getTotalSpace()/1024/1024/1024+"G");
    System.out\.println("磁盘可用空间大小: "+file.getUsableSpace()/1024/1024/1024+"G");
    System.out\.println("磁盘剩余空间大小: "+ file.getFreeSpace()/1024/1024/1024+"G");
}
修改文件名称
file.renameTo(new File("D:\\modify.txt"));	
System.out\.println("文件名称: "+ file.getName());
File nFile = new File("D:\\modify.txt");
System.out.println("修改文件名: "+ file.renameTo(nFile));

程序运行结果:

是否是隐藏问: false
最后一次修改时间: Tue Jan 25 14:28:29 CST 2022
是否可读: true
是否可写: true
是否可执行: true
磁盘总空间大小: 429G
磁盘可用空间大小: 424G
磁盘剩余空间大小: 424G
修改文件名: true
文件夹、文件访问

程序案例:

File file = new File("C:\\");
String[] fs = file.list();
File[] files = file.listFiles();

for(File f: files) {
	System.out\.println(f.getName());
}

程序运行结果(部分):

eclipse
hiberfil.sys
Intel
pagefile.sys
PerfLogs
Program Files

流的概念

流是个抽象的概念,是\对输入输出设备的抽象\,Java程序中,对于数据的输入/输出操作都是以“流”的方式进行。设备可以是文件,网络,内存等。

1.2.1 输入、输出流

提输入、输出是相对于\内存\的操作而言。

imgimg

imgimg

字节流、字符流

字节流–传输过程中,传输数据的最基本单位是字节的流。

字符流–传输过程中,传输数据的最基本单位是字符的流。

1.2.3 流的层次结构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

imgimg

1.3 字节流

以字节为(8bits)为单位进行IO操作,一般用来处理二进制文件(例如:图片、声音、视频等)。

1.3.1 字节输入流

img

1.3.2 字节输出流

img

程序案例:

程序案例:使用字节流完成流的拷贝功能。

InputStream in = new FileInputStream("c:\\jdk-8u311-windows-x64.exe");

OutputStream out = new FileOutputStream("d:\\jdk-8u311-windows-x64.exe");

int n = 0;
long t1 = System.currentTimeMillis();

while ((n = in.read()) != -1) {
   out.write(n);

}
long t2 = System.currentTimeMillis();
out.close();
in.close();

System.out\.println("字节拷贝,耗时: " + (t2 - t1)+"ms");

程序运行结果:                                

字节拷贝,耗时: 439897ms

字节流的缓存

如果按照一个字节一个字节的进行IO操作,字节的入和出的速度不是对等的。比如我们在工地经常看到传递砖块的操作,一般不是一个砖接一个砖传递,而是几块砖头放在一起传递。在流操作中,经常用到的技术是定义一个缓存区域,积累到一定数量后,一次性发送给接收端。

img

程序案例: 使用缓存优化字节流完成流的拷贝功能

InputStream in = new FileInputStream("c:\\jdk-8u311-windows-x64.exe");

OutputStream out = new FileOutputStream("d:\\jdk-8u311-windows-x64.exe");

long t1 = System.currentTimeMillis();
byte[] buffer = new byte[1024];
while (in.read(buffer) != -1) {
  out.write(buffer);
}
long t2 = System.currentTimeMillis();
out.close();
in.close();
System.out\.println("字节缓存拷贝,耗时: " + (t2 - t1)+"ms");

程序运行结果:

字节缓存拷贝,耗时: 586ms

1.4 字符流

以字符为单位的IO操作,一般用来操作文本信息。

1.4.1 字符输入流

img

程序案例:

BufferedReader in =
new BufferedReader(
new FileReader("D:\\java-workspace\\javaio\\src\\javaio\\CopyDemo.java"));
String line = null;
int index = 0;

while ((line = in.readLine()) != null) {
	System.out\.println((++index) +"\t"+ line);

}		

in.close();

程序运行结果(部分):

1	package javaio;
2  
3	import java.io.FileInputStream;
4	import java.io.FileOutputStream;
5	import java.io.IOException;
6	import java.io.InputStream;
7	import java.io.OutputStream;

1.4.2 字符输出流

img

程序案例:

PrintWriter pw = new PrintWriter(new FileWriter("D:\\pw.html"));
pw.println("<h1>你好,java IO 流</h1>");
pw.println("<h2>java爱好者</h2>");
pw.println("<h3>测试字符输出流的用法</h3>");		
pw.flush();
pw.close();

程序运行结果:

img

流的异常捕获方案

try … catch … finally

一般流的异常都是可检查异常,所有在开发过程中需要强制使用异常捕获流程处理。一般打开流对象后,如果不关闭会一直占用一个通道(就像开辟了几条通道进行数据传输,其中一条已经完成,但是不释放则会一直占用此通道,造成资源浪费)。一般开发中我们会在finally语句块调用流的关闭语句,以此释放流资源。

程序案例:

InputStream in = null;
try{
 in = new FileInputStream(“D:\\in.dat”);
}catch(IOException e){
 //异常信息
}finally{
in.close(); //关闭流对象
}

try … with … resource

如果打开了外部资源(文件、数据库连接、网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们。因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制,如果我们不在编程时确保在正确的时机关闭外部资源,就会导致外部资源泄露,紧接着就会出现文件被异常占用,数据库连接过多导致连接池溢出等诸多很严重的问题。

对于实现了Closeable接口的类,可以使用try…with…resource处理异常。

程序案例:

try(InputStream in = new FileInputStream(D:/abc.txt”)){
 //异常信息
}catch(IOException e){
 //捕获异常
}

序列化

序列化:一个Java对象作一下“变换”,变成\字节序列\,这样一来方便持久化存储到磁盘,避免程序运行结束后对象就从内存里消失,另外变换成字节序列也更便于网络运输和传播

反序列化:把字节序列恢复为原先的Java对象。

img

实现序列化接口的对象,有一个特殊常量serialVersinUID

img

提示: static修饰的不会被序列化,transient修饰的不会被序列化。

对象流

对象流:有的时候,我们可能需要将内存中的对象持久化到硬盘上,或者将硬盘中的对象信息读到内存中,这个时候我们需要使用对象输入输出流。

当使用对象流写入或者读取对象的时候,必须保证该对象是序列化的,这样是为了保证对象能够正确的写入文件,并能够把对象正确的读回程序。

(1) ObjectInputStream: 字节对象输入流

(2) ObjectOutputStream: 字节对象输出流

程序案例((ObjectInputStream):

public class Car implements Serializable{

	private static final long serialVersionUID\ = 1L;
	private String brand;
	private String color;
	private double price; 
	
	public Car(String brand, String color, double price) {
		this.brand = brand;
		this.color = color;
		this.price = price;
	}
  //其它代码省略
}
.....

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:\\car.dat"));
Car car = new Car("BMW", "黑色", 1200000.00);
out.writeObject(car);
out.flush();
out.close();

程序运行结果:

img

程序案例(ObjectOutputStream):

ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:\\car.dat"));
Car car = (Car) in.readObject();	
System.out\.println(car);
in.close();

程序运行结果:

Car [brand=BMW, color=黑色, price=1200000.0]

序列化接口

Serializable是一个标记性接口,没有实现任何内容,只是告诉JVM当前对象需要序列化。

public interface Serializable {

}

日志

日志概念

日志是一种记录、跟踪程序运行的技术。作用主要在以下三个方面:

调试

在Java项目调试时,查看栈信息可以方便地知道当前程序的运行状态,输出的日志便于记录程序在之前的运行结果。

错误定位

项目在运行一段时候后,可能由于数据问题,网络问题,内存问题等出现异常。这时日志可以帮助开发或者运维人员快速定位错误位置,提出解决方案。

数据分析

日志中蕴含了大量的用户数据,包括点击行为,兴趣偏好等,用户画像对于公布下一步的战略方向有一定指引作用。

日志级别

(1) ALL: 最低等级的,用于打开所有日志记录。

(2) TRACE: 很低的日志级别,一般不会使用。

(3) DEBUG: 指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于打印一些调试信息。

(4) WARN: 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员一些提示。

(5) INFO: 消息在粗粒度级别上突出强调应用程序的运行过程。打印一些你感兴趣的或者重要的信息。这个用于生产环境中输出程序运行的一些重要信息,但是不能滥用,避免打印过多的日志。

(6) ERROR: 指出虽然发生错误事件,但任然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。

(7) FATAL: 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误。

log4j

Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

日志配置
Loggers

Loggers组件在此系统中被分为五个级别:DEBUG、INFO、WARN、ERROR和FATAL。这五个级别是有顺序的,DEBUG < INFO < WARN < ERROR < FATAL,分别用来指定这条日志信息的重要程度Log4j有一个规则:只输出级别不低于设定级别的日志信息,假设Loggers级别设定为INFO,则INFO、WARN、ERROR和FATAL级别的日志信息都会输出,而级别比INFO低的DEBUG则不会输出。

Appenders

禁用和使用日志请求只是Log4j的基本功能,Log4j日志系统还提供许多强大的功能,比如允许把日志输出到不同的地方,如控制台(Console)、文件(Files)等,可根据天数或者文件大小产生新的文件,可以以流的形式发送到其它地方等等。

Layouts

Log4j可以在Appenders的后面附加Layouts来完成这个功能。Layouts提供四种日志输出样式,如根据HTML样式、自由指定样式、包含日志级别与信息的样式和包含日志时间、线程、类别等信息的样式。

PatternLayout格式参数如下表:

序号格式含义
1%p输出日志信息的优先级:DEBUG,INFO,WARN,ERROR,FATAL。
2%d输出日志时间点的日期或时间。默认格式为ISO8601,也可以在其后指定格式。%d{yyyy/MM/dd HH:mm:ss SSS}。
3%r输出自应用程序启动到输出该log信息耗费的毫秒数。
4%t输出产生该日志事件的线程名。
5%l输出日志事件的发生位置,相当于%C%M(%F%L)的组合,包括类全名、方法、文件名以及在代码中的行数。例如:testLog4j.java:
6%c输出日志信息所属的类目,通常就是所在类的全名。
7%M输出产生日志信息的方法名
8%F输出日志消息产生时所在的文件名称
9%L输出代码中的行号
10%m输出代码中指定的具体日志位置
11%n输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”。
日志使用

配置文件: 在src定义一个properties文件: log4j.properties

配置文件案例

log4j.rootLogger = DEBUG,Console,infoFile
log4j.appender.Console = org.apache.log4j.ConsoleAppender
log4j.appender.Console.Target = System.out
log4j.appender.Console.Threshold = DEBUG
log4j.appender.Console.layout = org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%c] - %m%n
log4j.appender.infoFile = org.apache.log4j.FileAppender
log4j.appender.infoFile.File=D:/logs/test.log
log4j.appender.infoFile.Threshold = DEBUG
log4j.appender.infoFile.layout = org.apache.log4j.PatternLayout
log4j.appender.infoFile.layout.ConversionPattern=[%c] - %m%n

程序案例:

Logger.getLogger(Logger.class).debug("测试log4j日志...");

NIO编程

java.nio全称java non-blocking IO(实际上是 new io),是指JDK 1.4 及以上版本里提供的新api(new IO) ,为所有的原始类型(boolean类型除外)提供缓存支持的数据容器,使用它可以提供非阻塞式的高伸缩性网络。

NIO组件

img

缓冲区

(缓冲区(Buffer): 本质上是一个可以写入数据的内存块,然后可以再次读取,该对象提供了一组方法,可以更轻松地使用内存。

img

通道(Channel):

channel(通道)可以同时进行读写,而流只能读或者只能写。

通道可以实现异步读写数据。

通道可以从缓冲读数据,也可以写数据到缓冲。

channel提供了一个map()方法,可以直接将数据映射到内存中。

img

选择器(Selector)

可以检测多个NIO channel,看看读或者写事件是否就绪。多个\Channel\以事件的方式可以注册到同一个Selector,从而达到用一个线程处理多个请求成为可能。

img

NIO编程

程序案例:

String fileName = "D:\\java-workspace\\javaio\\src\\javaio\\ReaderDemo.java";

RandomAccessFile raf = new RandomAccessFile(fileName, "rw");

/*
 * 创建Channel
 */		
FileChannel inChannel = raf.getChannel();

/*
 * 创建缓存区,缓存48个字节
 */		
ByteBuffer buffer = ByteBuffer.allocate(48);

/*
 *
 * 读取48个字符到buffer缓存中
 * 检查是否到达文件的末尾(-1表示末尾)
 */		
while((bytesRead = inChannel.read(buffer)) !=-1) {

 /*
  *
  * 把buffer当前位置更改为buffer缓冲区的第一个位置
  */

buffer.flip();		

while(buffer.hasRemaining()) {

/*
 *
 * 从buffer当前位置一个字节、一个字节的读取缓存区数据
 */

 System.out\.print((char)buffer.get());

}

/*
 *
 * 清空buffer,设置到buffer缓冲区的第一个位置
 */

buffer.clear();

}
raf.close(); 

程序运行结果(部分):

package javaio;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class ReaderDemo { 
	public static void main(String[] args) throws IOException {
        :
        :
        :

BIO/AIO/NIO概念

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/703634.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C#开源项目推荐:Watt Toolkit跨平台游戏工具箱支持github网络加速

Watt Toolkit是一个开源跨平台的多功能游戏工具箱&#xff0c;主要专注于增强玩家在Steam平台上的游戏体验及国外网站平台加速。 主要功能 兼容性 用户数据 团队背景 github加速功能 使用方法&#xff1a;用户只需在Watt Toolkit中启用网络加速功能&#xff0c;并选择对Gi…

cleanmymacx最新破解版百度云免费下载 cleanmymac激活码分享

CleanMyMac X4.15.3 中文破解版是一款 mac 系统清理软件&#xff0c;是一款专业的 Mac 清理、优化和维护工具&#xff0c;可以帮助用户清理系统垃圾、卸载不需要的应用程序、优化系统性能、保护隐私和安全等&#xff0c;让用户的 Mac 始终保持高效、安全和稳定。 CleanMyMac X4…

再度牵手,制造升级 | 毅达科技IMS OS+通用产品集+行业套件项目正式启动!

在数字化与智能制造的浪潮中&#xff0c;制造业企业纷纷加快转型步伐&#xff0c;力求通过技术创新实现生产效率与质量的双重提升。近日&#xff0c;广东毅达医疗科技股份有限公司&#xff08;以下简称“毅达科技”&#xff09;再次携手盘古信息&#xff0c;正式启动了IMS 数字…

跃入AI新纪元:亚马逊云科技LLM全景培训,解锁AI构建者之路

亲爱的技术爱好者们&#xff0c;你是否也对大语言模型&#xff08;LLM&#xff09;的神奇魅力所吸引&#xff0c;渴望深入探索其背后的技术奥秘&#xff1f;今天&#xff0c;我要为大家推荐一份超级硬核的学习资源——亚马逊云科技 对话AI 构建者&#xff1a;从基础到应用的LLM…

判断环形链表-链表题

141. 环形链表 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:bool hasCycle(ListNode *head) {ListNode* slow head;ListNode* fast head;while(fast ! NULL &&fast->next ! NULL){fast fast->next->next;slow slow->next;if(fast…

iOS/iPadOS18Beta是否值得升级体验?Bug汇总和升级办法分享!

苹果昨天发布了iOS/iPadOS18Beta更新&#xff0c;引入了诸多新功能/新特性&#xff0c;很多喜欢尝鲜的用户已经在第一时间进行了升级。 iOS/iPadOS18Beta目前存在不少Bug&#xff0c;建议暂时不要更新&#xff0c;轻则浪费装机时间&#xff0c;重则丢失相关数据&#xff0c;甚至…

STM32F413 STM32F423数据手册 中文版 STM32F413 STM32F423勘误手册英文版等文档

链接: https://pan.baidu.com/s/1AeYaoFb5Wurii6OM2ZlY2Q 提取码: a3tj 本文分享关于STM32F413 和STM32F423芯片的相关资料&#xff0c;主要资源如下图所示&#xff1a; 包含的文档有&#xff1a; STM32F40xxx and STM32F41xxx单片机编程手册 中文版 英文版 STM32F413xG 423…

自动化办公03 用xlrd和xlwt库操作excel.xls文件(老版本)

目录 一、读操作 二、写操作 三、设置单元格格式 0.综合案例 1.设置行高和列宽 2.设置字体样式 3.设置边框样式 4.设置对齐方式 5.设置背景颜色 6.合并单元格 四、 xlutils修改Excel⽂件内容 1.安装 2.使用 一、读操作 import xlrd# 1. 打开excel文件 wb xlrd.op…

51.Python-web框架-Django开始第一个应用的增删改查

目录 1.概述 2.创建应用 创建app01 在settings.py里引用app01 3.定义模型 在app01\models.py里创建模型 数据库迁移 4.创建视图 引用头 部门列表视图 部门添加视图 部门编辑视图 部门删除视图 5.创建Template 在app01下创建目录templates 部门列表模板depart.ht…

网络编程(一)基本概念、TCP协议

文章目录 一、概念&#xff08;一&#xff09;网络发展阶段1. ARPAnet阶段2. TCP/IP两个协议阶段3. 网络体系结构和OSI开放系统互联模型4. TCP/IP协议簇体系结构&#xff08;1&#xff09; 应用层&#xff1a;&#xff08;2&#xff09;传输层&#xff1a;&#xff08;3&#x…

电商平台“质价比”增量密码,藏在美妆价格战里

文&#xff5c;新熔财经 作者&#xff5c;宏一 电商平台越来越难赚到用户的钱了。 数据显示&#xff0c;今年4月&#xff0c;抖音护肤与彩妆总GMV达141.72亿元&#xff0c;同比增长32.66%&#xff0c;环比下滑8.87%。 即便是最受关注的美妆类淘宝主播李佳琦&#xff0c;今年…

【网络编程】基于TCP的服务器端/客户端

TCP是Transmission Control Protocol(传输控制协议)简写。因为TCP套接字是面向连接的&#xff0c;因此又称为基于流的套接字。 把协议分为多个层次&#xff0c;设计更容易&#xff0c;通过标准化操作设计开放式系统 网络层介绍 链路层 链路层是物理连接领域标准化的结果&…

推荐系统三十六式学习笔记:原理篇.近邻推荐09|协同过滤中的相似度计算方法有哪些?

目录 相似度的本质相似度的计算方法&#xff1a;1、欧式距离2、余弦相似度3、皮尔逊相关度4 、杰卡德&#xff08;Jaccard&#xff09;相似度 总结 相似度的本质 推荐系统中&#xff0c;推荐算法分为两个门派&#xff0c;一个是机器学习派&#xff0c;一个是相似度门派。机器学…

网络编程2----UDP简单客户端服务器的实现

首先我们要知道传输层提供的协议主要有两种&#xff0c;TCP协议和UDP协议&#xff0c;先来介绍一下它们的区别&#xff1a; 1、TCP是面向连接的&#xff0c;UDP是无连接的。 连接的本质是双方分别保存了对方的关键信息&#xff0c;而面向连接并不意味着数据一定能正常传输到对…

天熠电脑怎么更换文件夹位置?三种方法,轻松驾驭

在日常使用电脑的过程中&#xff0c;文件夹的管理和整理对于提升工作效率和保持桌面整洁至关重要。然而&#xff0c;随着文件的不断增多和项目的频繁切换&#xff0c;我们可能需要不断调整文件夹的位置以适应新的工作需求。今天&#xff0c;我们就以天熠电脑为例&#xff0c;为…

LeetCode | 20.有效的括号

这道题就是栈这种数据结构的应用&#xff0c;当我们遇到左括号的时候&#xff0c;比如{,(,[&#xff0c;就压栈&#xff0c;当遇到右括号的时候&#xff0c;比如},),]&#xff0c;就把栈顶元素弹出&#xff0c;如果不匹配&#xff0c;则返回False&#xff0c;当遍历完所有元素后…

“圆周素数”算法题解析

什么是圆周素数&#xff1f; 将一个素数逐位轮转后&#xff0c;所得到的数依然是素数&#xff0c;那么就称这个数为圆周素数。 例如&#xff1a;197是一个素数&#xff0c;将它逐位轮转后所得到的数&#xff0c;971&#xff0c;719 依然是素数。 小于100的圆周素数一共有13个…

HLS入门实验

文章目录 一、HLS介绍1.1 什么是HLS1.2HLS与VHDL/Verilog编程技术有什么关系?1.3HLS的关键技术和技术局限性1.3.1关键技术1.3.2 技术局限性 二、HLS入门实验2.1安装Vivado2.2创建项目2.3添加文件2.4仿真2.5创建Vivado工程2.6生成IP核2.7添加代码 参考 一、HLS介绍 1.1 什么是…

MySQL的发展历程:欧洲诞生,中国兴盛,美国低谷

目录 1 早期历史 2 成长与发展 3 重大变化和收购 4 现代发展 5 结语 一直比较写一些数据库相关的技术和操作、优化等文章。但写数据库在中国一般也逃脱不了MySQL这个数据库。下面简单谈一些个人看法。 MySQL整体上是起于欧洲&#xff1a; 一直有开源社区运营&#xff0c…

社会组织上前台、高质量发展勇担当|番禺区社联会成立十周年大会

6月5日&#xff0c;番禺区社联会举行“社会组织上前台&#xff0c;高质量发展勇担当”庆祝成立十周年大会暨“百社联百村—助力百千万工程”专项行动启动仪式。 广东省社会组织总会副秘书长王洁珊&#xff0c;广州市民政局一级调研员李又文&#xff0c;番禺区委副书记、区长叶珊…