0

好吧,所以我应该做一个任务:

假设您有这样排序的聊天日志:

System-0/Server-#channel.log
System-0/Server-#channel1.log
System-0/Server-#channel2.log
System-1/Server-#channel.log
System-1/Server-#channel2.log
System-2/Server-#channel3.log

System-0 是我的第一个系统,系统 1 和 2 是其他计算机。我将如何继续将 System-0/#channel 与 System-1/#channel 日志文件合并?我已经想出了如何获取它们,但是,BufferedWriter 随机停止写入(它忘记了文本)并且它只适用于 1 个文件(所以说在不同的目录中有 2 个重复的日志文件它只会处理第一个重复的日志文件在不同的目录中)。

对不起我的英语,我不是母语人士,但我希望你明白我的意思。到目前为止,这是我所拥有的:我也对任何改进持开放态度。

import java.io.*;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

public class MergeV2 {

private static final Logger log = Logger.getLogger(MergeV2.class.getName());
private static final File ROOT_FOLDER = new File(System.getProperty("user.home") + (System.getProperty("os.name").contains("Windows") ? "/AppData/Roaming/X-Chat 2/xchatlogs" : "/.xchat2/xchatlogs"));
private static final HashMap<String, File[]> files = new HashMap<String, File[]>();
private static final HashMap<File, File[]> filesToWrite = new HashMap<File, File[]>();

public static void main(String... args) {
    if (ROOT_FOLDER.exists()) {
        for (final File f : ROOT_FOLDER.listFiles()) {
            if (f.isDirectory() && f.getName().contains("System")) { //mandatory check
                for (final File sub : f.listFiles()) {
                    String channelName = sub.getName().split("#")[1].replaceAll(".log", "");
                    if (files.containsKey(channelName)) {
                        ArrayList<File> tempFiles = new ArrayList<File>();
                        for (File t : files.get(channelName)) {
                            tempFiles.add(t);
                        }
                        tempFiles.add(sub);
                        File[] array = new File[tempFiles.size()];
                        array = tempFiles.toArray(array);
                        files.put(channelName, array);
                    } else {
                        files.put(channelName, new File[]{sub});
                    }
                }
            }
        }
    } else {
        log.info("No log folder detected.");
    }
    String channel;
    File f, ftemp;
    for (Map.Entry<String, File[]> es : files.entrySet()) {
        channel = "#" + es.getKey();
        f = new File(ROOT_FOLDER.getAbsolutePath() + "/merged-" + channel + ".log");
        ftemp = new File(f.getAbsolutePath() + ".temp");
        if (f.exists()) {
            f.delete();
            ftemp.delete();
        }
        try {
            f.createNewFile();
            ftemp.createNewFile();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
        filesToWrite.put(f, es.getValue());
    }
    try {
        FileWriter fw = null;
        BufferedWriter bw = null;
        BufferedReader in = null;
        for (Map.Entry<File, File[]> es : filesToWrite.entrySet()) {
            File temp = new File(es.getKey() + ".temp");
            bw = new BufferedWriter(new FileWriter(temp));
            for (File t : es.getValue()) {
                bw.write(readFile(t.getAbsolutePath()));
            }
            in = new BufferedReader(new FileReader(new File(es.getKey() + ".temp")));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = in.readLine()) != null) {
                if (!line.contains("**** LOGGEN") && !line.contains("**** LOGGING")) {
                    sb.append(line);
                }
            }
            bw = new BufferedWriter(new FileWriter(es.getKey()));
            in.close();
            new File(es.getKey() + ".temp").delete();
            bw.write(sb.toString());
        }
    } catch (IOException e) {

    }
}

private static String readFile(String path) throws IOException {
    System.out.println("reading " + path);
    FileInputStream stream = new FileInputStream(new File(path));
    try {
        FileChannel chan = stream.getChannel();
        MappedByteBuffer mbb = chan.map(FileChannel.MapMode.READ_ONLY, 0, chan.size());
        return Charset.defaultCharset().decode(mbb).toString();
    } finally {
        stream.close();
    }
}
}

非常感谢!

4

1 回答 1

1

您必须关闭缓冲写入器:

后 ..

 bw = new BufferedWriter(new FileWriter(es.getKey()));
 in.close();
 new File(es.getKey() + ".temp").delete();
 bw.write(sb.toString());

添加

 bw.close();

如果缓冲写入器未关闭,则不会保存更改,这解释了您提到的“(它忘记了文本)”。

于 2012-07-31T18:20:23.577 回答