Java如何使用多线程读取40M的文件?最好有实例 如题:本人想用IO流读取个文件将文件信息添加到SWT的Table中,但是文件太大,速度较慢,所以想使用多线程一次读100或1000行,将这些行添加到Tale后在读指定行数,应该怎么实现?谢谢各位高手 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 java有个MappedByteBuffer类,他的作用可以把一个文件映射到内存中,然后就能像访问数组一样去读取这个文件。这样不用多线程也可以,你试试public void readResource() { long fileLength = 0; final int BUFFER_SIZE = 0x300000;// 3M的缓冲 for(String fileDirectory:this.readResourceDirectory())//得到文件存放路径,我这里使用了一个方法从XML文件中读出文件的 //存放路径,当然也可以用绝对路径来代替这里的fileDriectory { File file = new File(fileDirectory); fileLength = file.length(); try { MappedByteBuffer inputBuffer = new RandomAccessFile(file,"r").getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fileLength);//读取大文件 byte[] dst = new byte[BUFFER_SIZE];//每次读出3M的内容 for(int offset=0; offset < fileLength; offset+= BUFFER_SIZE) { if(fileLength - offset >= BUFFER_SIZE) { for(int i = 0;i < BUFFER_SIZE;i++) dst = inputBuffer.get(offset + i); } else { for(int i = 0;i < fileLength - offset;i++) dst = inputBuffer.get(offset + i); } //将得到的3M内容给Scanner,这里的XXX是指Scanner解析的分隔符 Scanner scan = new Scanner(new ByteArrayInputStream(dst)).useDelimiter("XXX"); while(scan.hasNext()) { //这里为对读取文本解析的方法 } scan.close(); } } catch (Exception e) { e.printStackTrace(); } }} Dintin请问有相关的实力代码么?参考下,谢谢 多线程,每个线程分别读取2万行左右。 //线程,按指定行数读取文本文件内容 public class NewThread implements Runnable { String ThreadName; //线程名称 Thread ThreadObject; //线程 ... NewThread(String threadname , String filename) { ThreadName = threadname; FileName = filename; String ReturnStr = ""; new Thread(this , ThreadName).start(); } public void run() { try { int CurrentLineNo = 0; //当前行号 System.out.println(ThreadName + "开始干活了"); long Time1 = System.currentTimeMillis(); File f = new File(FileName); if(f.exists() == false || f.isDirectory() || f.canRead() == false) { System.out.println("打文件错误!"); } FileReader fr = new FileReader(FileName); BufferedReader read = new BufferedReader(fr); while((sline = read.readLine()) != null) { tmpsline1 = sline; //操作前的文本 if(sline.length() > 0 && sline.indexOf(",") > 0) { //按行写入数据 try { SQL[i] = GetSpecialSQL(sline);//由该行文本取得要执行的SQL ... 每50条语句批量操作一次 stms.executeBatch(SQL); ... } catch(Exception e) { TxtlineCount--; RecordErrorLog(sline + e.toString()); //记录错误 e.printStackTrace(); } } CurrentLineNo++; //有效行,行数才加 } read.close(); fr.close(); stmt.close(); //关闭数据库操作对象 con.close(); //关闭数据库连接 f.delete(); //删除临时文件 } //创建线程读取文本并写库 public TestReadFileAndIntoDB(){ int PreBufferLines = 20000; //每个Buffer的文本行数 byte b[] = new byte[1024]; NewThread UpDBThread; //定义一个更新数据库的进程 long FileTotalLines[] = {0 , 0}; // long Realcount = 0 , TotalCount = 0; File f = new File(fileName); if(f.exists() == false || f.isDirectory() || f.canRead() == false) { System.out.println("打文件错误!"); return "打文件错误!"; } try { //E:\JavaProject\UpdateDBTest\defaultroot/file/testFile.txt //约17万行,40M String sline; //先创建临时文件名 格式:路径+源文件名+序号+扩展名 TempFileName = TrueFullPath + "/" + TrueFileName + j + "." + TrueExtName; System.out.println("正在读取源文件" + TrueFileName + "." + TrueExtName + "并自动生成临时文件.."); FileReader fr = new FileReader(fileName); BufferedReader read = new BufferedReader(fr); //FileWriter fw = new FileWriter(TempFileName); //BufferedWriter write = new BufferedWriter(fw); File fw = new File(TempFileName); FileOutputStream write = new FileOutputStream(fw); try { while((sline = read.readLine()) != null) { if(sline.length() > 0) { //FileContentList.add(sline); Realcount++; //该行不为空,则有效行数加1 if(i < PreBufferLines) { //当前行数小于指定的分割点时,写入原定的临时文件 sline += "\r\n"; //加上回车换行 b=sline.getBytes() ;//转换成二制流 write.write(b); i++; } else { //当前行大小分割点时,要换临时文件名了 j++; //关闭原来的读写文件的对象。并按新临时文件重新打开 write.close(); //fw.close(); new NewThread(j + "-" + (Realcount - 1) , TempFileName ); //执行线程 //生成新的文件临时文件名 TempFileName = TrueFullPath + "/" + TrueFileName + j + "." + TrueExtName; fw = new File(TempFileName); write = new FileOutputStream(fw); sline += "\r\n"; //加上回车换行 b=sline.getBytes() ;//转换成二制流 write.write(b); i = 1; } } TotalCount++; //不管该行是否空,总行数加1 } } catch(Exception e) { System.out.println("读写文件并开线程的错误:" + e.toString()); } write.close(); //fw.close(); new NewThread("最后一线程:" + Realcount , TempFileName); //执行线程 read.close(); //读文件关闭 fr.close(); // read = null; fr = null; f = null; }这段代码是几年给客户网站做的一个导数据的程序。主要功能是多线程分块读取源文件,多线程导入数据。采取的是分块读取并生成临时文件,然后在线程内读取临时文件并导入。LZ可看看历史贴子,当时也遇到不少问题,主要是RedHat9 Linux 环境下程序运行可能与windows下有差异。http://topic.csdn.net/t/20040424/18/3004091.htmlhttp://topic.csdn.net/t/20040414/10/2962641.htmlhttp://topic.csdn.net/t/20040202/10/2694219.html 个人意见:MappedByteBuffer 主要是用来处理一个文件被多次读取的情况,而且对读取大文件性能没有太大的提升。 正则问题 跪求帮助 寻!以为会JNI的朋友帮忙啊~!! 文件写数据怎么换行? java实现的telnet功能到windows为啥输出的是乱码啊? 关于正则表达式的问题,高手帮忙 for()小问题 望大推荐几本Java的好书,多谢:) 求救:jcreator 的track呀 java poi 导出excel不能超过65536行 还是javac命令问题 小小的小问题!!!!!!
long fileLength = 0;
final int BUFFER_SIZE = 0x300000;// 3M的缓冲
for(String fileDirectory:this.readResourceDirectory())//得到文件存放路径,我这里使用了一个方法从XML文件中读出文件的
//存放路径,当然也可以用绝对路径来代替这里的fileDriectory
{
File file = new File(fileDirectory);
fileLength = file.length();
try {
MappedByteBuffer inputBuffer =
new RandomAccessFile(file,"r").getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fileLength);//读取大文件
byte[] dst = new byte[BUFFER_SIZE];//每次读出3M的内容
for(int offset=0; offset < fileLength; offset+= BUFFER_SIZE)
{
if(fileLength - offset >= BUFFER_SIZE)
{
for(int i = 0;i < BUFFER_SIZE;i++)
dst = inputBuffer.get(offset + i);
}
else
{
for(int i = 0;i < fileLength - offset;i++)
dst = inputBuffer.get(offset + i);
}
//将得到的3M内容给Scanner,这里的XXX是指Scanner解析的分隔符
Scanner scan = new Scanner(new ByteArrayInputStream(dst)).useDelimiter("XXX");
while(scan.hasNext())
{
//这里为对读取文本解析的方法
}
scan.close();
}
} catch (Exception e)
{
e.printStackTrace();
}
}
}
//线程,按指定行数读取文本文件内容
public class NewThread implements Runnable
{
String ThreadName; //线程名称
Thread ThreadObject; //线程
...
NewThread(String threadname , String filename)
{
ThreadName = threadname;
FileName = filename;
String ReturnStr = "";
new Thread(this , ThreadName).start();
} public void run()
{
try
{
int CurrentLineNo = 0; //当前行号
System.out.println(ThreadName + "开始干活了");
long Time1 = System.currentTimeMillis();
File f = new File(FileName);
if(f.exists() == false || f.isDirectory() || f.canRead() == false)
{
System.out.println("打文件错误!");
} FileReader fr = new FileReader(FileName);
BufferedReader read = new BufferedReader(fr);
while((sline = read.readLine()) != null)
{ tmpsline1 = sline; //操作前的文本
if(sline.length() > 0 && sline.indexOf(",") > 0)
{
//按行写入数据
try
{
SQL[i] = GetSpecialSQL(sline);//由该行文本取得要执行的SQL
...
每50条语句批量操作一次
stms.executeBatch(SQL);
... }
catch(Exception e)
{ TxtlineCount--;
RecordErrorLog(sline + e.toString()); //记录错误
e.printStackTrace();
}
}
CurrentLineNo++; //有效行,行数才加
} read.close();
fr.close();
stmt.close(); //关闭数据库操作对象
con.close(); //关闭数据库连接
f.delete(); //删除临时文件
} //创建线程读取文本并写库
public TestReadFileAndIntoDB(){
int PreBufferLines = 20000; //每个Buffer的文本行数
byte b[] = new byte[1024];
NewThread UpDBThread; //定义一个更新数据库的进程 long FileTotalLines[] = {0 , 0}; //
long Realcount = 0 , TotalCount = 0;
File f = new File(fileName);
if(f.exists() == false || f.isDirectory() || f.canRead() == false)
{
System.out.println("打文件错误!");
return "打文件错误!";
}
try
{ //E:\JavaProject\UpdateDBTest\defaultroot/file/testFile.txt //约17万行,40M
String sline;
//先创建临时文件名 格式:路径+源文件名+序号+扩展名
TempFileName = TrueFullPath + "/" + TrueFileName + j + "." + TrueExtName;
System.out.println("正在读取源文件" + TrueFileName + "." + TrueExtName + "并自动生成临时文件..");
FileReader fr = new FileReader(fileName);
BufferedReader read = new BufferedReader(fr);
//FileWriter fw = new FileWriter(TempFileName);
//BufferedWriter write = new BufferedWriter(fw);
File fw = new File(TempFileName);
FileOutputStream write = new FileOutputStream(fw);
try
{
while((sline = read.readLine()) != null)
{
if(sline.length() > 0)
{
//FileContentList.add(sline);
Realcount++; //该行不为空,则有效行数加1
if(i < PreBufferLines)
{ //当前行数小于指定的分割点时,写入原定的临时文件
sline += "\r\n"; //加上回车换行
b=sline.getBytes() ;//转换成二制流
write.write(b); i++;
}
else
{ //当前行大小分割点时,要换临时文件名了
j++;
//关闭原来的读写文件的对象。并按新临时文件重新打开
write.close();
//fw.close();
new NewThread(j + "-" + (Realcount - 1) , TempFileName ); //执行线程
//生成新的文件临时文件名
TempFileName = TrueFullPath + "/" + TrueFileName + j + "." + TrueExtName;
fw = new File(TempFileName);
write = new FileOutputStream(fw);
sline += "\r\n"; //加上回车换行
b=sline.getBytes() ;//转换成二制流
write.write(b);
i = 1;
} }
TotalCount++; //不管该行是否空,总行数加1
} }
catch(Exception e)
{
System.out.println("读写文件并开线程的错误:" + e.toString());
}
write.close();
//fw.close();
new NewThread("最后一线程:" + Realcount , TempFileName); //执行线程
read.close(); //读文件关闭
fr.close(); //
read = null;
fr = null;
f = null;
}
这段代码是几年给客户网站做的一个导数据的程序。
主要功能是多线程分块读取源文件,多线程导入数据。
采取的是分块读取并生成临时文件,然后在线程内读取临时文件并导入。
LZ可看看历史贴子,当时也遇到不少问题,主要是RedHat9 Linux 环境下程序运行可能与windows下有差异。
http://topic.csdn.net/t/20040424/18/3004091.html
http://topic.csdn.net/t/20040414/10/2962641.html
http://topic.csdn.net/t/20040202/10/2694219.html