我的程序遍历一个目录并使用我的Recoder类中的以下函数在编码上使用FileUtils.readFileToString
读取文件,并在另一个编码上使用FileUtils.write
覆盖它。
然而,当它尝试使用xml文件执行此操作时,我在标题处获得异常,否则,它工作正常(我已经在.dava,.js,.css,.html ,. JSP ...)。
public class Recoder {
private static Charset fromCharset;
private static Charset toCharset;
public static void recodeToUTF(File f, boolean verbose){
try{
if(verbose){
System.out.println("Convertendo "+f.getAbsolutePath()+" para UTF-8");
}
toCharset = Charset.forName("UTF-8");
String content = FileUtils.readFileToString(f);
FileUtils.write(f,content, toCharset);
}catch(Exception e){
}
}
public static void recodeFile(File f, String de, String para, boolean verbose){
try{
if(verbose){
System.out.println("Convertendo "+f.getAbsolutePath()+" de "+ de + " para "+ para);
}
// CharsetDetector cd= new CharsetDetector();
// FileInputStream fis = new FileInputStream(f);
// cd.setText(fis);
// fis.close();
// CharsetMatch cm = cd.detect();
// if(cm!=null){
// fromCharset = Charset.forName(cm.getName());
// }else{ fromCharset = Charset.forName(de);}
fromCharset = Charset.forName(de);
toCharset = Charset.forName(para);
String content = FileUtils.readFileToString(f,fromCharset);
FileUtils.write(f,content,toCharset);
content=null;
}catch(Exception e){
}
}
public static String removeAcentos(String str) {
str = Normalizer.normalize(str, Normalizer.Form.NFD);
str = str.replaceAll("[^\\p{ASCII}]", "");
return str;
}
}
CharsetDetector的东西来自ICU4J,由于某种原因,它在调用cd.detect()时会挂起,所以,现在,我只是把它留在了评论中。
这是它的主要内容:
public static void main( String[] args ){
DecoderArguments decArgs = new DecoderArguments();
JCommander jc = new JCommander(decArgs, args);
try {
if(args.length>0){
for(String s : decArgs.files){
File file;
if (decArgs.recursive){
System.out.println("Executando Recursivamente em: "+ s);
file = new File(s);
if(file.isDirectory()){
Collection<File> files = FileUtils.listFiles(file,FileFileFilter.FILE, DirectoryFileFilter.DIRECTORY);
for (File f : files){
boolean exec=true;
for(String excl : decArgs.excludes){
if (f.getAbsolutePath().contains(excl)) exec=false;
}
if (file.exists() && exec){
if("".equals(decArgs.fromEncoding)){
Recoder.recodeToUTF(f, decArgs.verbose);
}else {
Recoder.recodeFile(f, decArgs.fromEncoding, decArgs.toEncoding, decArgs.verbose);
}
System.gc();
}
}
}else{
System.out.println("Por favor, informe um diretorio para ler recursivamente.\n"
+ "Uso: java -jar decoder.jar <-r> Caminho|Arquivo");
}
}else{
System.out.println("Convertendo arquivo: "+ s);
file = new File(s);
boolean exec=true;
for(String excl : decArgs.excludes){
if (file.getAbsolutePath().contains(excl)) exec=false;
}
if (file.exists() && exec){
if("".equals(decArgs.fromEncoding)){
Recoder.recodeToUTF(file, decArgs.verbose);
}else {
Recoder.recodeFile(file, decArgs.fromEncoding, decArgs.toEncoding, decArgs.verbose);
}
}
}
}
}else if (args.length==0){
System.out.println("Sintaxe incorreta.\n");
jc.usage();
}
} catch (Exception e) {
e.printStackTrace();
}
}
注意事项:
decArgs.recursive=true
),抛出异常的同一文件会在关于为什么会发生这种情况的任何想法?
提前致谢!
修改
使用Recoder.recodeToUTF
方法而不是Recoder.recodeFile
会导致不抛出OutOfMemory。也许尝试使用错误的编码打开会导致内存泄漏。
分析生成的.hprof,(混乱的)300Mb xml文件正在使用大约500Mb的堆。但是,堆的最大大小设置为2Gb
答案 0 :(得分:1)
您的记忆正在泄露,以便检查您可以解决的问题
使用这些参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump
配置JVM。当OutOfMemoryError
被抛出时,将在/path/to/dump
中创建转储。然后,您可以使用Eclipse Memory Analyzer对其进行分析,并查找泄露您记忆的对象。
好教程here