真正解决 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 datedFilename
		this.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;
		}
	}

你可能感兴趣的:(log4j)