java nio 按行读取_JAVA之NIO按行读写大文件,完美解决中文乱码问题
packagecom.chillax.imp;
importjava.io.File;
importjava.io.IOException;
importjava.io.RandomAccessFile;
importjava.nio.ByteBuffer;
importjava.nio.channels.FileChannel;
importjava.util.ArrayList;
importjava.util.Date;
importjava.util.List;
/**
* NIO读取百万级别文件
* @author Chillax
*
*/
publicclassNIO {
publicstaticvoidmain(String args[])throwsException {
intbufSize =1000000;//一次读取的字节长度
File fin = newFile("D:\\test\\20160622_627975.txt");//读取的文件
File fout = newFile("D:\\test\\20160622_627975_1.txt");//写出的文件
Date startDate = newDate();
FileChannel fcin = newRandomAccessFile(fin,"r").getChannel();
ByteBuffer rBuffer = ByteBuffer.allocate(bufSize);
FileChannel fcout = newRandomAccessFile(fout,"rws").getChannel();
ByteBuffer wBuffer = ByteBuffer.allocateDirect(bufSize);
readFileByLine(bufSize, fcin, rBuffer, fcout, wBuffer);
Date endDate = newDate();
System.out.print(startDate+"|"+endDate);//测试执行时间
if(fcin.isOpen()){
fcin.close();
}
if(fcout.isOpen()){
fcout.close();
}
}
publicstaticvoidreadFileByLine(intbufSize, FileChannel fcin,
ByteBuffer rBuffer, FileChannel fcout, ByteBuffer wBuffer) {
String enter = "\n";
List dataList = newArrayList();//存储读取的每行数据
byte[] lineByte =newbyte[0];
String encode = "GBK";
// String encode = "UTF-8";
try{
//temp:由于是按固定字节读取,在一次读取中,第一行和最后一行经常是不完整的行,因此定义此变量来存储上次的最后一行和这次的第一行的内容,
//并将之连接成完成的一行,否则会出现汉字被拆分成2个字节,并被提前转换成字符串而乱码的问题
byte[] temp =newbyte[0];
while(fcin.read(rBuffer) != -1) {//fcin.read(rBuffer):从文件管道读取内容到缓冲区(rBuffer)
intrSize = rBuffer.position();//读取结束后的位置,相当于读取的长度
byte[] bs =newbyte[rSize];//用来存放读取的内容的数组
rBuffer.rewind();//将position设回0,所以你可以重读Buffer中的所有数据,此处如果不设置,无法使用下面的get方法
rBuffer.get(bs);//相当于rBuffer.get(bs,0,bs.length()):从position初始位置开始相对读,读bs.length个byte,并写入bs[0]到bs[bs.length-1]的区域
rBuffer.clear();
intstartNum =0;
intLF =10;//换行符
intCR =13;//回车符
booleanhasLF =false;//是否有换行符
for(inti =0; i
if(bs[i] == LF){
hasLF = true;
inttempNum = temp.length;
intlineNum = i - startNum;
lineByte = newbyte[tempNum + lineNum];//数组大小已经去掉换行符
System.arraycopy(temp, 0, lineByte,0, tempNum);//填充了lineByte[0]~lineByte[tempNum-1]
temp = newbyte[0];
System.arraycopy(bs, startNum, lineByte, tempNum, lineNum);//填充lineByte[tempNum]~lineByte[tempNum+lineNum-1]
String line = newString(lineByte,0, lineByte.length, encode);//一行完整的字符串(过滤了换行和回车)
dataList.add(line);
// System.out.println(line);
writeFileByLine(fcout, wBuffer, line + enter);
//过滤回车符和换行符
if(i +1
startNum = i + 2;
}else{
startNum = i + 1;
}
}
}
if(hasLF){
temp = newbyte[bs.length - startNum];
System.arraycopy(bs, startNum, temp, 0, temp.length);
}else{//兼容单次读取的内容不足一行的情况
byte[] toTemp =newbyte[temp.length + bs.length];
System.arraycopy(temp, 0, toTemp,0, temp.length);
System.arraycopy(bs, 0, toTemp, temp.length, bs.length);
temp = toTemp;
}
}
if(temp !=null&& temp.length >0){//兼容文件最后一行没有换行的情况
String line = newString(temp,0, temp.length, encode);
dataList.add(line);
// System.out.println(line);
writeFileByLine(fcout, wBuffer, line + enter);
}
} catch(IOException e) {
e.printStackTrace();
}
}
/**
* 写到文件上
* @param fcout
* @param wBuffer
* @param line
*/
@SuppressWarnings("static-access")
publicstaticvoidwriteFileByLine(FileChannel fcout, ByteBuffer wBuffer,
String line) {
try{
fcout.write(wBuffer.wrap(line.getBytes("UTF-8")), fcout.size());
} catch(IOException e) {
e.printStackTrace();
}
}
}package com.chillax.imp;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**NIO读取百万级别文件
@author Chillax
*/
public class NIO {
public static void main(String args[]) throws Exception {
int bufSize = 1000000;//一次读取的字节长度
File fin = new File("D:\\test\\20160622_627975.txt");//读取的文件
File fout = new File("D:\\test\\20160622_627975_1.txt");//写出的文件
Date startDate = new Date();
FileChannel fcin = new RandomAccessFile(fin, "r").getChannel();
ByteBuffer rBuffer = ByteBuffer.allocate(bufSize);
FileChannel fcout = new RandomAccessFile(fout, "rws").getChannel();
ByteBuffer wBuffer = ByteBuffer.allocateDirect(bufSize);
readFileByLine(bufSize, fcin, rBuffer, fcout, wBuffer);
Date endDate = new Date();
System.out.print(startDate+"|"+endDate);//测试执行时间
if(fcin.isOpen()){
fcin.close();
}
if(fcout.isOpen()){
fcout.close();
}
}
public static void readFileByLine(int bufSize, FileChannel fcin,
ByteBuffer rBuffer, FileChannel fcout, ByteBuffer wBuffer) {
String enter = "\n";
List<String> dataList = new ArrayList<String>();//存储读取的每行数据
byte[] lineByte = new byte[0];
String encode = "GBK";
//String encode = "UTF-8";
try {
//temp:由于是按固定字节读取,在一次读取中,第一行和最后一行经常是不完整的行,因此定义此变量来存储上次的最后一行和这次的第一行的内容,
//并将之连接成完成的一行,否则会出现汉字被拆分成2个字节,并被提前转换成字符串而乱码的问题
byte[] temp = new byte[0];
while (fcin.read(rBuffer) != -1) {//fcin.read(rBuffer):从文件管道读取内容到缓冲区(rBuffer)
int rSize = rBuffer.position();//读取结束后的位置,相当于读取的长度
byte[] bs = new byte[rSize];//用来存放读取的内容的数组
rBuffer.rewind();//将position设回0,所以你可以重读Buffer中的所有数据,此处如果不设置,无法使用下面的get方法
rBuffer.get(bs);//相当于rBuffer.get(bs,0,bs.length()):从position初始位置开始相对读,读bs.length个byte,并写入bs[0]到bs[bs.length-1]的区域
rBuffer.clear();
int startNum = 0;
int LF = 10;//换行符
int CR = 13;//回车符
boolean hasLF = false;//是否有换行符
for(int i = 0; i < rSize; i++){
if(bs[i] == LF){
hasLF = true;
int tempNum = temp.length;
int lineNum = i - startNum;
lineByte = new byte[tempNum + lineNum];//数组大小已经去掉换行符
System.arraycopy(temp, 0, lineByte, 0, tempNum);//填充了lineByte[0]~lineByte[tempNum-1]
temp = new byte[0];
System.arraycopy(bs, startNum, lineByte, tempNum, lineNum);//填充lineByte[tempNum]~lineByte[tempNum+lineNum-1]
String line = new String(lineByte, 0, lineByte.length, encode);//一行完整的字符串(过滤了换行和回车)
dataList.add(line);
//System.out.println(line);
writeFileByLine(fcout, wBuffer, line + enter);
//过滤回车符和换行符
if(i + 1 < rSize && bs[i + 1] == CR){
startNum = i + 2;
}else{
startNum = i + 1;
}
}
}
if(hasLF){
temp = new byte[bs.length - startNum];
System.arraycopy(bs, startNum, temp, 0, temp.length);
}else{//兼容单次读取的内容不足一行的情况
byte[] toTemp = new byte[temp.length + bs.length];
System.arraycopy(temp, 0, toTemp, 0, temp.length);
System.arraycopy(bs, 0, toTemp, temp.length, bs.length);
temp = toTemp;
}
}
if(temp != null && temp.length > 0){//兼容文件最后一行没有换行的情况
String line = new String(temp, 0, temp.length, encode);
dataList.add(line);
//System.out.println(line);
writeFileByLine(fcout, wBuffer, line + enter);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 写到文件上
* @param fcout
* @param wBuffer
* @param line
*/
@SuppressWarnings("static-access")
public static void writeFileByLine(FileChannel fcout, ByteBuffer wBuffer,
String line) {
try {
fcout.write(wBuffer.wrap(line.getBytes("UTF-8")), fcout.size());
} catch (IOException e) {
e.printStackTrace();
}
}
}
—————END—————
java nio 按行读取_JAVA之NIO按行读写大文件,完美解决中文乱码问题相关推荐
- JAVA之NIO按行读写大文件,完美解决中文乱码问题
JAVA之NIO按行读写大文件,完美解决中文乱码问题 参考文章: (1)JAVA之NIO按行读写大文件,完美解决中文乱码问题 (2)https://www.cnblogs.com/jpfss/p/89 ...
- java读取.properties文件及解决中文乱码问题
java读取.properties文件及解决中文乱码问题 参考文章: (1)java读取.properties文件及解决中文乱码问题 (2)https://www.cnblogs.com/helloq ...
- Java 按行读写文件(解决中文乱码)
import java.io.*;public class EmployeeTest{EmployeeTest(){}// 按行读取文件public void readFile01(){try {Fi ...
- java txt中文乱码,JAVA读取TXT文件 可解决中文乱码问题
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.I ...
- java读写html文件时出现中文乱码问题的解决方法
最近在做HTML静态生成,需要从硬盘上把模版文件的内容读出来.然后,替换相关标签写到指定的文件中.无论是读写,都遇到了中文乱码问题.试过多种方法,发现下面一种可以避免中文乱码.(无论读取还是写入一定要 ...
- cocos2dx java 乱码_[cocos2d-x] --- 完美解决中文乱码
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 一 介绍 最近由于各种各样的原因,好长时间没有学习cocos2d-x了.突然有种害怕的感觉,这样下去,以前学的关于cocos2d-x的一点皮毛会彻底忘记的 ...
- java乱码base64_JavaScript BASE64算法实现(完美解决中文乱码)
JavaScript 的 BASE64 算法 var BASE64={ enKey: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123 ...
- java nio 从内存读信息_JAVA使用NIO技术按行读写大文件并且完美解决中文乱码问题...
packagecom.chillax.imp;importjava.io.File;importjava.io.IOException;importjava.io.RandomAccessFile;i ...
- java生成pdf字体居中,Java生成pdf文件,解决中文乱码问题
如下代码使用itext生成pdf文件,通过设置中文字体避免乱码. /** * AsianTest.java */ import java.io.FileOutputStream; import jav ...
最新文章
- linux 创建 虚拟文件系统设备 文件节点 使用 proc_create 实例 简介
- linux 上删除docker 虚悬镜像
- [云炬创业基础笔记]第四章测试23
- LiveVideoStackCon深圳-编解码的三足鼎立
- WPF实现实现圆形菜单
- OpenShift上的Java EE工作流(技术提示#64)
- 在落雨的鼓浪屿打着伞到处走走找个地方坐坐
- 史上最低价Surface!微软Surface Laptop Go上架 3700元起
- OpenShift 4 - 在控制台中安装使用 Web Terminal
- HBase源码分析:HTable put过程
- 查看Sql语句执行速度
- 小白一步步:EntLib5.0 - Data Access 最简练习
- 解决源码安装手册找不到问题
- 为什么canvas画的是正方形是长方形
- QinQ、VLAN Mapping原理和配置
- 重订增广(清·周希陶)
- 2017找工作的经历,给求职小伙伴的一些建议
- 1+3+5+....+99的和为
- CNN可视化!从CVPR 2022出发,聊聊CAM是如何激活我们文章的热度!
- 分享一个做简历的网站
热门文章
- 哈工大计算机学院非全日制,哈尔滨工业大学非全日制研究生上课方式
- Python笔记 Ch.13 标准库概览
- 对坐标的曲线积分求做功_曲线积分与曲面积分(前篇 曲线积分-坐标曲线积分-格林公式)...
- Easyui后台管理界面设计
- 过勇 清华计算机系,16位清华学霸的简历—比你牛的人还比你努力,膝盖已跪碎...
- Python黑马程序员学习路线
- 谁说国内无RISC-V开源核——您还不知蜂鸟E200?
- 小程序setData执行后,页面没有刷新
- JVM-废弃永久代(PermGen)迎来元空间(Metaspace)
- 十三、java类的封装、继承、多态