简体   繁体   English

如何用Java读写文件

[英]How to read/write a file in Java

I would like to replace some items in a file, based on some regular expressions. 我想根据一些正则表达式替换文件中的某些项目。 In order to do that: 为了做到这一点:

  • I read the file line per line 我逐行读取文件行
  • For every line, I check for the regular expression and I perform the replacement 对于每一行,我检查正则表达式并执行替换
  • Every line gets written in an array of strings 每行都以字符串数组形式编写

When all this is finished, I try to delete the file (in order to recreate it again with the replaced lines). 完成所有这些操作后,我尝试删除该文件(以便使用替换的行再次创建它)。

For some reason this does not work: it seems that Java keeps a handle on that file, even after the BufferedReader has been closed. 出于某种原因,这是行不通的:即使关闭了BufferedReader,Java仍在该文件上保留了句柄。

Does anybody have a solution for this (newbie) question? 有人对此新手问题有解决方案吗?

Code excerpt: 代码摘录:

      Pattern oDatePattern   = Pattern.compile("at \\d{2}:\\d{2}:\\d{2} "); // meaning: "at xx:xx:xx"
      Pattern oTimePattern   = Pattern.compile("Kernel time [0-9]*\\.?[0-9]+ User time: [0-9]*\\.?[0-9]+"); // "[0-9]*\.?[0-9]+" stands for any floating point number
      Pattern oMemoryPattern = Pattern.compile("\\([0-9,A-F]*\\)"); // "[0-9,A-F]*" stands for any hexadecimal number 
      Matcher oDateMatcher;
      Matcher oTimeMatcher;
      Matcher oMemoryMatcher;

      List<String> sLog_Content = new ArrayList<String>();

      BufferedReader br = new BufferedReader(new FileReader(sLp_LogFile));
      try {
        String sLine = br.readLine();

        while (sLine != null) {
          System.out.println("ORIG : " + sLine);
          oDateMatcher = oDatePattern.matcher(sLine);
          sLine        = oDateMatcher.replaceAll("at <timestamp> ");
          oTimeMatcher = oTimePattern.matcher(sLine);
          sLine        = oTimeMatcher.replaceAll("Kernel time <Kernel_Time_usage> User time: <User_Time_usage>");
          oMemoryMatcher = oMemoryPattern.matcher(sLine);
          sLine          = oMemoryMatcher.replaceAll("<Memory_Address>");
          System.out.println("REPL : " + sLine);
          sLog_Content.add(sLine);
          sLine = br.readLine();
        }
      } finally {
        br.close();
      }

      System.out.println("All lines are read and regex replaced, try to delete the file");

      File tst_File = new File(sLp_LogFile);
      if (tst_File.exists()) {
        System.out.println(sLp_LogFile + " exists");
      } else {
        System.out.println(sLp_LogFile + " does not exist");
      }

      if (tst_File.delete()) {
        System.out.println(sLp_LogFile + " is deleted");
      } else {
        System.out.println(sLp_LogFile + " is not deleted");
      }

Output logs: 输出日志:

ORIG : Reading buffer 1 (0000000002ED0070) at 15:40:44 (index 125999, size 4410000 lines 126000, total lines read 126000)
REPL : Reading buffer 1 <Memory_Address> at <timestamp> (index 125999, size 4410000 lines 126000, total lines read 126000)
...
ORIG : Sending buffer 1 (0000000002ED0070) at 15:40:44 (index 125999, size 4410000, lines 126000, total lines sent 126000)
REPL : Sending buffer 1 <Memory_Address> at <timestamp> (index 125999, size 4410000, lines 126000, total lines sent 126000)
...
ORIG : Kernel time 0.2808 User time: 0.312
REPL : Kernel time <Kernel_Time_usage> User time: <User_Time_usage>
...
All lines are read and regex replaced, try to delete the file
D:\Logfile_lp.log exists
D:\Logfile_lp.log is not deleted

One possible explanation is that your application has the file open somewhere else. 一种可能的解释是您的应用程序在其他位置打开了文件。

Or it could be another application that has the file open. 也可能是另一个已打开文件的应用程序。

Or maybe the application / user has permission to read the file but not to delete it. 或者,也许应用程序/用户有权读取文件,但不能删除它。


I concur with the suggestion of using Files.delete .. 我同意使用Files.delete ..的建议

I see no issues in your code. 我认为您的代码中没有问题。

Seemingly closing the BufferReader ensure the file is closed. 似乎关闭BufferReader确保文件已关闭。 (cf this response ). (请参阅此响应 )。

Maybe you can give a try to Files.delete cf this response . 也许您可以尝试使用Files.delete 这个响应
It will give more information about the deletion fail by throwing different exceptions. 通过抛出不同的异常,它将提供有关删除失败的更多信息。

i'm a beginner i do not know lotsa things as you. 我是一个初学者,我不了解你这么多东西。 But if i know right you should save your changes first a temp file. 但是,如果我知道的话,您应该先保存一个临时文件。 Afterwards you will read again the temp file and later you'll write to your real file. 之后,您将再次读取临时文件,然后将其写入实际文件。 I hope my comment will help you. 希望我的评论对您有所帮助。

Good afternoon, I would like to thank you all for having searched for a solution of this problem. 下午好,我想感谢大家寻找这个问题的解决方案。 Unfortunately the problem is not Java based: the file I'm trying to write to is created by a redirection cmd /c <program>.exe >> <output>.log , and it seems that Windows has not fully flushed the output buffer towards the output file, creating the problem. 不幸的是问题不是基于Java的:我要写入的文件是由重定向cmd /c <program>.exe >> <output>.log ,并且Windows似乎没有完全刷新输出缓冲区。朝向输出文件,从而产生问题。

I am currently using following (very dirty) work-around for this issue: 我目前正在使用以下(非常脏)的解决方法来解决此问题:

boolean bFile_can_be_opened = false;
while (!bFile_can_be_opened) {
  try {
    fwLog2 = new FileWriter(sLp_LogFile, true);
    bFile_can_be_opened = true;
  }
  catch (Exception e)
  {}
}

Further information on this issue can be found under the following new StackOverflow question: How to release a file, locked by the application, in Java 在以下新的StackOverflow问题下可以找到有关此问题的更多信息: 如何使用Java释放由应用程序锁定的文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM