Java:从服务器写入日志文件

时间:2014-04-22 05:00:18

标签: java file-io

我正在尝试为我创建的小聊天室创建一个日志文件。 到目前为止,这是我记录日志的内容:

static void log(String s){
    try{
        BufferedWriter writer =
                new BufferedWriter(new FileWriter("log"+getTime()+".txt"));
        writer.write(s);
    }catch(IOException e){
        e.printStackTrace();
    }
}

每次我向客户端广播时,我都会以这种方式在每个连接的线程中调用它:

log(name+"String")

但是在它被调用之后并没有继续该程序。但是,当它确实有效时,文本文件中唯一的东西就是一行,第一行称为。如何修复这些错误?

3 个答案:

答案 0 :(得分:1)

使用try-with-resources并写入追加模式

static void log(String s) {
    try (PrintWriter out = new PrintWriter(new BufferedWriter(
            new FileWriter("log" + getTime() + ".txt", true)))) {
        out.println(s);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

答案 1 :(得分:1)

如其他答案中所述,您不会关闭文件,也不会写行分隔符。

我看到Java 7中有一个完美的答案,但你在评论中说你无法使用它。 (我想你使用的是Java 6)

因此,我编写了一个仅使用Java 6 API的实现(使用Java 6 javadocs作为参考):

public class LogFileHelper {
  private final BufferedWriter writer;

  public LogFileHelper(File outputFile) throws IOException {
    if(!outputFile.exists()){ //The JavaDoc says that it is not certain if the file will be created
      outputFile.createNewFile();
    }

    this.writer = new BufferedWriter(new FileWriter(outputFile, true));
  }

  public void writeLine(String line) throws IOException {
    if(line == null){
      throw new IllegalArgumentException("line may not be null");
    }

    this.writer.write(line);
    this.writer.newLine();
    this.writer.flush(); //Make sure the line we just wrote is written and kept if the application crashes
  }

  public void tryWriteLine(String line) {
    try {
      writeLine(line);
    } catch(IOException ioe){
      //Your exception handling here
    }
  }

  public void close() throws IOException {
    this.writer.close();
  }

  public void tryClose() {
    try {
      this.writer.close();
    } catch(IOException ioe){
      //Your exception handling here
    }
  }
}

我添加了tryXXX方法来简化异常处理,因为我想你会在任何地方使用相同的方法。我保留了基本方法,以便在需要时允许自定义异常处理。

使用上面的类,您可以将实例存储在某个地方,在需要的地方写入并在退出时关闭它。你最好的选择是像这样的关机处理程序:

Runtime.getRuntime().addShutdownHook(new Thread("Chatlog Shutdown Thread"){
  @Override
  public void run(){
    myLogFileHelper.tryClose();
  }
});

在创建LogFileHelper实例后,您将在何处执行该语句。

每次写东西时,上面的代码都会刷新 - 如果你想要超高效,你可以不那么频繁地冲洗。不立即刷新的有效用例是在一次写入整批行时,尽管你必须在不刷新和立即在磁盘上存档文件之间取得平衡。

答案 2 :(得分:0)

你有几个问题:

  • 每次登录一个语句时,都会打开一个新的文件描述符;
  • ...你没有关闭;
  • .getTime()的输出上给出,你甚至可以写几个不同的文件。

使用您在所有使用日志记录工具的类中初始化并共享一次的专用类;例如单身人士。

在构造函数中,您将打开文件:

private final BufferedWriter writer;

// ...

public MyLogFile()
    throws IOException
{
    final Path path = Paths.get("path to logfile");
    writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8,
        StandardOpenOption.CREATE, StandardOpenOption.APPEND);
}

使用方法写一行:

public void writeOneLine(@Nonnull final String line)
    throws IOException
{
    Objects.requireNonNull(line, "won't write null, sorry");
    writer.write(line);
    writer.newLine();
    writer.flush();
}

至于退出时关闭文件,要么在程序结束时(甚至Closeable)使类实现.close()AutoCloseable,要么添加JVM关闭钩子。< / p>