背景:有时候服务运行的日志文件,需要统计分析,但数据量很大,并且直接在文件中看很不直观,这时可以将文件中的内容导入到数据库,入库后的数据就可以按照需求进行统计分析了。

这个是以服务器的访问日志作为示例,一个日志文件中一行的数据格式如下(文件夹中有多个日志文件):

[/Aug/::: +] ******* -  "-" "GET https://****/****/image57.png"    HIT "******" "image/png"

下面就是具体的读取文件,然后插入到数据库的过程,代码如图:

package com.mobile.web.api;

import com.mobile.commons.JsonResp;
import com.mobile.model.LogInfo;
import com.mobile.service.LogInfoService;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale; @RestController
@RequestMapping(value = "/test")
@Transactional
public class ImportController {
Logger log = Logger.getLogger(this.getClass()); @Autowired
private LogInfoService logInfoService; @RequestMapping(value = "/importTxt", method = RequestMethod.GET)
public JsonResp importTxt() throws IOException, ParseException {
log.debug("开始导入数据"); String encoding = "GBK";
List logInfoList = new ArrayList();
String dir = "E:\\test\\log";
File[] files = new File(dir).listFiles();
for (File file : files){           //循环文件夹中的文件
if (file.isFile() && file.exists()) { //判断文件是否存在
importFile(file, encoding, logInfoList); //将文件中的数据读取出来,并存放进集合中
} else {
return JsonResp.toFail("文件不存在,请检查文件位置!");
}
} Boolean insertFlag = logInfoService.insertBatch(logInfoList); //将集合中的数据批量入库
if (!insertFlag) {
return JsonResp.toFail("保存失败");
}
return JsonResp.ok();
}   /** 读取数据,存入集合中 */
public static void importFile(File file, String encoding, List logInfoList) throws IOException, ParseException {
InputStreamReader read = null;//考虑到编码格式
try {
read = new InputStreamReader(
new FileInputStream(file), encoding);  //输入流
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt = null;
SimpleDateFormat sdf = new SimpleDateFormat("[dd/MMM/yyyy:HH:mm:ss Z]", Locale.US); //时间格式化,此处有坑,下边会说到
while ((lineTxt = bufferedReader.readLine()) != null) {  //读取文件内容
String[] lineArr = lineTxt.split(" ");
int len = lineArr.length;
LogInfo logInfo = new LogInfo();     //封装实体对象做入库准备
String logDate = lineArr[] + " " + lineArr[];
System.out.println(sdf.parse(logDate)); //.............时间转换问题
logInfo.setLog1(sdf.parse(logDate));
logInfo.setLog2(lineArr[]);
logInfo.setLog3(lineArr[]);
logInfo.setLog4(lineArr[]);
logInfo.setLog5(lineArr[].substring(, lineArr[].length() - ));
logInfo.setLog6(lineArr[].substring());
logInfo.setLog8(lineArr[].substring(, lineArr[].length() - ));
String accessUrl = lineArr[];
String[] accessUrlArr = accessUrl.split("/");
logInfo.setItemName(accessUrlArr[]);
logInfo.setLog9(lineArr[]);
logInfo.setLog10(lineArr[]);
logInfo.setLog11(lineArr[]);
logInfo.setLog12(lineArr[]);
String[] uaHead = new String[len - ];
System.arraycopy(lineArr, , uaHead, , len - );//数组拷贝,a表示源数组,b表示源数组要复制的起始位置,c表示目标数组,d表示目标数组起始位置,e表示要复制的长度。
logInfo.setLog13(StringUtils.join(uaHead));
logInfo.setFileType(lineArr[len - ]); logInfoList.add(logInfo);
}
read.close(); //输入流关闭 } }

文件导入,成功;

    log文件夹下的结构如下图:

    

时间转换时的坑

  SimpleDateFormat sdf = new SimpleDateFormat("[dd/MMM/yyyy:HH:mm:ss Z]", Locale.US);

  字符串转时间时:英文简写为英文格式,而转换时JRE会按照当前地区的语言格式,所以转换失败

  解决方法:带上Locale.US参数

  详细解决可参考:https://www.cnblogs.com/mufengforward/p/9480102.html

此时,如果数据量特别大时,会出现入库慢的情况,有另一种方法是:读取文件后,将数据按照想要的格式存如新文件中,然后用sql语句(或navicat客户端)导入文件;

www.feng16.com

java批量读取多个文件并存入数据库的更多相关文章

  1. Spark1.6.2 java实现读取json数据文件插入MySql数据库

    public class Main implements Serializable { /** * */ private static final long serialVersionUID = -8 ...

  2. 使用JAVA API读取HDFS的文件数据出现乱码的解决方案

    使用JAVA api读取HDFS文件乱码踩坑 想写一个读取HFDS上的部分文件数据做预览的接口,根据网上的博客实现后,发现有时读取信息会出现乱码,例如读取一个csv时,字符串之间被逗号分割 英文字符串 ...

  3. Java项目读取resources资源文件路径那点事

    今天在Java程序中读取resources资源下的文件,由于对Java结构了解不透彻,遇到很多坑.正常在Java工程中读取某路径下的文件时,可以采用绝对路径和相对路径,绝对路径没什么好说的,相对路径, ...

  4. java使用stream流批量读取并合并文件,避免File相关类导致单文件过大造成的内存溢出。

    import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.F ...

  5. java读取本地txt文件并插入数据库

    package com.cniia.ny.web.control.configManage; import java.io.BufferedReader; import java.io.File; i ...

  6. Java中读取properties资源文件

    一.通过ResourceBundle来读取.properties文件 /** * 通过java.util.resourceBundle来解析properties文件. * @param String ...

  7. stream流批量读取并合并文件

    import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.F ...

  8. Java 批量反编译class文件,并保持目录结构

    jad -o -r -d d:\src -s java C:\Users\spring\Desktop\egorder3.0\WEB-INF\classes\**\*.class -o - overw ...

  9. java nio读取和写入文件

    读取 package com.test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputS ...

随机推荐

  1. hdu 5875 ACM/ICPC Dalian Online 1008 Function

    题目链接 分析:用RMQ预处理每段的最小值,然后对每次查询的区间找最靠近左边的小于的值,取模后递归操作.因为每次取模至少会使原来的值减半,所以递归操作是的.每次查询最小值如果通过线段树那么最终的复杂度 ...

  2. 防止IE不支持console.log报错

    function log(msg){ if (window["console"]){//判断是否是IE console.log(msg); } }

  3. C++ 我想这样用(七)

    话接前篇,继续基于对象编程语法的剩余部分: 6.类的const成员函数和const对象 const数据成员:跟const常量一样,只是一个在类里(而且是在构造函数里),一个在类外而已,都必须初始化. ...

  4. hadoop 2.2.0 关于map和reduce的个数的设置

    关于hadoop中的map过程,我的理解是每一个map系统会开启一个JVM进程来处理,map之间相互并行,map函数内串行.这样的想法是否正确? 由于想在hadoop集群上算一个初始输入数据不多,但是 ...

  5. 每篇半小时1天入门MongoDB——4.MongoDB索引介绍及数据库命令操作

    准备工作 继续连接到mongo C:\Users\zouqi>mongo MongoDB shell version: 3.0.7 connecting to: test 查看数据库和集合 &g ...

  6. npm安装项目出错

    F:\ajax>npm install iview --savenpm WARN saveError ENOENT: no such file or directory, open 'F:\aj ...

  7. Spring MVC学习step1——框架熟悉

    b站视频链接,整理的一些笔记,图是网上找到的黑马教案,侵权删,在此记录学习笔记 SpringMVC框架 步骤: 第一步:发起请求到前端控制器(Dispatcherservlet) 第二步:前端控制器请 ...

  8. 修改AD中PCB各层的透明度

    1.采用的Altium designer 版本为AD16: 2.进入PCB编辑页面,快捷键Ctrl+D,进入视图配置: 3.选择“透明度”,设置选中的层.对象所需的透明度:(横向可以连续选择多个对象, ...

  9. iOS main.m解析

    在iOS开发中,有一个文件main.m,可能并不是很引起开发的注意.不过,可能在面试过程中,面试官还是有些会问到主函数里面到底做了哪些工作和任务.下面我们主要看一下main.m内部的逻辑. #impo ...

  10. sklearn-标准化标签LabelEncoder

    sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003& ...