import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.io.*; /**
* 读取动态产生的文件内容
*/
public class RandomAccessRead {
public static Logger logger= LoggerFactory.getLogger(RandomAccessRead.class); //文件默认读取位置为从开始读取
public static final long DEFAULT_START_POSITION=0;
// 读取文件内容输出时采用的编码格式 默认采用ISO-8859-1编码格式,因为RandAccess读取文件内容为该格式
public static final String DEFAULT_OUTPUT_CHARSET="ISO-8859-1";
//读取文件超时时间,默认-1 没有超时时间
public static final long TIMEOUT=-1;
// 相邻两次读取文件内容时间间隔,默认20ms
public static final long DEFAULT_READ_INTERVAL=20; //私有构造方法,防止该对象通过new实例化
private RandomAccessRead(){}; /**
* 动态读取文件内容
* @param inputPath 输入路径
* @param inputFileName 输入文件名称
* @param outputPath 输出路径
* @param endFlag 文件内容中读取结束标志
* @return 文件读取结束位置
*/
public static long read(String inputPath,String inputFileName,String outputPath,String endFlag){
return read(inputPath,inputFileName,outputPath,"",DEFAULT_START_POSITION,DEFAULT_OUTPUT_CHARSET,-1,DEFAULT_READ_INTERVAL,endFlag);
} /**
* 读取动态产生的文件内容 执行输入路径、输入文件名称,输出路径,输出文件名称、读取开始位置,输出时使用的编码格式,超时时间,两次相邻读取文件时间间隔
* @param inputPath 读取文件路径
* @param inputFileName 读取文件名称
* @param outputPath 输出文件路径
* @param outputFileName 输出文件名称 不设置默认为源文件名称
* @param startPosition 文件读取开始位置 不设置默认从文件开始位置读取,其值为0
* @param outputCharset 读取文件内容输出时采用的编码格式 不设置默认采用ISO-8859-1编码格式,因为RandAccess读取文件内容为该格式
* @param timeOut 超时时间 读取的文件长时间没有内容产生,则超时,读取结束,不设置默认没有超时时间
* @param readInterval 相邻两次读取文件内容时间间隔,默认20ms
* @param endFlag 读取文件结束标志
* @return 返回本次读取文件内容的长度,方便下次通过该位置读取文件内容
*/ public static long read(String inputPath,String inputFileName,String outputPath,String outputFileName,long startPosition,String outputCharset,long timeOut,long readInterval,String endFlag) {
//判断路径后面是否带“/” linux下为”\“
inputPath=inputPath.endsWith(File.separator)==true?inputPath:inputPath+File.separator;
String filePath=inputPath+inputFileName;
long endPosition=startPosition;
//判断文件是否存在
RandomAccessFile randomAccess=null;
try {
randomAccess = new RandomAccessFile(filePath, "r");
} catch (FileNotFoundException e) {
logger.error("读取文件:{} 不存在,请检查文件路径", filePath);
e.printStackTrace();
return endPosition;
}
//初始化输出流
outputPath=outputPath.endsWith(File.separator)==true?outputPath:outputPath+filePath;
outputFileName=outputFileName.equals("")==true?inputFileName:outputFileName;
String outputFilePath=outputPath+outputFileName;
if(!new File(outputFilePath).exists()){
try {
new File(outputFilePath).createNewFile();
} catch (IOException e) {
logger.error("输出路径:{}创建失败",outputFilePath);
e.printStackTrace();
return endPosition;
}
}
BufferedWriter bw=null;
try {
bw= new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(outputFilePath)),outputCharset));
} catch (IOException e) {
e.printStackTrace();
}
long startTime=System.currentTimeMillis();
//上次更新数据时间
long preTime=startTime;
//读取结束标识 读到结束标志
Boolean readEnd=false; try {
String tempStr=null;
StringBuilder sb=null;
while(true) {
randomAccess.seek(startPosition);
sb=new StringBuilder();
while(null!=(tempStr=randomAccess.readLine())){
preTime=System.currentTimeMillis();
//RandomAccessFile读取的文件内容编码为ISO-8859-1,需要转化为指定编码格式
if(!"".equals(outputCharset)){
tempStr=new String(tempStr.getBytes(DEFAULT_OUTPUT_CHARSET),outputCharset);
}
if(!tempStr.contains(endFlag)) {
sb.append(tempStr);
sb.append("\n");
}else{
readEnd=true;
break;
}
//清空tempStr
tempStr=null;
}
//输出到文件中
bw.write(sb.toString());
bw.flush();
//清空sb
sb=null;
endPosition=randomAccess.length();
if(readEnd)
{
break;
}
//判断超时时间
if(timeOut!=-1&&System.currentTimeMillis()-preTime>timeOut) {
logger.info("读取文件超时,读取退出,输入文件路径:{},输出文件路径:{}",filePath,outputFilePath);
break;
}
//读取文件内容间隔时间 -1表示未设置 则使用默认的时间间隔
try {
if(-1==readInterval) {
readInterval=DEFAULT_READ_INTERVAL;
}
Thread.sleep(readInterval);
} catch (InterruptedException e) {
logger.error("线程挂起出现异常,异常信息为:{}",e.getMessage());
e.printStackTrace();
}
//break;
}
} catch (IOException e) {
logger.error("读取文件:{},发生IO异常,异常信息:{}",filePath,e.getMessage());
e.printStackTrace();
}finally {
if(null!=randomAccess)
{
try {
randomAccess.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null!=bw)
{
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime=System.currentTimeMillis();
logger.info("读取文件时长为:{} ms",(endTime-startTime));
logger.info("文件读取结束,输入文件路径:{},输出文件路径:{}",filePath,outputFilePath);
return endPosition;
}
} public static void main(String[] args) {
//test1();
//test2();
test3();
} /**
* 验证情况1 正常参数
*/
public static void test1(){
String inputPath="F:\\IDE\\DesignPatternWebServer\\src\\main\\java\\com\\main\\etl\\server";
String inputFileName="RandomAccessRead.java";
String outputPath="F:\\";
String outputFileName="test.java";
long startPosition=0;
String outputCharset="UTF-8";
long timeOut=1000;
long readInterval=50;
String endFlag="END";
long endPosition= RandomAccessRead.read(inputPath,inputFileName,outputPath,outputFileName,startPosition,outputCharset,timeOut,readInterval,endFlag);
} /**
* 验证情况2 正常参数 不填输出文件名称
*/
public static void test2(){
String inputPath="F:\\IDE\\DesignPatternWebServer\\src\\main\\java\\com\\main\\etl\\server";
String inputFileName="RandomAccessRead.java";
String outputPath="F:\\";
String outputFileName="";
long startPosition=0;
String outputCharset="UTF-8";
long timeOut=1000;
long readInterval=50;
String endFlag="END";
long endPosition= RandomAccessRead.read(inputPath,inputFileName,outputPath,outputFileName,startPosition,outputCharset,timeOut,readInterval,endFlag);
} /**
* 验证情况3 简化参数形式
*/
public static void test3(){
String inputPath="F:\\IDE\\DesignPatternWebServer\\src\\main\\java\\com\\main\\etl\\server";
String inputFileName="RandomAccessRead.java";
String outputPath="F:\\";
String endFlag="END";
long endPosition= RandomAccessRead.read(inputPath,inputFileName,outputPath,endFlag);
} }

