真正解决 log4j:ERROR Failed to rename错误解决办法
今天终于遇到了log4j配置成DailyRollingFileAppender后,没有正确生成文件,或者没有重命名log文件
在网上寻找了一遍,绝大部分都是复制了了就不管了,大致原文该链接http://www.blogjava.net/DreamAngel/archive/2011/11/10/363400.html中的代码有明显问题,比如日志文件过大怎么办,然而复制了原log文件后,那原来的log文件需要清空却没有做。
现修正如下,但修正的结果却是错误的(你可以不看修正的结果了):
真正占用文件的根源可以从这里说起,windows平台下你打开一个记事本,你是可以删除的该记事本的,但是如果用独占的方式打开一个记事本,因为加了锁,而另一个进程(对头这里是进程,而非线程)却要去重命名它,怎么可能做到呢,所以最好是两个独立的进程就做独立进程的事情了,具体解决思路当然是进程既然是独立的,log4j.properties中一定要修改日志记录的路径为不同的进程所独有。
/** * Rollover the current file to a new file. */void rollOver() throws IOException {/* Compute filename, but only if datePattern is specified */if (datePattern == null) {errorHandler.error("Missing DatePattern option in rollOver().");return;}String datedFilename = fileName + sdf.format(now);// It is too early to roll over because we are still within the// bounds of the current interval. Rollover will occur once the// next interval is reached.if (scheduledFilename.equals(datedFilename)) {return;}// close current file, and rename it to datedFilenamethis.closeFile();File target = new File(scheduledFilename);if (target.exists()) {target.delete();}File file = new File(fileName);boolean result = copy(file, target);if (result) {FileWriter fw = new FileWriter(file);fw.write("");fw.flush();fw.close();LogLog.debug(fileName + " -> " + scheduledFilename);} else {LogLog.error("Failed to rename [" + fileName + "] to ["+ scheduledFilename + "].");}try {// This will also close the file. This is OK since multiple// close operations are safe.this.setFile(fileName, true, this.bufferedIO, this.bufferSize);} catch (IOException e) {errorHandler.error("setFile(" + fileName + ", true) call failed.");}scheduledFilename = datedFilename;}// 最大的流为60MB,当文件的容量大于60MB的时候便分开流final int MAX_BYTE = 60000000;/** * Copies src file to dst file. If the dst file does not exist, it is * created.8KB cache * * @param src * @param dst * @throws IOException */boolean copy(File src, File dst) throws IOException {try {long streamTotal = 0; // 接受流的容量int streamNum = 0; // 流需要分开的数量int leave = 0; // 文件剩下的字符数byte[] inOutb;// byte数组接受文件的数据FileInputStream in = new FileInputStream(src);FileOutputStream out = new FileOutputStream(dst);// 通过available方法取得流的最大字符数streamTotal = in.available();// 取得流文件需要分开的数量streamNum = (int)Math.floor(streamTotal/MAX_BYTE);// 分开文件之后,剩余的数量leave = (int)(streamTotal % MAX_BYTE);// 文件的容量大于60MB时进入循环if(streamNum>0){for (int i = 0; i < streamNum; i++) {inOutb = new byte[MAX_BYTE];// 读入流,保存在byte数组in.read(inOutb, 0, MAX_BYTE);out.write(inOutb);out.flush();}}// 剩余的流数据inOutb = new byte[leave];in.read(inOutb, 0, leave);out.write(inOutb);out.flush();in.close();out.close();return true;} catch (FileNotFoundException e) {LogLog.error("源文件不存在,或者目标文件无法被识别.");return false;} catch (IOException e) {LogLog.error("文件读写错误.");return false;}}