3

我有一个目录,其中包含按顺序编号的日志文件和一些用于分析的 Excel 电子表格。日志文件总是从零开始按顺序编号,但它们的数量可能会有所不同。我正在尝试连接日志文件,按照它们被创建为单个文本文件的顺序,这将是所有日志文件的连接。

例如,对于日志文件 foo0.log、foo1.log、foo2.log 将通过在 foo0 之后附加 foo1 和在 foo1 之后附加 foo2 来输出到连接的 foo.log。

我需要计算给定目录中扩展名为 *.log 的所有文件,使用该计数来驱动一个 for 循环,该循环还生成用于连接的文件名。我很难找到一种使用过滤器来计算文件的方法......关于文件操作的 Java Turtorials 似乎都不适合这种情况,但我确信我错过了一些东西。这种方法有意义吗?还是有更简单的方法?

int numDocs = [number of *.log docs in directory];
 //
for (int i = 0; i <= numberOfFiles; i++) {
     fileNumber = Integer.toString(i);
     try
     {
          FileInputStream inputStream = new FileInputStream("\\\\Path\\to\\file\\foo" + fileNumber + ".log");
          BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
          try
          {
               BufferedWriter metadataOutputData = new BufferedWriter(new FileWriter("\\\\Path\\to\\file\\fooconcat.log").append());
               metadataOutputData.close();
          }
           //
          catch (IOException e)  // catch IO exception writing final output
          {
               System.err.println("Exception: ");
               System.out.println("Exception: "+ e.getMessage().getClass().getName());
               e.printStackTrace();
          }
     catch (Exception e)    // catch IO exception reading input file
     {
          System.err.println("Exception: ");
          System.out.println("Exception: "+ e.getMessage().getClass().getName());
          e.printStackTrace();
     }
}
4

5 回答 5

2

通过将日志文件夹作为File对象,您可以像这样编写代码

for (File logFile : logFolder.listFiles()){
    if (logFile.getAbsolutePath().endsWith(".log")){
        numDocs++;
    }
}

查找日志文件的数量。

于 2013-10-29T18:11:31.647 回答
2

怎么样

public static void main(String[] args){

    final int BUFFERSIZE = 1024 << 8;
    File baseDir = new File("C:\\path\\logs\\");

    // Get the simple names of the files ("foo.log" not "/path/logs/foo.log")
    String[] fileNames = baseDir.list(new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
            return name.endsWith(".log");
        }
    });

    // Sort the names
    Arrays.sort(fileNames);

    // Create the output file
    File output = new File(baseDir.getAbsolutePath() + File.separatorChar + "MERGED.log");
    try{
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(output), BUFFERSIZE);
        byte[] bytes = new byte[BUFFERSIZE];
        int bytesRead;
        final byte[] newLine = "\n".getBytes(); // use to separate contents

        for(String s : fileNames){
            // get the full path to read from
            String fullName = baseDir.getAbsolutePath() + File.separatorChar + s;
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(fullName),BUFFERSIZE);
            while((bytesRead = in.read(bytes,0,bytes.length)) != -1){
                out.write(bytes, 0, bytesRead);
            }
            // close input file and ignore any issue with closing it
            try{in.close();}catch(IOException e){}
            out.write(newLine); // seperation
        }

        out.close();
    }catch(Exception e){
        throw new RuntimeException(e);
    }
}

此代码确实假定“顺序命名”将被零填充,以便它们将按字典顺序 (?? sp) 正确排序。即文件将是

  • 0001.log(或 blah0001.log,或 0001blah.log 等)
  • 0002.log
  • ……
  • 0010.log

并不是

  • 1.日志
  • 2.日志
  • ...
  • 10.日志

后一种模式无法使用我给出的代码正确排序。

于 2013-10-29T18:15:41.517 回答
2

这是给你的一些代码。

File dir = new File("C:/My Documents/logs");
File outputFile = new File("C:/My Documents/concatenated.log");

找到“.log”文件:

File[] files = dir.listFiles(new FilenameFilter() {

    @Override
    public boolean accept(File file, String name) {
        return name.endsWith(".log") && file.isFile();
    }
});

将它们按适当的顺序排序:

Arrays.sort(files, new Comparator<File>() {

    @Override
    public int compare(File file1, File file2) {
        return numberOf(file1).compareTo(numberOf(file2));
    }

    private Integer numberOf(File file) {
        return Integer.parseInt(file.getName().replaceAll("[^0-9]", ""));
    }
});

连接它们:

byte[] buffer = new byte[8192];

OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFile));
try {
    for (File file : files) {
        InputStream in = new FileInputStream(file);
        try {
            int charCount;
            while ((charCount = in.read(buffer)) >= 0) {
                out.write(buffer, 0, charCount);
            }
        } finally {
            in.close();
        }
    }
} finally {
    out.flush();
    out.close();
}
于 2013-10-29T18:20:57.020 回答
0

我会;

  • 打开输出文件一次。只需使用 PrintWriter。
  • 在一个循环中...
    • 为每个可能的文件创建一个文件
    • 如果它不存在,则打破循环。
    • 使用 BufferedReader
      • 使用 readLine() 读取文件的行
      • 将每一行写入输出文件。

您应该能够使用大约 12 行代码来完成此操作。我会将 IOExceptions 传递给调用者。

于 2013-10-29T18:11:10.803 回答
0

您可以使用SequenceInputStream连接FileInputStreams. 要查看所有日志文件,可以使用File.listFiles(FileFilter) 。它将为您提供带有文件的未排序数组。要按正确顺序对文件进行排序,请使用Arrays.sort. 代码示例:

static File[] logs(String dir) {
    File root = new File(dir);
    return root.listFiles(new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            return pathname.isFile() && pathname.getName().endsWith(".log");
        }
    });
}

static String cat(final File[] files) throws IOException {
    Enumeration<InputStream> e = new Enumeration<InputStream>() {
        int index;

        @Override
        public boolean hasMoreElements() {
            return index < files.length;
        }

        @Override
        public InputStream nextElement() {
            index++;
            try {
                return new FileInputStream(files[index - 1]);
            } catch (FileNotFoundException ex) {
                throw new RuntimeException("File not available!", ex);
            }
        }
    };
    SequenceInputStream input = new SequenceInputStream(e);
    StringBuilder sb = new StringBuilder();
    int c;
    while ((c = input.read()) != -1) {
        sb.append((char) c);
    }
    return sb.toString();
}

public static void main(String[] args) throws IOException {
    String dir = "<path-to-dir-with-logs>";
    File[] logs = logs(dir);
    for (File f : logs) {
        System.out.println(f.getAbsolutePath());
    }
    System.out.println();
    System.out.println(cat(logs));
}
于 2013-10-29T19:02:46.593 回答