springboot项目练习十一 递归解析指定目录下的文件,保存至数据库

  • 获取该目录下所有以.json结尾的文件
  • 调用原解析的方法将数据批量插入数据库
  • 使用redis存储已解析文件的名称,避免下次重复解析
  • 使用到FileFilter文件过滤这个类,线程

从根目录开始解析判断是否是目录,是则获取子文件,将符合要求的文件存到集合,对剩下的文件进行递归遍历

1 先看下文件目录json文件目录下,方便测试加了一层子目录

2 编写递归读取文件的方法

package com.gc.utils;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 递归解析文件中的数据
 * @author gc
 *
 */
public class RecursiveGetJsonData {
private static List<Object> list = new ArrayList<Object>(); //公共的的数据池
private String  rootDir;//根目录
private  List<File> jsonFileList= new  ArrayList<File>();//公共的数据区域 找到的文件数据
public List<File> getJsonFileList() {
	return jsonFileList;
}
public void setJsonFileList(List<File> jsonFileList) {
	this.jsonFileList = jsonFileList;
}
public RecursiveGetJsonData(String  rootDir){
	this.setRootDir(rootDir);
}
public RecursiveGetJsonData() { // 空构造方法
}
//public static void main(String[] args) {
//	RecursiveGetJsonData re= new  RecursiveGetJsonData("D:\\xml");
//	re.getDataFromFile(re.getRootDir(),".json");
//	List<File> jsonList = re.getJsonFileList();
//	for (File file : jsonList) {
//		System.out.println(file.getName());
//	}
//}
/**
 * rootDir 根目录
 * fileNameEndFlag  问价结尾标识
 * @param rootDir
 * @param fileNameEndFlag
 */
public void getDataFromFile(String rootDir,final String fileNameEndFlag){
	File rootFile  = new File(rootDir);
	FileFilter filter = new  FileFilter(){ //文件后缀过滤
		@Override
		public boolean accept(File file) {
			String fileName = file.getName();
			if(fileName!=null && fileName!="" &&fileName.endsWith(fileNameEndFlag) ){
				return true;
			}
			return false;
		}};
	if(rootFile.isDirectory()){ //如果是目录
		File[] listFiles = rootFile.listFiles(filter); // 满足条件的文件装入公共数据区
		if(null!=listFiles && listFiles.length>0){
			jsonFileList.addAll(Arrays.asList(listFiles)); //Arrays 将数组转化为List集合
		}
		File[] list = rootFile.listFiles();
		if(null!=list && list.length>0){
			for (int i = 0; i < list.length; i++) {
				if(list[i].isDirectory()){
					getDataFromFile(list[i].getAbsolutePath(),fileNameEndFlag); //递归调用方法
				}
			}
		}
	}
}



public String getRootDir() {
	return rootDir;
}

public void setRootDir(String rootDir) {
	this.rootDir = rootDir;
}

public static List<Object> getList() {
	return list;
}

public static void setList(List<Object> list) {
	RecursiveGetJsonData.list = list;
}


	
}

3 修改文件解析的方法增加一个方法

public static  List<News>  importData(File file,String fileName){
	InputStream in =null;
	BufferedReader br=null;
	List<News> list=null;
	try {
		in = new FileInputStream(file);
		br = new BufferedReader(new InputStreamReader(in));
		String line;
		StringBuffer strb = new StringBuffer();
		while ((line = br.readLine()) != null) {
			strb.append(line);
		}
		ObjectMapper mapper  = new  ObjectMapper();
		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		JsonNode jsonNode = mapper.readTree(strb.toString());
		JsonNode root = jsonNode.get("T1348647853363");
		
		if(root.isArray()){
			 list=	mapper.readValue(root.toString(), new TypeReference<List<News>>() {});
		}
		if(list!=null){
			for (News news : list) {
				news.setId(UUID.randomUUID().toString());
				System.out.println(news.toString());
			}
		}
	} catch (Exception e) {
		
		e.printStackTrace();
	}finally {
			try {
			if(br!=null){
					br.close();
			}
			if(in!=null){
				in.close();
			}
			} catch (IOException e) {
				e.printStackTrace();
			}
	}
	
	return list;
	
}

4 在newsService中增加一个导入的方法

void importFromFile(String rootFile);//接收controller传递的文件路径

5 实现该导入的方法

@Autowired
	private StringRedisTemplate redisTemplate;

/**
	 * 从文件解析数据
	 */
	@Override
	public void importFromFile(String rootFile) {
		RecursiveGetJsonData pageJson = new RecursiveGetJsonData(); // 构造对象
		pageJson.getDataFromFile(rootFile, ".json"); //传入后缀以.json的  需要找到以.json结尾的
		List<File> jsonFile = pageJson.getJsonFileList(); // 得到所有的文件
		for (File file : jsonFile) { 
			redisTemplate.opsForList().leftPush("newsJsonFileList", file.getName()); //将文件名存储进redis中
			try{
				new Thread(){ // 构造线程
					@Override
					public void run() {
						List<News> list = JsonUtils.importData(file,""); //调用解析文件的方法 第二个参数暂时没用到不传
						newsDao.insertIntoByList(list); //批量插入数据库
					}
				}.start();
				
			}catch(Exception e){
				e.printStackTrace();
			}
			
		}
	}

5 编写入口方法

@RequestMapping("importToDataBase")
	@ResponseBody
	public String importToDataBase(){
		
		newsService.importFromFile("F:\\springboot\\springboot_solr\\src\\main\\resources\\json");
		return "导入成功 ";
	}

插入成功的数据截图

在数据的导入过程中遇到几个问题:

忘记给news方法提供无参构造方法了

在数据导入的时候由于使用的是当前时间戳+随机生成随机数的方法做id导致在插入数据的时候出现主键冲突。(改用UUID生成Id)。

在做测试的过程中生成了大量的重复代码,接下来对数据库的数据进行筛选和去重,根据返回的docId进行去重,将去重完的数据重新导入solr中,修改以前交互的方式,列表查询调用solr,删除方法调用中增加数据库的信息的删除。

项目下载地址:

链接:https://pan.baidu.com/s/1wREoJutn4Rny2VY0dYe97A 
提取码:iv3a 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Master_slaves

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值