JAVA遇到大批数据处理时会出现Java heap space的报错的解决方案
(2012-09-26 21:00:15)
标签:
javaheapspaceit |
分类: Code |
JAVA遇到大批数据处理时会出现Java heap space的报错的解决方案
Java heap space一直是困扰我们的一个问题。像Matlab就可以一次性读取5000*5000的数据到一个矩阵matrix中。然而Java确不行。
我遇到实验室处理一个“合并5000左右txt文档到一个txt文件中”的问题,相同的算法用Matlab就不会出现内存不足的问题,而JAVA则会报出:java.lang.OutOfMemoryError: Java heap space。从这里可以判断的说Matlab是为处理大型数据而设计(It is conceived for),所以其执行代码时对内存启动了自动的分配与管理。因为我的5000左右txt文档大约有180M,显而易见,同时读到内存肯定会出现内存空间不足的警告,所以也不怪JAVA。当然,你可以在运行JAVA代码之前提高内存分配值,但是这实际上不能从根本上解决问题。因为哪天万一还有更大的数据遇到时,你是不是还要继续增大内存?要知道现在一般电脑的内存也就2G,就算1G的也很普遍。
所以根本上我觉得是要改变你的算法。一个很自然的思路就是:数据大了就分配处理嘛。
所以我最后就是利用了递归的手段,将5000左右txt文档分批调入内存进行处理,处理一部分就释放一部分资源。这样不管是5000个数据文件还是7000,9000都没问题。试验测得我的情况是如果不进行分批处理而是一次性调入内存在合并文档,那最大文件数只能是2000,就是超过2000个数据文件就会出现java.lang.OutOfMemoryError: Java heap space这样的错误。
Matlab的缺点就是速度慢。所以处理海里数据为求速度还是可以试一下用JAVA实现的。我的实验结果表明,速度相差几十倍。
下面将一步一步介绍对这个同一问题不同的编程版本以及其结果:
1.
本程序是属于数据处理程序,用JAVA所实现。
spectrometer中光栅的每次采样所获得的数据被保存在一个文本文件中, 分为2列:第一列为波长值,第二列为对应的光强值。 第1次采样文本文件被命名为“000000.txt”,第二个为“000001.txt”,依次类推。 比如若让spectrometer采样3mins,大概会出现4000次采样, 被保存的文件就为000000.txt~003999.txt
此程序使用的是二维LinkedList类型来拉取数据。 LinkedList:就是采用链表结构保存对象。 PS:JAVA中集合类分为List,Set,和Map。 List又有LinkedList和ArrayList; Set分为HashSet和TreeSet; Map分为HashMap和TreeMap。 顾名思义,Hash就是由哈希表提供支持,Tree树结构提供了排序和顺序输出的功能。
- package
com.han; -
- import
java.io.*; - import
java.util.*; -
-
- public
class CombinedTextSpectres { -
staticfinal int N= 6;//N是保存的文件名称的长度 -
staticfinal int M= 4520;//M是保存的文件数目 -
@SuppressWarnings({"unchecked", "rawtypes" }) -
publicstatic void main(String[] args) { -
//TODO Auto-generated method stub -
longstartTime=System.currentTimeMillis(); -
try{ -
//若是当前class类文件目录则用下面的getClass().getRessource()代码 -
//Filenew_file=new File(new File(new test().getClass().getResource("").toURI()),"combinedFile.txt"); -
newFile new_file= File( "/home/han/Desktop","combinedFile.txt");//定义合并后的文件的保存路径 -
newFileWriter fw = FileWriter(new_file); -
newBufferedWriter bfw= BufferedWriter(fw); -
newList row= LinkedList(); -
intnum_line 0;= -
for(inti= 0;i -
newList column= LinkedList(); -
-
"00"+i;//"00"是保存的文件的前缀String filename= -
inttemLength=filename.length(); -
for(intj= 0;j -
"0"+filename;filename= -
} -
".txt";filename=filename+ -
-
//定义存放离散采样数据文件的文件夹 -
newFile file= File( "/home/han/UbuntuOne/apresmidi ,filename);sans pola" -
//Filefile=new File(new File(new test().getClass().getResource("").toURI()),filename); -
newFileReader fr= FileReader(file); -
newBufferedReader bfr= BufferedReader(fr); -
-
null;String s= -
while((s=bfr.readLine())!=null){ -
',',s=s.replace( '.'); -
if(i==0){ -
column.add(s); -
else{} -
"\t");String[] sArray=s.split( -
1]);column.add(sArray[ -
} -
} -
row.add(column); -
num_line=column.size(); -
bfr.close(); -
fr.close(); -
} -
"FilesSystem.out.println( are );all viewed" -
for(inti= 0;i -
Iterator it=row.iterator(); -
while(it.hasNext()){ -
List tempList=(List)it.next(); -
bfw.write((String)tempList.get(i)); -
"\t");bfw.write( -
} -
-
bfw.newLine(); -
} -
bfw.close(); -
fw.close(); -
"OK");System.out.println( -
catch} (Exception e) { -
//TODO Auto-generated catch block -
e.printStackTrace(); -
} -
longendTime=System.currentTimeMillis(); -
"耗费时间:System.out.println( " +(endTime-startTime)+"ms" ); -
} -
}
package com.han;
import java.io.*;
import java.util.*;
public class CombinedTextSpectres {
static final int N=6;//N是保存的文件名称的长度
static final int M=4520;//M是保存的文件数目
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void main(String[] args) {
// TODO Auto-generated method stub
long startTime=System.currentTimeMillis();
try {
//若是当前class类文件目录则用下面的getClass().getRessource()代码
//File new_file=new File(new File(new test().getClass().getResource("").toURI()),"combinedFile.txt");
File new_file=new File("/home/han/Desktop","combinedFile.txt");//定义合并后的文件的保存路径
FileWriter fw = new FileWriter(new_file);
BufferedWriter bfw=new BufferedWriter(fw);
List row=new LinkedList();
int num_line = 0;
for(int i=0;i
运行结果:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.ArrayList.subList(ArrayList.java:915)
at java.lang.String.split(String.java:2359)
at java.lang.String.split(String.java:2403)
at com.han.CombinedTextSpectres.main(CombinedTextSpectres.java:64)
2. 若减少要合并的离散数据文件个数,上面的程序是可以成功运行的。为方便读者,还是把数据源和代码分别列出如下:
- package
com.han; -
- import
java.io.*; - import
java.util.*; -
-
- public
class CombinedTextSpectres { -
staticfinal int N= 6;//N是保存的文件名称的长度 -
staticfinal int M= 357;//M是保存的文件数目 -
@SuppressWarnings({"unchecked", "rawtypes" }) -
publicstatic void main(String[] args) { -
//TODO Auto-generated method stub -
longstartTime=System.currentTimeMillis(); -
try{ -
//若是当前class类文件目录则用下面的getClass().getRessource()代码 -
//Filenew_file=new File(new File(new test().getClass().getResource("").toURI()),"combinedFile.txt"); -
newFile new_file= File( "/home/han/Desktop","combinedFile.txt");//定义合并后的文件的保存路径 -
newFileWriter fw = FileWriter(new_file); -
newBufferedWriter bfw= BufferedWriter(fw); -
newList row= LinkedList(); -
intnum_line 0;= -
for(inti= 0;i -
newList column= LinkedList(); -
-
"00"+i;//"00"是保存的文件的前缀String filename= -
inttemLength=filename.length(); -
for(intj= 0;j -
"0"+filename;filename= -
} -
".txt";filename=filename+ -
-
//定义存放离散采样数据文件的文件夹 -
newFile file= File( "/home/han/UbuntuOne/spectre ,filename);sans pola" -
//Filefile=new File(new File(new test().getClass().getResource("").toURI()),filename); -
newFileReader fr= FileReader(file); -
newBufferedReader bfr= BufferedReader(fr); -
-
null;String s= -
while((s=bfr.readLine())!=null){ -
',',s=s.replace( '.'); -
if(i==0){ -
column.add(s); -
else{} -
"\t");String[] sArray=s.split( -
1]);column.add(sArray[ -
} -
} -
row.add(column); -
num_line=column.size(); -
bfr.close(); -
fr.close(); -
} -
"FilesSystem.out.println( are );all viewed" -
for(inti= 0;i -
Iterator it=row.iterator(); -
while(it.hasNext()){ -
List tempList=(List)it.next(); -
bfw.write((String)tempList.get(i)); -
"\t");bfw.write( -
} -
-
bfw.newLine(); -
} -
bfw.close(); -
fw.close(); -
"OK");System.out.println( -
catch} (Exception e) { -
//TODO Auto-generated catch block -
e.printStackTrace(); -
} -
longendTime=System.currentTimeMillis(); -
"耗费时间:System.out.println( " +(endTime-startTime)+"ms" ); -
} -
}
package com.han;
import java.io.*;
import java.util.*;
public class CombinedTextSpectres {
static final int N=6;//N是保存的文件名称的长度
static final int M=357;//M是保存的文件数目
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void main(String[] args) {
// TODO Auto-generated method stub
long startTime=System.currentTimeMillis();
try {
//若是当前class类文件目录则用下面的getClass().getRessource()代码
//File new_file=new File(new File(new test().getClass().getResource("").toURI()),"combinedFile.txt");
File new_file=new File("/home/han/Desktop","combinedFile.txt");//定义合并后的文件的保存路径
FileWriter fw = new FileWriter(new_file);
BufferedWriter bfw=new BufferedWriter(fw);
List row=new LinkedList();
int num_line = 0;
for(int i=0;i
运行结果:Files are all viewed
OK
耗费时间: 14880 ms
3. 下面的方法一样的使用二维LinkedList类型来读取数据。 但是在重新写入到单个合并文件时使用了StringBuilder, 经测试,效率和CombinedTextSpectres(第一版)差不多。
但是依然对于大数据如超过2000个文件要合并时则出现内存泄漏。
- package
com.han; -
- import
java.io.*; - import
java.util.*; -
-
- public
class CombinedTextSpectres_2 { -
staticfinal int N= 6;//N是保存的文件名称的长度 -
staticfinal int M= 357;//M是保存的文件数目 -
@SuppressWarnings({"unchecked", "rawtypes" }) -
publicstatic void main(String[] args) { -
//TODO Auto-generated method stub -
longstartTime=System.currentTimeMillis(); -
try{ -
//若是当前class类文件目录则用下面的getClass().getRessource()代码 -
//Filenew_file=new File(new File(new test().getClass().getResource("").toURI()),"combinedFile.txt"); -
newFile new_file= File( "/home/han/Desktop","combinedFile.txt"); -
newFileWriter fw = FileWriter(new_file); -
newBufferedWriter bfw= BufferedWriter(fw); -
newList row= LinkedList(); -
intnum_line 0;= -
for(inti= 0;i -
newList column= LinkedList(); -
-
"00"+i;//"00"是保存的文件的前缀String filename= -
inttemLength=filename.length(); -
for(intj= 0;j -
"0"+filename;filename= -
} -
".txt";filename=filename+ -
//定义存放离散采样数据文件的文件夹 -
newFile file= File( "/media/96D0265ED0264539/Users/HAN/Documents/ThèseISMO/DonneesLabo/10_10-14_10/spectre ,filename);sans pola" -
//Filefile=new File(new File(new test().getClass().getResource("").toURI()),filename); -
newFileReader fr= FileReader(file); -
newBufferedReader bfr= BufferedReader(fr); -
-
null;String s= -
while((s=bfr.readLine())!=null){ -
',',s=s.replace( '.'); -
if(i==0){ -
column.add(s); -
else{} -
"\t");String[] sArray=s.split( -
1]);column.add(sArray[ -
} -
} -
row.add(column); -
num_line=column.size(); -
bfr.close(); -
fr.close(); -
} -
"FilesSystem.out.println( are );all viewed" -
newStringBuilder sb= StringBuilder( ""); -
for(inti= 0;i -
Iterator it=row.iterator(); -
while(it.hasNext()){ -
List tempList=(List)it.next(); -
sb.append((String)tempList.get(i)); -
"\t");sb.append( -
} -
//以下这种应用.size()的遍历方法在大循环的时候效率要略低于上面的.iterator()方法 -
-
"\n");sb.append( -
} -
bfw.write(sb.toString()); -
bfw.close(); -
fw.close(); -
"OK");System.out.println( -
catch} (Exception e) { -
//TODO Auto-generated catch block -
e.printStackTrace(); -
} -
longendTime=System.currentTimeMillis(); -
"耗费时间:System.out.println( " +(endTime-startTime)+"ms" ); -
} -
}
package com.han;
import java.io.*;
import java.util.*;
public class CombinedTextSpectres_2 {
static final int N=6;//N是保存的文件名称的长度
static final int M=357;//M是保存的文件数目
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void main(String[] args) {
// TODO Auto-generated method stub
long startTime=System.currentTimeMillis();
try {
//若是当前class类文件目录则用下面的getClass().getRessource()代码
//File new_file=new File(new File(new test().getClass().getResource("").toURI()),"combinedFile.txt");
File new_file=new File("/home/han/Desktop","combinedFile.txt");
FileWriter fw = new FileWriter(new_file);
BufferedWriter bfw=new BufferedWriter(fw);
List row=new LinkedList();
int num_line = 0;
for(int i=0;i
运行结果:
OK
耗费时间: 15155 ms
4. 下面的方法一样的使用经典固定长度数组,以及在重新写入到单个合并文件时使用了StringBuilder (其实因为BufferedWriter也是缓存,所以有无SringBuilder效率一样)。 经测试,效率比CombinedTextSpectres(第一版) 和CombinedTextSpectres_2(第二版)都要高出10倍!。
但是依然对于大数据如超过2000个文件要合并时则出现内存泄漏。
- package
com.han; -
- import
java.io.*; -
- public
class CombinedTextSpectres_3 { -
//此方法使用自动探测单个文件的行数(即spectrometre的采样点数),无SringBuilder -
staticfinal int N= 6;//N是保存的文件名称的长度 -
-
staticfinal int M= 357;//M是保存的文件数目 -
-
publicstatic void main(String[] args) { -
//TODO Auto-generated method stub -
longstartTime=System.currentTimeMillis(); -
try{ -
//定义存放离散采样数据文件的文件夹 -
"/media/96D0265ED0264539/Users/HAN/Documents/ThèseString dirPath= ISMO/DonneesLabo/10_10-14_10/spectre ;sans pola" -
newFile file_temp= File(dirPath, "000000.txt"); -
newFileReader fr_temp= FileReader(file_temp); -
newBufferedReader bfr_temp= BufferedReader(fr_temp); -
intNLine 0;//自动探测单个文件的行数(即spectrometre的采样点数)= -
@SuppressWarnings("unused") -
null;String s_temp= -
while((s_temp=bfr_temp.readLine())!=null){ -
NLine++; -
} -
bfr_temp.close(); -
fr_temp.close(); -
newString[][] CombinedArray= String[NLine][M+ 1]; -
-
newFile new_file= File( "/home/han/Desktop","combinedFile.txt"); -
//若是当前class类文件目录则用下面的getClass().getRessource()代码 -
//Filenew_file=new File(new File(new test().getClass().getResource("").toURI()),"combinedFile.txt"); -
newFileWriter fw = FileWriter(new_file); -
newBufferedWriter bfw= BufferedWriter(fw); -
for(inti= 0;i -
"00"+i;//"00"是保存的文件的前缀String filename= -
inttemLength=filename.length(); -
for(intj= 0;j -
"0"+filename;filename= -
} -
".txt";filename=filename+ -
-
newFile file= File(dirPath,filename); -
//Filefile=new File(new File(new test().getClass().getResource("").toURI()),filename); -
newFileReader fr= FileReader(file); -
newBufferedReader bfr= BufferedReader(fr); -
-
null;String s= -
intnum_line 0;= -
while((s=bfr.readLine())!=null){ -
',',s=s.replace( '.'); -
"\t");String[] sArray=s.split( -
if(i==0){ -
0]=sArray[0];CombinedArray[num_line][ -
1]=sArray[1];CombinedArray[num_line][ -
else{} -
1]=sArray[1];CombinedArray[num_line][i+ -
} -
num_line++; -
} -
bfr.close(); -
fr.close(); -
} -
"FilesSystem.out.println( are );all viewed" -
for(inti= 0;i -
for(intj= 0;j1;j++){ -
bfw.write(CombinedArray[i][j]); -
"\t");bfw.write( -
} -
bfw.newLine(); -
} -
bfw.close(); -
fw.close(); -
"OK");System.out.println( -
catch} (Exception e) { -
//TODO Auto-generated catch block -
e.printStackTrace(); -
} -
longendTime=System.currentTimeMillis(); -
"耗费时间:System.out.println( " +(endTime-startTime)+"ms" ); -
} -
}
package com.han;
import java.io.*;
public class CombinedTextSpectres_3 {
//此方法使用自动探测单个文件的行数(即spectrometre的采样点数),无SringBuilder
static final int N=6;//N是保存的文件名称的长度
static final int M=357;//M是保存的文件数目
public static void main(String[] args) {
// TODO Auto-generated method stub
long startTime=System.currentTimeMillis();
try {
//定义存放离散采样数据文件的文件夹
String dirPath="/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/10_10-14_10/spectre sans pola";
File file_temp=new File(dirPath,"000000.txt");
FileReader fr_temp=new FileReader(file_temp);
BufferedReader bfr_temp=new BufferedReader(fr_temp);
int NLine = 0;//自动探测单个文件的行数(即spectrometre的采样点数)
@SuppressWarnings("unused")
String s_temp=null;
while((s_temp=bfr_temp.readLine())!=null){
NLine++;
}
bfr_temp.close();
fr_temp.close();
String[][] CombinedArray=new String[NLine][M+1];
File new_file=new File("/home/han/Desktop","combinedFile.txt");
//若是当前class类文件目录则用下面的getClass().getRessource()代码
//File new_file=new File(new File(new test().getClass().getResource("").toURI()),"combinedFile.txt");
FileWriter fw = new FileWriter(new_file);
BufferedWriter bfw=new BufferedWriter(fw);
for(int i=0;i
运行结果: Files are all viewed
OK
耗费时间: 1802 ms
5.
代码中level变量就是每次分批处理的数目,本程序设为1000。
此方法使用自动探测单个文件的行数(即spectrometre的采样点数), 因为BufferedWriter也是缓存,所以有无SringBuilder效率差不多, 本程序因此写入到单个合并文件时没有使用StringBuilder。 但是写的时候也向系统申请了String[][] CombinedArray=new String[2048][Column]; 其中Column为批处理次数,比如3或4。由此可见虽然载入的还是“整个数据”, 但申请的String二维数组只有String[2048][4],系统处理速度和内存占用却大大改善!
- package
com.han; -
- import
java.io.*; -
-
- public
class CombinedTextSpectres_4 { -
staticint N= 6;//N是保存的文件名称的长度 -
staticint M= 4520;//M是保存的文件数目 -
intlevel= 1000;//每次分批处理的数目 -
intfilenumBegin; //每批处理时的第一个文件名 -
intfilenumEnd; //每批处理时的最后一个文件名 -
"/media/96D0265ED0264539/Users/HAN/Documents/ThèseString dirPath= ISMO/DonneesLabo/17_10-21_10/apresmidi ;//定义存放离散采样数据文件的文件夹sans pola" -
staticFile //定义临时文件夹来存放每批合并后的结果文件tempFile; -
staticString "/home/han/Desktop";//定义存放最终结果文件的文件夹destDirPath= -
-
publicCombinedTextSpectres_4(){ -
try{ -
0);combine(M, -
catch} (IOException e) { -
//TODO Auto-generated catch block -
e.printStackTrace(); -
} -
} -
-
-
voidcombine( intnum, intloop) throwsIOException{ -
if(num>level){ -
//如果剩余的文件数还是大于设定的level=1000的话,则继续往下递归 -
1);combine(num-level,loop+ -
} -
filenumBegin=loop*level; -
if(num<=level){ -
filenumEnd=filenumBegin+num; -
else{} -
filenumEnd=filenumBegin+level; -
} -
-
//定义经典固定长度数组,因为比集合等动态数组效率要高。 -
//并且此时也可以保证String[][]CombinedArray不会 -
//超出内存,因为每次处理的不会超过level=1000 -
newString[][] CombinedArray= String[ 2048][filenumEnd-filenumBegin]; -
-
for(inti=filenumBegin;i -
"00"+i;//"00"是保存的文件的前缀String filename= -
inttemLength=filename.length(); -
for(intj= 0;j -
"0"+filename;filename= -
} -
".txt";filename=filename+ -
newFile file= File(dirPath,filename); -
newFileReader fr= FileReader(file); -
newBufferedReader bfr= BufferedReader(fr); -
intnum_line 0;= -
null;String s= -
while((s=bfr.readLine())!=null){ -
if(i==0){ -
0]=s.replace(',',CombinedArray[num_line][ '.'); -
else{} -
"\t");String[] sArray=s.split( -
1].replace(',',CombinedArray[num_line][i-filenumBegin]=sArray[ '.'); -
} -
num_line++; -
} -
bfr.close(); -
fr.close(); -
} -
//System.out.println("Filesare all viewed"); -
-
-
".txt";String filename=loop+ -
newtempFile= File(dirPath, "temp"); -
if(!tempFile.exists()){ -
tempFile.mkdir(); -
} -
newFile new_file= File(tempFile,filename); -
newFileWriter fw = FileWriter(new_file); -
newBufferedWriter bfw= BufferedWriter(fw); -
for(inti= 0;i<</SPAN>2048;i++){ -
for(intj= 0;j -
bfw.write(CombinedArray[i][j]); -
"\t");bfw.write( -
} -
bfw.newLine(); -
} -
null;//让JAVA垃圾自动回收装置认为此CombinedArray变量可以回收CombinedArray= -
bfw.close(); -
fw.close(); -
System.out.println(new_file); -
"OK");System.out.println( -
} -
publicstatic void main(String[] args) { -
//TODO Auto-generated method stub -
longstartTime=System.currentTimeMillis(); -
newCombinedTextSpectres_4(); -
-
File[] FileArray=tempFile.listFiles(); -
intColumn=FileArray.length; -
newString[][] CombinedArray= String[ 2048][Column]; -
try{ -
for(inti= 0;i -
newFileReader fr= FileReader(FileArray[i]); -
newBufferedReader bfr= BufferedReader(fr); -
intnum_line 0;= -
null;String s= -
while((s=bfr.readLine())!=null){ -
CombinedArray[num_line][i]=s; -
num_line++; -
} -
bfr.close(); -
fr.close(); -
} -
newFile new_file= File(destDirPath, "CombinedSpectres.txt"); -
newFileWriter fw = FileWriter(new_file); -
newBufferedWriter bfw= BufferedWriter(fw); -
-
"IntegratedString ExperienceCondition= time ;is 1 ms, with the HR Spectrometer, with polarizorH, using the syringe Rh6G+Glycol and the other is Huile" -
bfw.write(ExperienceCondition); -
bfw.newLine(); -
-
"Wavelengthbfw.write( (nm)\t" ); -
for(inti= 0;i -
"00"+i;//"00"是保存的文件的前缀String filename= -
inttemLength=filename.length(); -
for(intj= 0;j -
"0"+filename;filename= -
} -
".txt";filename=filename+ -
bfw.write(filename); -
"\t");bfw.write( -
} -
bfw.newLine(); -
-
for(inti= 0;i<</SPAN>2048;i++){ -
for(intj= 0;j -
bfw.write(CombinedArray[i][j]); -
//bfw.write("\t"); -
} -
bfw.newLine(); -
} -
null;CombinedArray= -
bfw.close(); -
fw.close(); -
System.out.println(new_file); -
"OK");System.out.println( -
catch} (Exception e) { -
//TODO Auto-generated catch block -
e.printStackTrace(); -
} -
longendTime=System.currentTimeMillis(); -
"耗费时间:System.out.println( " +(endTime-startTime)+"ms" ); -
} -
}
package com.han;
import java.io.*;
public class CombinedTextSpectres_4 {
static int N=6;//N是保存的文件名称的长度
static int M=4520;//M是保存的文件数目
int level=1000;//每次分批处理的数目
int filenumBegin;//每批处理时的第一个文件名
int filenumEnd;//每批处理时的最后一个文件名
String dirPath="/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/17_10-21_10/apresmidi sans pola";//定义存放离散采样数据文件的文件夹
static File tempFile; //定义临时文件夹来存放每批合并后的结果文件
static String destDirPath="/home/han/Desktop";//定义存放最终结果文件的文件夹
public CombinedTextSpectres_4(){
try {
combine(M,0);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
void combine(int num, int loop) throws IOException{
if(num>level){
//如果剩余的文件数还是大于设定的level=1000的话,则继续往下递归
combine(num-level,loop+1);
}
filenumBegin=loop*level;
if(num<=level){
filenumEnd=filenumBegin+num;
}else{
filenumEnd=filenumBegin+level;
}
//定义经典固定长度数组,因为比集合等动态数组效率要高。
//并且此时也可以保证String[][] CombinedArray不会
//超出内存,因为每次处理的不会超过level=1000
String[][] CombinedArray=new String[2048][filenumEnd-filenumBegin];
for(int i=filenumBegin;i<2048;i++){
for(int j=0;j<2048;i++){
for(int j=0;j
运行结果:/media/96D0265ED0264539/Users/HAN/Documents/Thèse
ISMO/DonneesLabo/17_10-21_10/apresmidi sans pola/temp/4.txtOK
/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/17_10-21_10/apresmidi sans pola/temp/3.txt
OK
/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/17_10-21_10/apresmidi sans pola/temp/2.txt
OK
/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/17_10-21_10/apresmidi sans pola/temp/1.txt
OK
/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/17_10-21_10/apresmidi sans pola/temp/0.txt
OK
/home/han/Desktop/CombinedSpectres.txt
OK
耗费时间: 30842 ms
6.
- package
com.han; -
- import
java.io.*; -
-
- public
class CombinedTextSpectres_5 { -
staticint N= 6;//N是保存的文件名称的长度 -
staticint M= 4520;//M是保存的文件数目 -
intlevel= 1000;//每次分批处理的数目 -
intfilenumBegin; //每批处理时的第一个文件名 -
intfilenumEnd; //每批处理时的最后一个文件名 -
"/media/96D0265ED0264539/Users/HAN/Documents/ThèseString dirPath= ISMO/DonneesLabo/17_10-21_10/apresmidi ;//定义存放离散采样数据文件的文件夹sans pola" -
staticFile //定义临时文件夹来存放每批合并后的结果文件tempFile; -
staticString "/home/han/Desktop";//定义存放最终结果文件的文件夹destDirPath= -
-
publicCombinedTextSpectres_5(){ -
try{ -
0);combine(M, -
catch} (IOException e) { -
//TODO Auto-generated catch block -
e.printStackTrace(); -
} -
} -
-
-
voidcombine( intnum, intloop) throwsIOException{ -
if(num>level){ -
//如果剩余的文件数还是大于设定的level=1000的话,则继续往下递归 -
1);combine(num-level,loop+ -
} -
filenumBegin=loop*level; -
if(num<=level){ -
filenumEnd=filenumBegin+num; -
else{} -
filenumEnd=filenumBegin+level; -
} -
-
//定义经典固定长度数组,因为比集合等动态数组效率要高。 -
//并且此时也可以保证String[][]CombinedArray不会 -
//超出内存,因为每次处理的不会超过level=1000 -
newString[][] CombinedArray= String[ 2048][filenumEnd-filenumBegin]; -
-
for(inti=filenumBegin;i -
"00"+i;//"00"是保存的文件的前缀String filename= -
inttemLength=filename.length(); -
for(intj= 0;j -
"0"+filename;filename= -
} -
".txt";filename=filename+ -
newFile file= File(dirPath,filename); -
newFileReader fr= FileReader(file); -
newBufferedReader bfr= BufferedReader(fr); -
intnum_line 0;= -
null;String s= -
while((s=bfr.readLine())!=null){ -
if(i==0){ -
0]=s.replace(',',CombinedArray[num_line][ '.'); -
else{} -
"\t");String[] sArray=s.split( -
1].replace(',',CombinedArray[num_line][i-filenumBegin]=sArray[ '.'); -
} -
num_line++; -
} -
bfr.close(); -
fr.close(); -
} -
//System.out.println("Filesare all viewed"); -
-
//建立临时文件夹存放每批合并后的结果文件 -
".txt";String filename=loop+ -
newtempFile= File(dirPath, "temp"); -
if(!tempFile.exists()){ -
tempFile.mkdir(); -
} -
newFile new_file= File(tempFile,filename); -
newFileWriter fw = FileWriter(new_file); -
newBufferedWriter bfw= BufferedWriter(fw); -
for(inti= 0;i<</SPAN>2048;i++){ -
for(intj= 0;j -
bfw.write(CombinedArray[i][j]); -
"\t");bfw.write( -
} -
bfw.newLine(); -
} -
null;//让JAVA垃圾自动回收装置认为此CombinedArray变量可以回收CombinedArray= -
bfw.close(); -
fw.close(); -
System.out.println(new_file); -
"OK");System.out.println( -
} -
-
publicstatic void main(String[] args) { -
//TODO Auto-generated method stub -
longstartTime=System.currentTimeMillis(); -
newCombinedTextSpectres_5(); -
try{ -
newFile new_file= File(destDirPath, "CombinedSpectres.txt"); -
newFileWriter fw = FileWriter(new_file); -
newBufferedWriter bfw= BufferedWriter(fw); -
-
"IntegratedString ExperienceCondition= time ;is 1 ms, with the HR Spectrometer, with polarizorH, using the syringe Rh6G+Glycol and the other is Huile" -
bfw.write(ExperienceCondition); -
bfw.newLine(); -
-
"Wavelengthbfw.write( (nm)\t" ); -
for(inti= 0;i -
"00"+i;//"00"是保存的文件的前缀String filename= -
inttemLength=filename.length(); -
for(intj= 0;j -
"0"+filename;filename= -
} -
".txt";filename=filename+ -
bfw.write(filename); -
"\t");bfw.write( -
} -
bfw.newLine(); -
-
//再把中间临时文件都合并成最终的单个文件 -
File[] FileArray=tempFile.listFiles(); -
intColumn=FileArray.length; -
newFileReader[] fr= FileReader[Column]; -
newBufferedReader[] bfr= BufferedReader[Column]; -
-
for(inti= 0;i -
newfr[i]= FileReader(FileArray[i]); -
newbfr[i]= BufferedReader(fr[i]); -
} -
String s; -
while((s=bfr[0].readLine())!=null){ -
for(inti= 0;i -
if(i==0){ -
bfw.write(s); -
else{} -
bfw.write(bfr[i].readLine()); -
} -
} -
bfw.newLine(); -
} -
for(inti= 0;i -
bfr[i].close(); -
fr[i].close(); -
} -
bfw.close(); -
fw.close(); -
System.out.println(new_file); -
"OK");System.out.println( -
catch} (Exception e) { -
//TODO Auto-generated catch block -
e.printStackTrace(); -
} -
longendTime=System.currentTimeMillis(); -
"耗费时间:System.out.println( " +(endTime-startTime)+"ms" ); -
} -
}
package com.han;
import java.io.*;
public class CombinedTextSpectres_5 {
static int N=6;//N是保存的文件名称的长度
static int M=4520;//M是保存的文件数目
int level=1000;//每次分批处理的数目
int filenumBegin;//每批处理时的第一个文件名
int filenumEnd;//每批处理时的最后一个文件名
String dirPath="/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/17_10-21_10/apresmidi sans pola";//定义存放离散采样数据文件的文件夹
static File tempFile; //定义临时文件夹来存放每批合并后的结果文件
static String destDirPath="/home/han/Desktop";//定义存放最终结果文件的文件夹
public CombinedTextSpectres_5(){
try {
combine(M,0);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
void combine(int num, int loop) throws IOException{
if(num>level){
//如果剩余的文件数还是大于设定的level=1000的话,则继续往下递归
combine(num-level,loop+1);
}
filenumBegin=loop*level;
if(num<=level){
filenumEnd=filenumBegin+num;
}else{
filenumEnd=filenumBegin+level;
}
//定义经典固定长度数组,因为比集合等动态数组效率要高。
//并且此时也可以保证String[][] CombinedArray不会
//超出内存,因为每次处理的不会超过level=1000
String[][] CombinedArray=new String[2048][filenumEnd-filenumBegin];
for(int i=filenumBegin;i<2048;i++){
for(int j=0;j
运行结果:
OK
/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/17_10-21_10/apresmidi sans pola/temp/3.txt
OK
/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/17_10-21_10/apresmidi sans pola/temp/2.txt
OK
/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/17_10-21_10/apresmidi sans pola/temp/1.txt
OK
/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/17_10-21_10/apresmidi sans pola/temp/0.txt
OK
/home/han/Desktop/CombinedSpectres.txt
OK
耗费时间: 28230 ms
到此,实验室中频谱数据处理就告一段落了。总结就是:改变算法非常重要。遇到问题,找到根源后,总会有改良的算法来解决它的。
******************************************************************************************************************************************************************************
不过,随着继续经验的积累,我发现全部使用流操作是可以的,即:用约5000个输入流同时分别指向每一个要合并的文件,然后用一个输出流指向合并结果文件。
虽然也许会遇到同时打开的流数限制(发现在Linux下是这样的,Windows尚未发现),但是可以再通过分批处理的思想来解决的。
(
)在本程序中又采用了另一种方法:同时开通N个输入流分别指向N个要合并的数据文件, 写入最后的单个结果文件。效果证明运行时间差不多,但是占用内存更少。
PS: 但是发现了一个Linux下特有的问题(因为此问题在Windows下不存在): 当文件读到大约第4092个时,抛出了“文件找不到“的异常。 所以断定同时打开输入流的数目在Linux下此时被限制为4092。 所以此时必须分批来处理,每批处理数目自动设为能够同时打开的最大流数目 (实际发现是输入流和输出流的总数,而此数字可以通过抛出的异常信息获得)。
总结:这样此程序即可以在Linux中运行,又可以在Windows中运行,就是做到了真正的跨平台!
代码如下:
- package
com.han; -
- import
java.io.*; -
-
- public
class CombinedTextSpectres6 { -
-
privatefinal int N= 6;//N是保存的文件名称的长度 -
privatefinal int M= 4520;//M是保存的文件数目 -
"IntegratedString ExperienceCondition= time ;is 1 ms, with the HR Spectrometer, with polarizorH, using the syringe Rh6G+Glycol and the other is Huile" -
"/media/96D0265ED0264539/Users/HAN/Documents/ThèseString dirPath= ISMO/DonneesLabo/17_10-21_10/apresmidi ;//定义存放离散采样数据文件的文件夹sans pola" -
//String dirPath="/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/10_10-14_10/spectre sans pola"; -
staticString "/home/han/Desktop";//定义存放最终结果文件的文件夹destDirPath= -
File new_file; -
-
File[] FileArray; -
intColumn; -
FileReader[] fr; -
BufferedReader[] bfr; -
FileWriter fw; -
BufferedWriter bfw; -
-
publicCombinedTextSpectres6() throwsIOException{ -
longstartTime=System.currentTimeMillis(); -
try{ -
-
newFileArray= File(dirPath).listFiles(); -
//Column=FileArray.length; 4000 limit -
newfr= FileReader[Column]; //声明 -
newbfr= BufferedReader[Column]; -
-
for(inti= 0;i//初始化 -
newfr[i]= FileReader(FileArray[i]); -
newbfr[i]= BufferedReader(fr[i]); -
} -
-
newnew_file= File(destDirPath, "CombinedSpectres.txt"); -
newfw = FileWriter(new_file); -
newbfw= BufferedWriter(fw); -
-
bfw.write(ExperienceCondition); -
bfw.newLine(); -
-
"Wavelengthbfw.write( (nm)\t" ); -
for(inti= 0;i -
"00"+i;//"00"是保存的文件的前缀String filename= -
inttemLength=filename.length(); -
for(intj= 0;j -
"0"+filename;filename= -
} -
".txt";filename=filename+ -
bfw.write(filename); -
"\t");bfw.write( -
} -
bfw.newLine(); -
-
String s; -
while((s=bfr[0].readLine())!=null){ -
for(inti= 0;i -
if(i==0){ -
',',bfw.write(s.replace( '.')); -
"\t");bfw.write( -
else{} -
"\t")[1].replace(',',bfw.write(bfr[i].readLine().split( '.')); -
"\t");bfw.write( -
} -
} -
bfw.newLine(); -
} -
for(inti= 0;i -
bfr[i].close(); -
fr[i].close(); -
} -
bfw.close(); -
fw.close(); -
System.out.println(new_file); -
"OK");System.out.println( -
catch} (Exception e) { -
//TODO Auto-generated catch block -
String strFile=e.getMessage(); -
1,String fileName=strFile.substring(dirPath.length()+ dirPath.length()+ 7); -
intmaxNumFile=Integer.parseInt(fileName); -
6;//formaxNumFile=maxNumFile- "bfr[i].close();" successful -
-
for(inti= 0;i//closeall input streams opened for the aims of releasing the resources. -
bfr[i].close(); -
fr[i].close(); -
} -
"TheSystem.out.printf( maximum ,maxNumFile-1);opened file number limited by the current computer environment is : %d\n" -
"SoSystem.out.println( we );have to retreat the problem by considering the limitation of the computer resources." -
newLinuxLimit(maxNumFile- 1).run(); -
} -
longendTime=System.currentTimeMillis(); -
"耗费时间:System.out.println( " +(endTime-startTime)+"ms" ); -
} -
classLinuxLimit{ -
privatefinal int maxNumFile; -
newFile tempDir= File(destDirPath, "temp"); -
-
intLinuxLimit( maxNumFile){ -
this.maxNumFile=maxNumFile; -
} -
voidrun(){ -
intfileStart= 0; -
intfileEnd= 0; -
intnum= 0; -
".txt";String filename=num+ -
if(!tempDir.exists()){ -
tempDir.mkdir(); -
} -
Column=maxNumFile; -
try{ -
while(Column>=maxNumFile){ -
fileEnd=fileStart+maxNumFile; -
newfw= FileWriter( newFile(tempDir,filename)); -
newbfw= BufferedWriter(fw); -
System.out.println(fileStart); -
System.out.println(fileEnd); -
for(inti=fileStart;i //初始化 -
newfr[i-fileStart]= FileReader(FileArray[i]); -
newbfr[i-fileStart]= BufferedReader(fr[i-fileStart]); -
} -
String s; -
while((s=bfr[0].readLine())!=null){ -
for(inti= 0;i -
if(i==0&& 0){num== -
',',bfw.write(s.replace( '.')); -
"\t");bfw.write( -
else} if(i==0 && 0){num!= -
"\t")[1].replace(',',bfw.write(s.split( '.')); -
"\t");bfw.write( -
else} if(i!=0){ -
"\t")[1].replace(',',bfw.write(bfr[i].readLine().split( '.')); -
"\t");bfw.write( -
} -
} -
bfw.newLine(); -
} -
for(inti= 0;i -
bfr[i].close(); -
fr[i].close(); -
} -
bfw.close(); -
fw.close(); -
fileStart=fileEnd; -
Column=M-fileEnd; -
num++; -
".txt";filename=num+ -
} -
if(Column!=0){ -
newfw= FileWriter( newFile(tempDir,filename)); -
newbfw= BufferedWriter(fw); -
for(inti=fileStart;i //初始化M=fileStart+Column -
newfr[i-fileStart]= FileReader(FileArray[i]); -
newbfr[i-fileStart]= BufferedReader(fr[i-fileStart]); -
} -
String s; -
while((s=bfr[0].readLine())!=null){ -
for(inti= 0;i -
if(i==0){ -
"\t")[1].replace(',',bfw.write(s.split( '.')); -
"\t");bfw.write( -
else{} -
"\t")[1].replace(',',bfw.write(bfr[i].readLine().split( '.')); -
"\t");bfw.write( -
} -
} -
bfw.newLine(); -
} -
for(inti= 0;i -
bfr[i].close(); -
fr[i].close(); -
} -
bfw.close(); -
fw.close(); -
} -
-
-
FileArray=tempDir.listFiles(); -
Column=FileArray.length; -
newfr= FileReader[Column]; //声明 -
newbfr= BufferedReader[Column]; -
newnew_file= File(destDirPath, "CombinedSpectres.txt"); -
newfw = FileWriter(new_file); -
newbfw= BufferedWriter(fw); -
for(inti= 0;i -
System.out.println(FileArray[i]); -
} -
for(inti= 0;i//初始化 -
newfr[i]= FileReader(FileArray[i]); -
newbfr[i]= BufferedReader(fr[i]); -
} -
-
-
bfw.write(ExperienceCondition); -
bfw.newLine(); -
-
"Wavelengthbfw.write( (nm)\t" ); -
for(inti= 0;i -
"00"+i;//"00"是保存的文件的前缀String fname= -
inttemLength=fname.length(); -
for(intj= 0;j -
"0"+fname;fname= -
} -
".txt";fname=fname+ -
bfw.write(fname); -
"\t");bfw.write( -
} -
bfw.newLine(); -
-
String s; -
while((s=bfr[0].readLine())!=null){ -
for(inti= 0;i -
if(i==0){ -
bfw.write(s); -
"\t");bfw.write( -
else{} -
bfw.write(bfr[i].readLine()); -
"\t");bfw.write( -
} -
} -
bfw.newLine(); -
} -
for(inti= 0;i -
bfr[i].close(); -
fr[i].close(); -
} -
bfw.close(); -
fw.close(); -
for(Filee:FileArray){ -
e.delete(); -
} -
tempDir.delete(); -
"TheSystem.out.println( temp );folder has been deleted." -
catch(Exception} e){ -
e.printStackTrace(); -
} -
} -
} -
publicstatic void main(String[] args) { -
//TODO Auto-generated method stub -
try{ -
newCombinedTextSpectres6(); -
catch} (IOException e) { -
//TODO Auto-generated catch block -
e.printStackTrace(); -
} -
-
} -
}
package com.han;
import java.io.*;
public class CombinedTextSpectres6 {
private final int N=6;//N是保存的文件名称的长度
private final int M=4520;//M是保存的文件数目
String ExperienceCondition="Integrated time is 1 ms, with the HR Spectrometer, with polarizorH, using the syringe Rh6G+Glycol and the other is Huile";
String dirPath="/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/17_10-21_10/apresmidi sans pola";//定义存放离散采样数据文件的文件夹
// String dirPath="/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/10_10-14_10/spectre sans pola";
static String destDirPath="/home/han/Desktop";//定义存放最终结果文件的文件夹
File new_file;
File[] FileArray;
int Column;
FileReader[] fr;
BufferedReader[] bfr;
FileWriter fw;
BufferedWriter bfw;
public CombinedTextSpectres6() throws IOException{
long startTime=System.currentTimeMillis();
try{
FileArray=new File(dirPath).listFiles();
Column=FileArray.length;// 4000 limit
fr=new FileReader[Column];//声明
bfr=new BufferedReader[Column];
for(int i=0;i=maxNumFile){
fileEnd=fileStart+maxNumFile;
fw=new FileWriter(new File(tempDir,filename));
bfw=new BufferedWriter(fw);
System.out.println(fileStart);
System.out.println(fileEnd);
for(int i=fileStart;i
运行结果:The maximum opened file number limited by the current computer environment is : 4091
So we have to retreat the problem by considering the limitation of the computer resources.
0
4091
/home/han/Desktop/temp/0.txt
/home/han/Desktop/temp/1.txt
The temp folder has been deleted.
耗费时间: 17582 ms
程序中所要用到的数据文件以及合并后的结果文件都和前面是相同的。

加载中…