2015-04-03 69 views
0

我想要做的是有兩個參數來解析我的users.txt文件 - 找到條目(已經做了測試beforehands知道它在那裏),並作出新文件(users_new.txt)跳過該條目。在java中交換文件(刪除重命名)失敗

畢竟完成後,我想刪除舊文件,並保留新文件作爲舊文件重命名。

我已經在一個新的java文件中單獨測試了代碼,它完美地工作。 在這種情況下,刪除/重命名部分將不起作用。即使我運行它並獲取「真正」標誌以及tex文件被更改,交換將不會成功。

下面是解析的代碼。

boolean deleted = false; 

    try { 

     // open the users.txt file 
     FileInputStream fis = new FileInputStream("users.txt"); 
     BufferedReader br = new BufferedReader(new InputStreamReader(fis)); 
     FileWriter writer = new FileWriter("users_new.txt"); 
     PrintWriter out = new PrintWriter(writer); 

     String line = null; 

     while ((line = br.readLine()) != null) { 
      String[] values = line.split(" "); 
      // only interested for duplicate usernames 

      if (username.equals(values[0])) { 
       // if we find the user, we dont keep it in 
       // the new temporary file 
       // but have to mark the pointer as true, so we know it was found 
       deleted = true; 
       continue; 
      } 
      // keeping every other entry 
      out.println(values[0] + " " + values[1]); 

     } 
     br.close(); 
     out.close(); 

    } catch (IOException e) { 
     return false; 
    } 

    return deleted; 

雖然我執行刪除如下

private static void swapFiles(){ 
    // needs some more careful approach. But for now.. 
    File inputFile = new File("users.txt"); 
    File outFile = new File("users_new.txt"); 

     if (inputFile.delete()) { 
      outFile.renameTo(inputFile); 
     } 
} 

,並調用它

public static boolean delete(String key) { 

    if (removeEntry(key)) { 
     swapFiles();  
     return true; 
    } else { 
     return false; 
    } 

} 

編輯:嘗試其他方式圓,它的工作原理是,更離奇。

+0

@BoristheSpider感謝您的幫助。 – Rentonie 2015-04-03 10:11:04

+1

只需要說一句,你只能關閉流的最後一個包裝,即'br'和'out'。 – Tzoiker 2015-04-03 10:17:28

+0

@Tzoiker是的,我也試過這種方式,以防萬一。謝謝 – Rentonie 2015-04-03 10:20:09

回答

0

有一些問題在這裏,我可以看到:

  1. 沒有正確關閉資源,這可能會導致使用舊File API,它具有幾乎沒有任何反饋緩衝區不被刷新
  2. 失敗。

從我的理解,你想要做的兩個獨立的任務:

  1. 讀取文件orig,並寫入內容到文件new - 跳過與username
  2. 開始替換文件orig行用文件new

第一種方法應該看起來像這樣,注意try...finally constru CTS - 這提供了正確的封閉的保證

public static void filter(final Path orig, final Path into, final Predicate<String> lineFilter) throws IOException { 
    try (final Stream<String> lines = Files.lines(orig); 
     final PrintWriter pw = new PrintWriter(Files.newBufferedWriter(into))) { 
     lines.filter(lineFilter).forEach(pw::println); 
    } 
} 

現在的替換文件:

public static void moveAndDelete(final Path orig, final Path into) throws IOException { 
    Files.move(into, orig, StandardCopyOption.REPLACE_EXISTING); 
} 

所以調用代碼:

public static void main(String[] args) throws Exception { 
    final Path users = Paths.get("users.txt"); 
    final Path newUsers = Paths.get("users_new.txt"); 
    final String username = "MyUser"; 
    filter(users, newUsers, s -> !s.startsWith(username)); 
    overwrite(newUsers, users); 
} 

的NIO方法拋出適當他們無法完成的例外,而不是簡單地返回boolean

+0

抱歉,您正在編寫自己的代碼。如果我不能那樣想,我不想徹底改變我的想法。 – Rentonie 2015-04-03 10:39:57

+0

@Rentonie不能解決你有一些問題,這是你應該寫的代碼。 – 2015-04-03 10:45:31

0

顯然該文件在刪除之前的身份驗證過程中正在使用中。