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. struct可以拥有class般的构造函数

    struct A { int a, b; A(int x, int y) :a(x), b(y){} }; int main() { A a(1, 2); cout << a.a < ...

  2. [转]Windows与Linux系统下的库文件介绍

    什么是库   库文件是一些预先编译好的函数的集合,那些函数都是按照可再使用的原则编写的.它们通常由一组互相关联的用来完成某项常见工作的函数构成,从本质上来说库是一种可执行代码的二进制形式,可以被操作系 ...

  3. hook技术分类

    1.HOOK SERVICE TABLE:HOOK SSDT 这种方法对于拦截 NATIVE API 来说用的比较多. SSDT hook,一句话——Windows把需要调用的内核API地址全都存在了 ...

  4. traceroute小结 come from CSDN author:houdong

    traceroute程序可以使我们看到IP数据报从一台主机传到另一台主机的所经过的路由,并且可以使用IP源站路由选项. traceroute取代IP RR的原因 1 不是所有的路由器都支持IP RR选 ...

  5. js和jquery中的触发事件

    改别人的坑,遇到jquery选择器和fireEvent混用,不认识fireEvent方法报错. js的方法不能使用jquery的选择器去调用. 1.fireEvent (IE上的js方法 ) 我们来看 ...

  6. 绘制数据图表的又一利器:C3.js

  7. UCOS 信号量

    uCOS-II信号量OSSemCreate(0)和OSSemCreate(1)详解 (2014-04-22 18:04:18) 转载▼ 标签: it 分类: 操作系统 在ucos-II中,为了实现任务 ...

  8. Linux/Unix工具与正则表达式的POSIX规范

    http://www.infoq.com/cn/news/2011/07/regular-expressions-6-POSIX 对正则表达式有基本了解的读者,一定不会陌生『\d』.『[a-z]+』之 ...

  9. xdebug及webgrind的联用

    参考URL: http://www.tuicool.com/articles/ERFNva http://blog.sina.com.cn/s/blog_635833b3010127q5.html h ...

  10. Qt事件机制浅析(定义,产生,异步事件循环,转发,与信号的区别。感觉QT事件与Delphi的事件一致,而信号则与Windows消息一致)

    Qt事件机制 Qt程序是事件驱动的, 程序的每个动作都是由幕后某个事件所触发.. Qt事件的发生和处理成为程序运行的主线,存在于程序整个生命周期. Qt事件的类型很多, 常见的qt的事件如下: 键盘事 ...