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. noip2015运输计划

    二分+LCA+查分前缀和 #include<iostream> #include<cstring> #include<cstdio> #include<alg ...

  2. javascript学习教程之---如何从一个tab切换到banner幻灯片的转换2

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  3. HTML&CSS基础学习笔记1.2-HTML的全局属性?

    HTML元素都有属性,下面的这些全局属性是所有的HTML元素都可以使用的. 常见的有: HTML元素也有一些本身自己独特的属性,我们以后的笔记中有机会,会再为大家介绍哦. 下面是代码测验,具体的内容可 ...

  4. pyzmq简单的在线聊天室

    #encoding=utf-8#客户端 import zmq c = zmq.Context() s = c.socket(zmq.REQ) s.connect('tcp://127.0.0.1:10 ...

  5. iOS开发之常用第三方框架(下载地址,使用方法,总结)

    iOS开发之常用第三方框架(下载地址,使用方法,总结) 说句实话,自学了这么久iOS,如果说我不知道的但是又基本上都摸遍了iOS相关知识,但是每次做项目的时候,遇到难一点的地方或者没试过的东西就闷了. ...

  6. GCD使用经验与技巧浅谈--备

    GCD(Grand Central Dispatch)可以说是Mac.iOS开发中的一大“利器”,本文就总结一些有关使用GCD的经验与技巧. dispatch_once_t必须是全局或static变量 ...

  7. Cmake 脚本对预处理器的宏定义

    我们有些时候会在#if   #ifndef   等预编译命令里面看到_WIN32等定义的宏.但是有些宏定义,你即使通过Visual Studio右键的go to definitions 和go to ...

  8. socket使用TCP协议时,send、recv函数解析以及TCP连接关闭的问题

    Tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻塞,send发送的大小,并不代表对端recv到多少的数据. 在阻塞模式下, send函数的过程是将应用程序请求发送的数 ...

  9. debuggap,移动端调试新方式

    最近发现了一个移动端调试的新技能,这里简单描述一下基本情况. 移动端调试常遇到的问题 手机访问只能看到页面的展现,除此之外看不到任何其他信息 无法像调试PC页面那么方便的查看js.dom.networ ...

  10. <php>Ajax基本格式

    <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8&quo ...