SpringBoot整合reids之JSON序列化文件夹操作
前言
最近在开发项目,用到了redis作为缓存,来提高系统访问速度和缓解系统压力,提高用户响应和访问速度,这里遇到几个问题做一下总结和整理
快速配置
SpringBoot整合redis有专门的场景启动器整合起来还是非常方便的
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
如果使用redis连接池引入
<!-- redis连接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
集成配置文件
#------------------redis缓存配置------------
# Redis数据库索引(默认为 0)
spring.redis.database=1
# Redis服务器地址
spring.redis.host= 127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis 密码
spring.redis.password
# 连接超时时间(毫秒)
spring.redis.timeout= 5000
# redis连接池
# 连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=10
# 连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle= 500
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=2000
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.lettuce.pool.max-wait=10000
JSON序列化
由于缓存数据默认使用的是jdk自带的序列化 二进制
需要序列化的实体类继承Serializable接口。而且序列化后的内容在redis中看起来也不是很方便。
\xAC\xED\x00\x05sr\x00Lorg.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken/\xDFGc\x9D\xD0\xC9\xB7\x02\x00\x01L\x00\x0Aexpirationt\x00\x10Ljava/util/Date;xr\x00Dorg.springframework.security.oauth2.common.DefaultOAuth2RefreshTokens\xE1\x0E\x0AcT\xD4^\x02\x00\x01L\x00\x05valuet\x00\x12Ljava/lang/String;xpt\x00$805a75f7-2ee2-4a27-a598-591bfa1cf17dsr\x00\x0Ejava.util.Datehj\x81\x01KYt\x19\x03\x00\x00xpw\x08\x00\x00\x01}y\x81\xDB\x9Ax
于是萌生了需要将数据序列化成json的想法。
jackson序列化
在使用spring-data-redis,默认情况下是使用org.springframework.data.redis.serializer.JdkSerializationRedisSerializer这个类来做序列化,Jackson redis序列化是spring中自带的.我们使用jackson方式
@Bean
@ConditionalOnClass(RedisOperations.class)
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
//序列化包括类型描述 否则反向序列化实体会报错,一律都为JsonObject
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(mapper);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用 String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的 key也采用 String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用 jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的 value序列化方式采用 jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
序列化后存储在redis后内容
[
"com.qhong.test.dependBean.Person",
{
"age": 20,
"name": "name0",
"iss": true
}
]
[
"java.util.ArrayList",
[
[
"com.qhong.test.dependBean.Person",
{
"age": 20,
"name": "name0",
"iss": true
}
],
[
"com.qhong.test.dependBean.Person",
{
"age": 21,
"name": "name1",
"iss": true
}
],
[
"com.qhong.test.dependBean.Person",
{
"age": 22,
"name": "name2",
"iss": true
}
]
]
]
上面的不是严格符合json格式规范,虽然比默认二进制好
注意这里序列化json代类型
"com.qhong.test.dependBean.Person"
如果没有这个反序列化会报类型转换异常错误
也就是代码中这一段必须设置,我之前就是没有设置,反序列化都是JsonObject必须自己转换类型,否则会报错
//序列化包括类型描述 否则反向序列化实体会报错,一律都为JsonObject
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(mapper);
Fastjson序列化
- 需要倒入Fastjson到依赖
<!-- JSON工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
- 实现RedisSerializer接口
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {
public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
static {
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
}
private final Class<T> clazz;
public FastJson2JsonRedisSerializer(Class<T> clazz) {
super();
this.clazz = clazz;
}
/**
* 序列化
*/
@Override
public byte[] serialize(T t) throws SerializationException {
if (null == t) {
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
/**
* 反序列化
*/
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (null == bytes || bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return (T) JSON.parseObject(str, clazz);
}
}
- 配置redisTemplate
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisCacheAutoConfiguration {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
FastJson2JsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJson2JsonRedisSerializer<>(Object.class);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用fastJson
template.setValueSerializer(fastJsonRedisSerializer);
// hash的value序列化方式采用fastJson
template.setHashValueSerializer(fastJsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
注意这是一种方式自己实现RedisSerializer 序列化接口
但是FastJson 1.2.36版本以后不需要自己实现RedisSerializer
为我们提供序列化支持在com.alibaba.fastjson.support.spring中 有GenericFastJsonRedisSerializer
和FastJsonRedisSerializer
两个实现类 ,
区别在于
GenericFastJsonRedisSerializer
可以自动转换对象类型,FastJsonRedisSerializer
需要自定义转换需要的类型。
通常使用 GenericFastJsonRedisSerializer 即可满足大部分场景,如果你想定义特定类型专用的 RedisTemplate 可以使用 FastJsonRedisSerializer 来代替 GenericFastJsonRedisSerializer”
FastJson github有对应问题描述lssues 我已入坑 ,刚开始一直使用FastJsonRedisSerializer****无法自动反向序列化
序列化后存储在redis后内容
{
"@type": "com.qhong.test.dependBean.Person",
"age": 20,
"iss": true,
"name": "name0"
}
[
{
"@type": "com.qhong.test.dependBean.Person",
"age": 20,
"iss": true,
"name": "name0"
},
{
"@type": "com.qhong.test.dependBean.Person",
"age": 21,
"iss": true,
"name": "name1"
},
{
"@type": "com.qhong.test.dependBean.Person",
"age": 22,
"iss": true,
"name": "name2"
}
]
正常情况是格式是正确的,但是如果你存储内容出现set或者doubble类型,会带上Set,D类型描述如下
会出现问题无法解析,但是在程序里是可以反向序列化的
分析参考对比
jdkSerializationRedisSerializer:
使用JDK提供的序列化功能。 优点是反序列化时不需要提供类型信息(class),但缺点是需要实现Serializable接口,还有序列化后的结果非常庞大,是JSON格式的5倍左右,这样就会消耗redis服务器的大量内存。Jackson2JsonRedisSerializer:
使用Jackson库将对象序列化为JSON字符串。优点是速度快,序列化后的字符串短小精悍,不需要实现Serializable接口。但缺点也非常致命,那就是此类的构造函数中有一个类型参数,必须提供要序列化对象的类型信息(.class对象)。 通过查看源代码,发现其只在反序列化过程中用到了类型信息。FastJsonRedisSerializer
性能最优号称最快的json解析库,但是反序列化后类字段顺序和原来实体类不一致发生改变,在某些set,double字段情况下json格式不正确,但是在程序可以解析
更多问题参考
redis数据库操作
在整合了spring-boot-starter-data-redis
后会自动帮我们注入redisTemplate
对象,专门用来操作reids数据库的
在reids中如果想用文件夹方式存储key的话类似这样
我们只需要在存储使用使用::表示文件夹就可以了
redisTemplate.opsForValue().set("userLoginCache::Kenx_6003783582be4c368af14daf3495559c", "user");
如果需要模糊查询key话使用*
来表示 如
- 获取所有key
public static Set<String> getAllKey(String keys) {
Set<String> key = redisTemplate.keys(keys + "*");
return key;
}
- 模糊批量删除
/**
* 删除缓存
*
* @param key 可以传一个值 或多个
*/
public static void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(Arrays.asList(key));
}
}
}
public static void delByPrefix(String key) {
if (key != null) {
Set<String> keys = redisTemplate.keys(key + "*");
redisTemplate.delete(keys);
}
}
public static void delBySuffix(String key) {
if (key != null) {
Set<String> keys = redisTemplate.keys("*" + key);
redisTemplate.delete(keys);
}
}
public static void clean(){
Set<String> keys = redisTemplate.keys("*");
redisTemplate.delete(keys);
}
因为使用很频繁所以我写成工具库RedisUtil
通过静态方法方式去调用就可以了
基本上包含工作中用到的所有方法, 这里附上源码
package cn.soboys.kmall.cache.utils;
import cn.hutool.extra.spring.SpringUtil;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* 定义常用的 Redis操作
*
* @author kenx
*/
public class RedisUtil {
private static final RedisTemplate<String, Object> redisTemplate = SpringUtil.getBean("redisTemplate", RedisTemplate.class);
/**
* 指定缓存失效时间
*
* @param key 键
* @param time 时间(秒)
* @return Boolean
*/
public static Boolean expire(String key, Long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据key获取过期时间
*
* @param key 键 不能为 null
* @return 时间(秒) 返回 0代表为永久有效
*/
public static Long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断 key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public static Boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
*
* @param key 可以传一个值 或多个
*/
public static void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(Arrays.asList(key));
}
}
}
public static void delByPrefix(String key) {
if (key != null) {
Set<String> keys = redisTemplate.keys(key + "*");
redisTemplate.delete(keys);
}
}
public static void delBySuffix(String key) {
if (key != null) {
Set<String> keys = redisTemplate.keys("*" + key);
redisTemplate.delete(keys);
}
}
public static void clean(){
Set<String> keys = redisTemplate.keys("*");
redisTemplate.delete(keys);
}
/**
* 普通缓存获取
*
* @param key 键
* @return 值
*/
public static Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
*
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public static Boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
*
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public static Boolean set(String key, Object value, Long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 递增
*
* @param key 键
* @param delta 要增加几(大于0)
* @return Long
*/
public static Long incr(String key, Long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
*
* @param key 键
* @param delta 要减少几
* @return Long
*/
public static Long decr(String key, Long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
/**
* HashGet
*
* @param key 键 不能为 null
* @param item 项 不能为 null
* @return 值
*/
public static Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取 hashKey对应的所有键值
*
* @param key 键
* @return 对应的多个键值
*/
public static Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* 获取 hashKey对应的所有键
*
* @param key 键
* @return 对应的多个键
*/
public static Set<String> hmgetKey(String key) {
Map map = redisTemplate.opsForHash().entries(key);
return map.keySet();
}
/**
* HashSet
*
* @param key 键
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public static Boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 并设置时间
*
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public static Boolean hmset(String key, Map<String, Object> map, Long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public static Boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public static Boolean hset(String key, String item, Object value, Long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除hash表中的值
*
* @param key 键 不能为 null
* @param item 项 可以使多个不能为 null
*/
public static void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判断hash表中是否有该项的值
*
* @param key 键 不能为 null
* @param item 项 不能为 null
* @return true 存在 false不存在
*/
public static Boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
*
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return Double
*/
public static Double hincr(String key, String item, Double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
*
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return Double
*/
public static Double hdecr(String key, String item, Double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
/**
* 根据 key获取 Set中的所有值
*
* @param key 键
* @return Set
*/
public static Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据value从一个set中查询,是否存在
*
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public static Boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将数据放入set缓存
*
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public static Long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
}
/**
* 将set数据放入缓存
*
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public static Long sSetAndTime(String key, Long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0) {
expire(key, time);
}
return count;
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
}
/**
* 获取set缓存的长度
*
* @param key 键
* @return Long
*/
public static Long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
}
/**
* 移除值为value的
*
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public static Long setRemove(String key, Object... values) {
try {
return redisTemplate.opsForSet().remove(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
}
/**
* 获取list缓存的内容
*
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return List
*/
public static List<Object> lGet(String key, Long start, Long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取list缓存的长度
*
* @param key 键
* @return Long
*/
public static Long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
}
/**
* 通过索引 获取list中的值
*
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;
* index<0时,-1,表尾,-2倒数第二个元素,依次类推
* @return Object
*/
public static Object lGetIndex(String key, Long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @return Boolean
*/
public static Boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return Boolean
*/
public static Boolean lSet(String key, Object value, Long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @return Boolean
*/
public static Boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return Boolean
*/
public static Boolean lSet(String key, List<Object> value, Long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据索引修改list中的某条数据
*
* @param key 键
* @param index 索引
* @param value 值
* @return Boolean
*/
public static Boolean lUpdateIndex(String key, Long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N个值为value
*
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public static Long lRemove(String key, Long count, Object value) {
try {
return redisTemplate.opsForList().remove(key, count, value);
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
}
public static Set<String> getAllKey(String keys) {
Set<String> key = redisTemplate.keys(keys + "*");
return key;
}
}
SpringBoot整合reids之JSON序列化文件夹操作的更多相关文章
- python json序列化与反序列化操作
python json序列化与反序列化操作 # dumps() dict-->str 序列化 # loads() str---dict 反序列化 result1 = json.dumps({'a ...
- [No000083]文件与文件夹操作
#region Folder option 文件夹操作 /// <summary> /// 指定目录是否存在 /// </summary> /// <param name ...
- PHP 文件夹操作「复制、删除、查看大小」递归实现
PHP虽然提供了 filesize.copy.unlink 等文件操作的函数,但是没有提供 dirsize.copydir.rmdirs 等文件夹操作的函数(rmdir也只能删除空目录).所以只能手动 ...
- .Net文件*夹*操作
一.文件夹操作 Directory类,DirectoryInfo类.使用using System.IO命名空间 (一)创建文件夹 方法一: private string path = @"F ...
- iOS开发——Swift篇&文件,文件夹操作
文件,文件夹操作 ios开发经常会遇到读文件,写文件等,对文件和文件夹的操作,这时就可以使用NSFileManager,NSFileHandle等类来实现. 下面总结了各种常用的操作: 1,遍 ...
- Python的文件与文件夹操作
Python的文件与文件夹操作 Python OS模块 1.重命名:os.rename(old, new) 2.删除:os.remove(file) 3.列出目录下的文件 :os.listdir(pa ...
- linux —— 学习笔记(文件、文件夹操作)
目录:1.常用的文件文件夹操作 2.文件属性的设置 1.常用的文件文件夹操作 mkdir 创建文件夹 -p 如果指定 a/b/c 时 a .b 不存在,一起创建出来 cp 复制文件或文件 ...
- c# 封装的文件夹操作类之复制文件夹
c# 封装的文件夹操作类之复制文件夹 一.复制文件夹原理: 1.递归遍历文件夹 2.复制文件 二.FolderHelper.cs /// <summary> /// 文件夹操作类 /// ...
- Python_文件与文件夹操作
''' os模块除了提供使用操作系统功能和访问文件系统的简便方法之外,还提供了大量文件与文件夹操作的方法. os.path模块提供了大量用于路径判断.切分.连接以及文件夹遍历的方法. shutil模块 ...
随机推荐
- javascript,jquery在父窗口触发子窗口(iframe)某按钮的click事件
$('iframe').contents().find(".btn").click(); 其中 contents(): 查找匹配元素内部所有的子节点(包括文本节点).如果元素是一个 ...
- Jmeter系列(17)- 常用断言之JSON断言
模块分析 Assert JSON Path exists:需要断言的 JSON 表达式 Additionally assert value:如果要根据值去断言,请勾选 Match as regular ...
- mongodb linux基本启动 基础增删改 mysql语法的对比
一.主流数据源类型 还存在自定义数据源以及REST接口数据,共6中数据源. 二.linux下启动连接数据库 进去mongodb的目录启动服务:mongo --host 192.168.320.826 ...
- 网站优化之mysql优化
一,网站优化之mysql优化:1.前缀索引,可以通过前缀去识别唯一性,把这个前缀作为索引内容,可以节省存储索引的空间,从而提高索引的查询速度.distinct 排重操作2,2.in条件索引使用同时查询 ...
- Unittest 框架之断言,你学会了吗??
unittest断言 Python在 unittest.TestCase 类中提供了很多断言方法.断言方法检查你认为应该满足的条件是否确实满足.如果该条件确实满足,你对程序行为的假设就得到了确认,你就 ...
- 用Flask 实现文件服务器(包含docker版本)
最近有了公司局域网内共享axure原型的需求,所以用Flask开发了一款文件上传/查看工具,记录一下其中的问题和解决方案 这个工具参照了一位大神的uploads工具 https://zhuanlan. ...
- jmx_prometheus_javaagent+prometheus+alertmanager+grafana完成容器化java监控告警(二)
一.拓扑图 二.收集数据 2.1前期准备 创建共享目录,即为了各节点都创建该目录,有两个文件,做数据共享 /home/target/prom-jvm-demo 1.下载文件 jmx_prometheu ...
- 调试器地址出现大小端紊乱,引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。
今天在编写一系列新增需求代码后,开始调试代码 发现上个版本正常可运行的代码出现了:引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突. 上个版本数代码 ...
- 前段--->js
一,java script的引入方式 1,直接在script里书写你的代码 <script> alert("hbflfb")</script> 2,引入额外 ...
- 题解 「HDU6403」卡片游戏
link Description 桌面上摊开着一些卡牌,这是她平时很爱玩的一个游戏.如今卡牌还在,她却不在我身边.不知不觉,我翻开了卡牌,回忆起了当时一起玩卡牌的那段时间. 每张卡牌的正面与反面都各有 ...