View Javadoc

1   /**
2    * LOGBack: the reliable, fast and flexible logging library for Java.
3    * 
4    * Copyright (C) 1999-2006, QOS.ch
5    * 
6    * This library is free software, you can redistribute it and/or modify it under
7    * the terms of the GNU Lesser General Public License as published by the Free
8    * Software Foundation.
9    */
10  package ch.qos.logback.core.rolling.helper;
11  
12  
13  import java.io.File;
14  import java.io.FileInputStream;
15  import java.io.FileOutputStream;
16  import java.io.IOException;
17  
18  import ch.qos.logback.core.rolling.RolloverFailure;
19  import ch.qos.logback.core.spi.ContextAwareBase;
20  
21  
22  /**
23   * Utility class to help solving problems encountered while renaming files.
24   * @author Ceki Gulcu  
25   */
26  public class RenameUtil extends ContextAwareBase {
27  
28    
29    /**
30     * A robust file renaming method which in case of failure falls back to
31     * renaming by copying. In case, the file to be renamed is open by another
32     * process, renaming by copying will succeed whereas regular renaming will
33     * fail. However, renaming by copying is much slower.
34     * 
35     * @param from
36     * @param to
37     * @throws RolloverFailure
38     */
39    public void rename(String from, String to) throws RolloverFailure {
40      if(from.equals(to)) {
41        addWarn("From and to file are the same ["+from+"]. Skipping.");
42        return;
43      }
44      File fromFile = new File(from);
45  
46      if (fromFile.exists()) {
47        File toFile = new File(to);
48        addInfo("Renaming file ["+fromFile+"] to ["+toFile+"]");
49  
50        boolean result = fromFile.renameTo(toFile);
51  
52        if (!result) {
53          addWarn("Failed to rename file ["+fromFile+"] to ["+toFile+"].");
54          addWarn("Attempting to rename by copying.");
55          renameByCopying(from, to);
56        }
57      } else {
58        throw new RolloverFailure("File [" + from + "] does not exist.");
59      }
60    }
61  
62    static final int BUF_SIZE = 32*1024;
63    
64    public void renameByCopying(String from, String to)
65        throws RolloverFailure {
66      try {
67        FileInputStream fis = new FileInputStream(from);
68        FileOutputStream fos = new FileOutputStream(to);
69        byte[] inbuf = new byte[BUF_SIZE];
70        int n;
71  
72        while ((n = fis.read(inbuf)) != -1) {
73          fos.write(inbuf, 0, n);
74        }
75  
76        fis.close();
77        fos.close();
78  
79        File fromFile = new File(from);
80  
81        if (!fromFile.delete()) {
82          addWarn("Could not delete "+ from);
83        }
84      } catch (IOException ioe) {
85        addError("Failed to rename file by copying", ioe);
86        throw new RolloverFailure("Failed to rename file by copying");
87      }
88    }
89    
90    @Override
91    public String toString() {
92      return "c.q.l.co.rolling.helper.RenameUtil";
93    }
94  }