com.gitee.apanlh.util.io.ReadLineIterator Maven / Gradle / Ivy
package com.gitee.apanlh.util.io;
import com.gitee.apanlh.exp.NotFoundException;
import com.gitee.apanlh.exp.StreamReadException;
import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.encode.CharsetCode;
import com.gitee.apanlh.util.unit.BuffSize;
import com.gitee.apanlh.util.valid.ValidParam;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.Reader;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.function.Consumer;
/**
* 行迭代器,读取使用迭代器方式
*
需要自行关闭流
*
如果迭代器未找到元素时才将会自动关闭流
* @example
*
* {@code
* try{
* FileLineIterator fli = new FileLineIterator(filePath/File/FileInputStream/Reader);
* while (fli.hasNext()) {
* String str = fli.next();
* }
* } finally {
* fli.close();
* }
* }
*
* @author Pan
*/
public class ReadLineIterator implements Iterator, Closeable {
/** 缓冲读取流 */
private BufferedReader reader;
/** 文件流 */
private FileInputStream fis;
/** 字符集编码 */
private String charset;
/** 缓冲长度 */
private int bufferSize;
/** 行内容 */
private String content;
/** 行总数 */
private int lineCount;
/** 是否存在下一行 */
private boolean hasNext;
/**
* 默认构造函数
*
* @author Pan
*/
ReadLineIterator() {
super();
}
/**
* 构造函数-根据文件路径构建
*
默认8K缓冲区大小
*
默认系统字符集编码
*
* @author Pan
* @param filePath 文件路径
*/
public ReadLineIterator(String filePath) {
this(new File(filePath), CharsetCode.getDefaultToString(), BuffSize.SIZE_8K);
}
/**
* 构造函数-根据文件路径构建
*
自定义缓冲区大小
*
自定义字符集编码
*
* @author Pan
* @param filePath 文件路径
* @param charset 字符集编码
* @param bufferSize 缓冲区大小
*/
public ReadLineIterator(String filePath, String charset, int bufferSize) {
this(new File(filePath), charset, bufferSize);
}
/**
* 构造函数-根据文件路径构建
*
默认8K缓冲区大小
*
默认系统字符集编码
*
* @author Pan
* @param file 文件对象
*/
public ReadLineIterator(File file) {
this(file, CharsetCode.getDefaultToString(), BuffSize.SIZE_8K);
}
/**
* 构造函数-根据文件对象构建
*
自定义缓冲区大小
*
自定义字符集编码
*
* @author Pan
* @param file 文件对象
* @param charset 字符集编码
* @param bufferSize 缓冲区大小
*/
public ReadLineIterator(File file, String charset, int bufferSize) {
this(FileIOUtils.getInput(file), charset, bufferSize);
}
/**
* 构造函数-根据文件输入流
*
默认8K缓冲区大小
*
默认系统字符集编码
*
* @author Pan
* @param fis 文件输入流
*/
public ReadLineIterator(FileInputStream fis) {
this(fis, CharsetCode.getDefaultToString(), BuffSize.SIZE_8K);
}
/**
* 构造函数-根据文件输入流
*
自定义缓冲区大小
*
自定义字符集编码
*
* @author Pan
* @param fis 文件输入流
* @param charset 字符集编码
* @param bufferSize 缓冲区大小
*/
public ReadLineIterator(FileInputStream fis, String charset, int bufferSize) {
this.charset = charset;
this.bufferSize = bufferSize;
this.fis = fis;
open();
}
/**
* 构造函数-根据读取流
*
默认8K缓冲区大小
*
* @author Pan
* @param reader 读取流
*/
public ReadLineIterator(Reader reader) {
this(reader, BuffSize.SIZE_8K);
}
/**
* 构造函数-根据读取流
*
自定义缓冲区大小
*
* @author Pan
* @param reader 读取流
* @param bufferSize 缓冲区大小
*/
public ReadLineIterator(Reader reader, int bufferSize) {
this.bufferSize = bufferSize;
if (reader instanceof BufferedReader) {
this.reader = (BufferedReader) reader;
} else {
this.reader = new BufferedReader(reader, bufferSize);
}
}
/**
* 读取文件开启读取流
*
如果获取字符集编码为空,默认设置系统字符集编码
*
* @author Pan
*/
private void open() {
try {
this.reader = IOUtils.getReader(fis, CharsetCode.getCharset(charset, CharsetCode.CHARSET_DEFAULT), bufferSize);
} catch (Exception e) {
IOUtils.close(reader);
throw new NotFoundException(e.getMessage(), e);
}
}
/**
* 将读取文件并保存至集合中(有序)
*
* @author Pan
* @return List
*/
public List getLines() {
List newArrayList = CollUtils.newArrayList();
while (hasNext()) {
newArrayList.add(next());
}
return newArrayList;
}
/**
* 验证是否存在下一个元素
*
如果不存在则自动关闭读取流
*
出现异常将自动关闭流
*
* @author Pan
*/
@Override
public boolean hasNext() {
try {
this.content = this.reader.readLine();
hasNext = ValidParam.isNotNull(this.content);
if (hasNext) {
lineCount++;
} else {
close();
}
return hasNext;
} catch (Exception e) {
close();
throw new StreamReadException(e.getMessage(), e);
}
}
/**
* 获取元素
*
* @author Pan
* @return String
*/
@Override
public String next() {
if (!hasNext) {
throw new NoSuchElementException("no more lines");
}
return this.content;
}
@Override
public void remove() {
// 不执行
}
@Override
public void forEachRemaining(Consumer action) {
Iterator.super.forEachRemaining(action);
}
/**
* 关闭读取流
*
* @author Pan
*/
@Override
public void close() {
content = null;
IOUtils.close(this.reader);
}
/**
* 获取读取的行总数
*
* @author Pan
* @return int
*/
public int getLineCount() {
return lineCount;
}
}