log4j.properties内容如下:

  ### set log levels ###
log4j.rootLogger = debug,stdout,R,E ### 输出到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.Threshold = INFO
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} %p [%t] %c{2} (%M:%L) - %m%n ### 输出etl-web日志到文件 ###
log4j.appender.R = org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.ImmediateFlush=true
log4j.appender.R.Append = true
log4j.appender.R.File =F:/logs/etl_web.log
log4j.appender.R.encoding=UTF-8
log4j.appender.R.Threshold = INFO
log4j.appender.R.DatePattern='.'yyyy-MM-dd
log4j.appender.R.layout = org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} %p [%t] %c{2} (%M:%L) - %m%n ### 保存异常信息到单独文件 ###
log4j.appender.E = org.apache.log4j.RollingFileAppender
log4j.appender.E.File = F:/logs/etl_error.log
log4j.appender.E.encoding=UTF-8
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} %p [%t] %c{2} (%M:%L) - %m%n

7 RandomAccessFile读取文件内容保存--简单例子(需要验证)的更多相关文章

  1. android逐行读取文件内容以及保存为文件

    用于长时间使用的apk,并且有规律性的数据 1,逐行读取文件内容 //首先定义一个数据类型,用于保存读取文件的内容 class WeightRecord { String timestamp; flo ...

  2. android按行读取文件内容的几个方法

    一.简单版 import java.io.FileInputStream; void readFileOnLine(){ String strFileName = "Filename.txt ...

  3. shell读取文件内容

           Shell脚本,执行解释速度快.代码简单易于理解.在shell代码编写过程中,经常会用到读取文件内容. 写法一: ------------------------------------ ...

  4. Node.js读取文件内容

    原文链接:http://blog.csdn.net/zk437092645/article/details/9231787 Node.js读取文件内容包括同步和异步两种方式. 1.同步读取,调用的是r ...

  5. 使用 istreambuf_iterator 读取文件内容,赋值给 std::string

    需要一个一个字符输入时考虑使用istreambuf_iterator 假设我们要把一个文本文件拷贝到一个字符串对象中.似乎可以用一种很有道理的方法完成: ifstream inputFile(&quo ...

  6. PHP读取文件内容的方法

    下面我们就为大家详细介绍PHP读取文件内容的两种方法. 第一种方法:fread函数 <?php $file=fopen('1.txt','rb+'); echo fread($file,file ...

  7. 在Spring Boot快捷地读取文件内容的若干种方式

    引言: 在Spring Boot构建的项目中,在某些情况下,需要自行去读取项目中的某些文件内容,那该如何以一种轻快简单的方式读取文件内容呢?  基于ApplicationContext读取 在Spri ...

  8. java读取文件内容常见几种方式

    ①随机读取文件内容 ②以行为单位读取文件,常用于读面向行的格式化文件 ③以字符为单位读取文件,常用于读文本,数字等类型的文件 ④以字节为单位读取文件,常用于读二进制文件,如图片.声音.影像等文件 pa ...

  9. shell逐行读取文件内容

    shell 中逐行读取文件内容 1.语法简介 #!/bin/bash <<EOF shell 中逐行读取文件内容的语法如下所示. 这里虽然很简单,但是再配合上其他的工具,如sed,awk, ...

随机推荐

  1. python学习第十三天 -模块和包

    模块和包 大家都知道,在计算机程序开发的过程中,随着程序代码越写越多,这样代码就会越不容易维护. 有时候为了好维护代码,把不同功能的函数放到不同的xx.py文件中. 在python中,一个.py文件就 ...

  2. 关于a标签下的img元素在IE7下不能点击的问题

    转载自http://segmentfault.com/q/1010000000712673<!DOCTYPE HTML> <html> <head> <met ...

  3. GO实例3 Slice append打印

    package main import "fmt" func main(){ ]int slice:=array[:] slice[]='a' slice[]='b' s1:=ap ...

  4. .a静态库的注意事项

    .a静态库  生成的时候   可以分为  debug 版本  和  release 版本. debug:速度比较慢,比较耗性能.会启动更多的  Xcode 系统监控功能.  对错误的敏感度不高. re ...

  5. Caffe--solver.prototxt配置文件 参数设置及含义

    ####参数设置################### 1. ####训练样本### 总共:121368个batch_szie:256将所有样本处理完一次(称为一代,即epoch)需要:121368/ ...

  6. jquery easyui根据需求二次开发记录

    1.tree需要显示多个图标 实际需求:设备树上节点需搁三个图片,分别标识运行状态.告警状态.设备类型 解决方法:给tree的iconCls传入一个数组,分别是各状态下的class(css),然后要改 ...

  7. E​F​I​主​板​和​G​P​T​分​区​表​安​装​系​统以及转换GPT分区表的方法

    现在硬盘越来越大,而原来的MBR分区方式,超过2T的硬盘就会识别不全,只有使用GPT的方式才可以,但是GPT如果用原来的BIOS是无法引导装系统了,不过如果你的主板支持EFI,那么可以用GPT+EFI ...

  8. 面试题 43 n 个骰子的点数

    ; void printfProbability(int number) { ) return; ]; p[] = ]; p[] = ]; memset(p[], , )); memset(p[], ...

  9. Global build settings

    [ ] Select all packages by default *** General build options ***   [ ] Show packages that require gr ...

  10. SQL基础理论题

    sql理论题 1.触发器的作用? 答:触发器是一中特殊的存储过程,主要是通过事件来触发而被执行的.它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化.可以 ...