Java nio按行处理文件(兼容Linux与Windows)
2017-01-17 00:00
477 查看
代码没有做复杂文件的测试,如果有问题,望请见谅并留言
import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; /** * Description: * Created by IntelliJ IDEA. * Created by on * User: * Date: * Time: */ public class HandleFileWithLine { private static final int BUFFER_LENGTH = 1024; //缓冲区数组长度 private static final byte CR = 13; //回车符 private static final byte LF = 10; //换行符 private static final Charset CHARSET = Charset.forName("UTF-8"); //编码字符集 public void handleFile(File handleFile) throws IOException { FileChannel inc = new RandomAccessFile(handleFile, "r").getChannel(); ByteBuffer inBuffer = ByteBuffer.allocate(BUFFER_LENGTH); //实际中每行的开始位置在数组中的下标 int lineStartPosition; //由于是按固定字节读取,在一次读取中,第一行和最后一行经常是不完整的行,因此定义此变量来存储上次的最后一行和这次的第一行的内容 byte[] tempByte = new byte[0]; while (inc.read(inBuffer) != -1) { lineStartPosition = 0; inBuffer.flip(); //按行处理文件的方法 tempByte = readLine(inBuffer, lineStartPosition, tempByte); inBuffer.clear(); } //处理最后一行数据 handleLine(tempByte); if (inc.isOpen()) inc.close(); } /** * 按行处理文件的方法 * @param inBuffer 每次获取的缓冲数据 * @param lineStartPosition 实际中每行的开始位置在数组中的下标 * @param tempByte 由于是按固定字节读取,在一次读取中,第一行和最后一行经常是不完整的行,因此定义此变量来存储上次的最后一行和这次的第一行的内容 * @return */ private byte[] readLine(ByteBuffer inBuffer, int lineStartPosition, byte[] tempByte) { //上一次剩余的不足一行的数据长度 int tempByteLength, lineStartOffset, lineEndOffset; //lineByte 每行的完整数据 //oneByte 一次获取的缓冲区的数据,与inBuffer中的实际有效数据相同 byte[] lineByte, oneByte; oneByte = new byte[inBuffer.limit()]; inBuffer.get(oneByte, inBuffer.position(), inBuffer.limit()); for (int i = 0, count = oneByte.length; i < count; i++) { //判断是否为回车符(每行的开始标志) if (oneByte[i] == LF) { lineStartOffset = i + 1 < count && oneByte[i + 1] == CR ? 2 : 1; //处理多个空白行的情况 if (oneByte[lineStartPosition] == LF) { //兼容Linux与window系统,Linux系统文件没有CR(13)回车符 lineStartPosition = i + lineStartOffset; System.out.println("---------blank lines"); continue; } lineByte = new byte[i - lineStartPosition + (tempByteLength = tempByte.length) - (lineEndOffset = oneByte[i - 1] == CR ? 1 : 0)]; if (tempByteLength > 0) { System.arraycopy(tempByte, 0, lineByte, 0, tempByteLength); tempByte = new byte[0]; } System.arraycopy(oneByte, lineStartPosition, lineByte, tempByteLength, i - lineStartPosition - lineEndOffset); //处理一行数据 handleLine(lineByte); //兼容Linux与window系统,Linux系统文件没有C 3ff0 R(13)回车符 lineStartPosition = i + lineStartOffset; } } //处理一行超长数据,一个tempByte数组长度存不下一行数据 if (tempByte.length > 0) { int oldTempByteLen = tempByte.length; byte[] newTempByte = new byte[oldTempByteLen + inBuffer.limit() - lineStartPosition]; System.arraycopy(tempByte, 0, newTempByte, 0, oldTempByteLen); tempByte = newTempByte; System.arraycopy(oneByte, lineStartPosition, tempByte, oldTempByteLen, inBuffer.limit() - lineStartPosition); } else { //处理上一次获取的剩余最后一行不完整数据 tempByte = new byte[inBuffer.limit() - lineStartPosition]; System.arraycopy(oneByte, lineStartPosition, tempByte, 0, inBuffer.limit() - lineStartPosition); } return tempByte; } /** * 处理方法(自己按需编写) * @param lineBytes 存储一行数据的数组 */ private void handleLine(byte[] lineBytes) { System.out.println(new String(lineBytes, CHARSET)); } }
相关文章推荐
- [C] 跨平台使用Intrinsic函数范例1——使用SSE、AVX指令集 处理 单精度浮点数组求和(支持vc、gcc,兼容Windows、Linux、Mac)
- [C] 跨平台使用Intrinsic函数范例1——使用SSE、AVX指令集 处理 单精度浮点数组求和(支持vc、gcc,兼容Windows、Linux、Mac)
- [C] 跨平台使用Intrinsic函数范例1——使用SSE、AVX指令集 处理 单精度浮点数组求和(支持vc、gcc,兼容Windows、Linux、Mac)
- 一个JSON字符串和文件处理的命令行神器jq,windows和linux都可用
- shell脚本兼容linux/unix与windows/cygwin的基础(注意处理好CR, LF, CR/LF 回车 换行的问题)
- Java下兼容linux和windows文件路径的间隔符的写法
- 『阿男的技术日志』*02 处理Git项目当中既有Windows文件又有Linux/Unix/MacOS文件的问题*
- shell脚本兼容linux/unix与windows/cygwin的基础(注意处理好CR, LF, CR/LF 回车 换行的问题)
- 在Java中兼容Windows和Linux的路径处理
- Java下兼容linux和windows文件路径的间隔符的写法
- [C] 跨平台使用Intrinsic函数范例1——使用SSE、AVX指令集 处理 单精度浮点数组求和(支持vc、gcc,兼容Windows、Linux、Mac)
- windows和linux对文件目录的处理
- 跨平台使用Intrinsic函数范例1——使用SSE、AVX指令集 处理 单精度浮点数组求和(支持vc、gcc,兼容Windows、Linux、Mac)
- linux 下windows 文件中文乱码处理
- 多线程 + java nio 实现按行读取并处理超大文件
- 在windows使用notepad++编写Linux文件的时候,处理换行问题(删掉CF/LF ^M)
- 同一个文件Linux环境下和windows环境下md5_file处理出来的结果不一致
- 批处理:Windows主机通过FTP下载远程Linux主机上文件
- 设置文件的权限,阻止用户访问(兼容Windows和Linux)
- [C] 跨平台使用Intrinsic函数范例1——使用SSE、AVX指令集 处理 单精度浮点数组求和(支持vc、gcc,兼容Windows、Linux、Mac)