import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.Writer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.CountingQuietWriter;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.spi.LoggingEvent;
import com.xxxx.core.util.DateUtil;
import com.xxxx.core.util.FileUtils;
/**
* MyDailyRollingFileAppender extends {@link FileAppender} so that the underlying
* file is rolled over at a user chosen frequency.
*
* <p>
* The rolling schedule is specified by the <b>DatePattern</b> option. This
* pattern should follow the {@link SimpleDateFormat} conventions. In
* particular, you <em>must</em> escape literal text within a pair of single
* quotes. A formatted version of the date pattern is used as the suffix for the
* rolled file name.
*
* <p>
* For example, if the <b>File</b> option is set to <code>/foo/bar.log</code>
* and the <b>DatePattern</b> set to <code>'.'yyyy-MM-dd</code>, on 2001-02-16
* at midnight, the logging file <code>/foo/bar.log</code> will be copied to
* <code>/foo/bar.log.2001-02-16</code> and logging for 2001-02-17 will continue
* in <code>/foo/bar.log</code> until it rolls over the next day.
*
* <p>
* Is is possible to specify monthly, weekly, half-daily, daily, hourly, or
* minutely rollover schedules.
*
* <p>
* <table border="1" cellpadding="2">
* <tr>
* <th>DatePattern</th>
* <th>Rollover schedule</th>
* <th>Example</th>
*
* <tr>
* <td><code>'.'yyyy-MM</code>
* <td>Rollover at the beginning of each month</td>
*
* <td>At midnight of May 31st, 2002 <code>/foo/bar.log</code> will be copied to
* <code>/foo/bar.log.2002-05</code>. Logging for the month of June will be
* output to <code>/foo/bar.log</code> until it is also rolled over the next
* month.
*
* <tr>
* <td><code>'.'yyyy-ww</code>
*
* <td>Rollover at the first day of each week. The first day of the week depends
* on the locale.</td>
*
* <td>Assuming the first day of the week is Sunday, on Saturday midnight, June
* 9th 2002, the file <i>/foo/bar.log</i> will be copied to
* <i>/foo/bar.log.2002-23</i>. Logging for the 24th week of 2002 will be output
* to <code>/foo/bar.log</code> until it is rolled over the next week.
*
* <tr>
* <td><code>'.'yyyy-MM-dd</code>
*
* <td>Rollover at midnight each day.</td>
*
* <td>At midnight, on March 8th, 2002, <code>/foo/bar.log</code> will be copied
* to <code>/foo/bar.log.2002-03-08</code>. Logging for the 9th day of March
* will be output to <code>/foo/bar.log</code> until it is rolled over the next
* day.
*
* <tr>
* <td><code>'.'yyyy-MM-dd-a</code>
*
* <td>Rollover at midnight and midday of each day.</td>
*
* <td>At noon, on March 9th, 2002, <code>/foo/bar.log</code> will be copied to
* <code>/foo/bar.log.2002-03-09-AM</code>. Logging for the afternoon of the 9th
* will be output to <code>/foo/bar.log</code> until it is rolled over at
* midnight.
*
* <tr>
* <td><code>'.'yyyy-MM-dd-HH</code>
*
* <td>Rollover at the top of every hour.</td>
*
* <td>At approximately 11:00.000 o'clock on March 9th, 2002,
* <code>/foo/bar.log</code> will be copied to
* <code>/foo/bar.log.2002-03-09-10</code>. Logging for the 11th hour of the 9th
* of March will be output to <code>/foo/bar.log</code> until it is rolled over
* at the beginning of the next hour.
*
*
* <tr>
* <td><code>'.'yyyy-MM-dd-HH-mm</code>
*
* <td>Rollover at the beginning of every minute.</td>
*
* <td>At approximately 11:23,000, on March 9th, 2001, <code>/foo/bar.log</code>
* will be copied to <code>/foo/bar.log.2001-03-09-10-22</code>. Logging for the
* minute of 11:23 (9th of March) will be output to <code>/foo/bar.log</code>
* until it is rolled over the next minute.
*
* </table>
*
* <p>
* Do not use the colon ":" character in anywhere in the <b>DatePattern</b>
* option. The text before the colon is interpeted as the protocol specificaion
* of a URL which is probably not what you want.
*/
public class MyDailyRollingFileAppender extends FileAppender {
// The code assumes that the following constants are in a increasing
// sequence.
static final int TOP_OF_TROUBLE = -1;
static final int TOP_OF_MINUTE = 0;
static final int TOP_OF_HOUR = 1;
static final int HALF_DAY = 2;
static final int TOP_OF_DAY = 3;
static final int TOP_OF_WEEK = 4;
static final int TOP_OF_MONTH = 5;
private final String place_holder="%fdps";
private String fileDatePattern="yyyyMMdd";
private SimpleDateFormat fdpsFormat;
private String replcaeFileName;
private final long ONE_DATE_MILLIONS=24*60*60*1000;
/**
* The default maximum file size is 10MB.
*/
protected long maxFileSize = 10 * 1024 * 1024;
protected int logKeepDays = 30;
/**
* There is one backup file by default.
*/
protected int maxBackupIndex = 1;
/**
* The date pattern. By default, the pattern is set to "'.'yyyy-MM-dd"
* meaning daily rollover.
*/
// private String datePattern = "'.'yyyy-MM-dd";
/**
* The log file will be renamed to the value of the scheduledFilename
* variable when the next interval is entered. For example, if the rollover
* period is one hour, the log file will be renamed to the value of
* "scheduledFilename" at the beginning of the next hour.
*
* The precise time when a rollover occurs depends on logging activity.
*/
private String scheduledFilename;
/**
* The next time we estimate a rollover should occur.
*/
private long nextCheck = System.currentTimeMillis() - 1;
Date now = new Date();
// SimpleDateFormat sdf;
// RollingCalendar rc = new RollingCalendar();
int checkPeriod = TOP_OF_TROUBLE;
// The gmtTimeZone is used only in computeCheckPeriod() method.
static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");
/**
* The default constructor does nothing.
*/
public MyDailyRollingFileAppender() {
}
/**
* Instantiate a <code>MyDailyRollingFileAppender</code> and open the file
* designated by <code>filename</code>. The opened filename will become the
* ouput destination for this appender.
*/
public MyDailyRollingFileAppender(Layout layout, String filename,
String datePattern) throws IOException {
super(layout, filename, true);
// this.datePattern = datePattern;
activateOptions();
}
/**
* Get the maximum size that the output file is allowed to reach before
* being rolled over to backup files.
*
* @since 1.1
*/
public long getMaximumFileSize() {
return maxFileSize;
}
/**
* Set the maximum size that the output file is allowed to reach before
* being rolled over to backup files.
*
* <p>
* This method is equivalent to {@link #setMaxFileSize} except that it is
* required for differentiating the setter taking a <code>long</code>
* argument from the setter taking a <code>String</code> argument by the
* JavaBeans {@link java.beans.Introspector Introspector}.
*
* @see #setMaxFileSize(String)
*/
public void setMaximumFileSize(long maxFileSize) {
this.maxFileSize = maxFileSize;
}
/**
* Set the maximum size that the output file is allowed to reach before
* being rolled over to backup files.
*
* <p>
* In configuration files, the <b>MaxFileSize</b> option takes an long
* integer in the range 0 - 2^63. You can specify the value with the
* suffixes "KB", "MB" or "GB" so that the integer is interpreted being
* expressed respectively in kilobytes, megabytes or gigabytes. For example,
* the value "10KB" will be interpreted as 10240.
*/
public void setMaxFileSize(String value) {
maxFileSize = OptionConverter.toFileSize(value, maxFileSize + 1);
}
/**
* Returns the value of the <b>MaxBackupIndex</b> option.
*/
public int getMaxBackupIndex() {
return maxBackupIndex;
}
/**
* Set the maximum number of backup files to keep around.
*
* <p>
* The <b>MaxBackupIndex</b> option determines how many backup files are
* kept before the oldest is erased. This option takes a positive integer
* value. If set to zero, then there will be no backup files and the log
* file will be truncated when it reaches <code>MaxFileSize</code>.
*/
public void setMaxBackupIndex(int maxBackups) {
this.maxBackupIndex = maxBackups;
}
public int getLogKeepDays() {
return logKeepDays;
}
public void setLogKeepDays(int logKeepDays) {
this.logKeepDays = logKeepDays;
}
/**
* The <b>DatePattern</b> takes a string in the same format as expected by
* {@link SimpleDateFormat}. This options determines the rollover schedule.
*/
// public void setDatePattern(String pattern) {
// datePattern = pattern;
// }
//
// /** Returns the value of the <b>DatePattern</b> option. */
// public String getDatePattern() {
// return datePattern;
// }
public void activateOptions() {
if (fileName != null) {
replcaeFileName=fileName;
Calendar calendar=Calendar.getInstance();
now=DateUtil.dateStart(new Date());
// sdf = new SimpleDateFormat(datePattern);
fdpsFormat = new SimpleDateFormat(fileDatePattern);
String fileDatePatternStr = fdpsFormat.format(now);
if(fileName.indexOf(place_holder)>-1) {
fileName=fileName.replaceAll(place_holder, fileDatePatternStr);
}
// int type = computeCheckPeriod();
// printPeriodicity(type);
// rc.setType(type);
File file = new File(fileName);
// scheduledFilename = fileName
// + sdf.format(new Date(file.lastModified()));
//写死 只能2个 文件夹和文件后缀
int index=fileName.indexOf(fileDatePatternStr);
if(index>0) {
String subString=fileName.substring(0,index+fileDatePatternStr.length());
File parentFile=new File(subString);
if(!parentFile.exists()) {
parentFile.mkdir();
}
}
super.activateOptions();
} else {
LogLog.error("Either File or DatePattern options are not set for appender ["
+ name + "].");
}
}
void printPeriodicity(int type) {
switch (type) {
case TOP_OF_MINUTE:
LogLog.debug("Appender [" + name + "] to be rolled every minute.");
break;
case TOP_OF_HOUR:
LogLog.debug("Appender [" + name
+ "] to be rolled on top of every hour.");
break;
case HALF_DAY:
LogLog.debug("Appender [" + name
+ "] to be rolled at midday and midnight.");
break;
case TOP_OF_DAY:
LogLog.debug("Appender [" + name + "] to be rolled at midnight.");
break;
case TOP_OF_WEEK:
LogLog.debug("Appender [" + name
+ "] to be rolled at start of week.");
break;
case TOP_OF_MONTH:
LogLog.debug("Appender [" + name
+ "] to be rolled at start of every month.");
break;
default:
LogLog.warn("Unknown periodicity for appender [" + name + "].");
}
}
// This method computes the roll over period by looping over the
// periods, starting with the shortest, and stopping when the r0 is
// different from from r1, where r0 is the epoch formatted according
// the datePattern (supplied by the user) and r1 is the
// epoch+nextMillis(i) formatted according to datePattern. All date
// formatting is done in GMT and not local format because the test
// logic is based on comparisons relative to 1970-01-01 00:00:00
// GMT (the epoch).
// int computeCheckPeriod() {
// RollingCalendar rollingCalendar = new RollingCalendar(gmtTimeZone,
// Locale.ENGLISH);
// // set sate to 1970-01-01 00:00:00 GMT
// Date epoch = new Date(0);
// if (datePattern != null) {
// for (int i = TOP_OF_MINUTE; i <= TOP_OF_MONTH; i++) {
// SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
// datePattern);
// simpleDateFormat.setTimeZone(gmtTimeZone); // do all date
// // formatting in GMT
// String r0 = simpleDateFormat.format(epoch);
// rollingCalendar.setType(i);
// Date next = new Date(rollingCalendar.getNextCheckMillis(epoch));
// String r1 = simpleDateFormat.format(next);
// // System.out.println("Type = "+i+", r0 = "+r0+", r1 = "+r1);
// if (r0 != null && r1 != null && !r0.equals(r1)) {
// return i;
// }
// }
// }
// return TOP_OF_TROUBLE; // Deliberately head for trouble...
// }
/**
* Implements the usual roll over behaviour.
*
* <p>
* If <code>MaxBackupIndex</code> is positive, then files {
* <code>File.1</code>, ..., <code>File.MaxBackupIndex -1</code> are renamed
* to {<code>File.2</code>, ..., <code>File.MaxBackupIndex</code> .
* Moreover, <code>File</code> is renamed <code>File.1</code> and closed. A
* new <code>File</code> is created to receive further log output.
*
* <p>
* If <code>MaxBackupIndex</code> is equal to zero, then the
* <code>File</code> is truncated with no backup files created.
*/
public// synchronization not necessary since doAppend is alreasy synched
void sizeRollOver() {
File target;
File file;
LogLog.debug("rolling over count="
+ ((CountingQuietWriter) qw).getCount());
LogLog.debug("maxBackupIndex=" + maxBackupIndex);
String datedFilename = fileName;
if (maxBackupIndex > 0) {
// Delete the oldest file, to keep Windows happy.
file = new File(datedFilename + '.' + maxBackupIndex);
if (file.exists())
file.delete();
// Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3,
// 2}
for (int i = maxBackupIndex - 1; i >= 1; i--) {
file = new File(datedFilename + "." + i);
if (file.exists()) {
target = new File(datedFilename + '.' + (i + 1));
LogLog.debug("Renaming file " + file + " to " + target);
file.renameTo(target);
}
}
// Rename fileName to datedFilename.1
target = new File(datedFilename + "." + 1);
this.closeFile(); // keep windows happy.
file = new File(fileName);
LogLog.debug("Renaming file " + file + " to " + target);
file.renameTo(target);
}else if (maxBackupIndex < 0){//infinite number of files
//find the max backup index
for (int i = 1; i < Integer.MAX_VALUE; i++) {
target = new File(datedFilename + "." + i);
if (! target.exists()) {//Rename fileName to datedFilename.i
this.closeFile();
file = new File(fileName);
file.renameTo(target);
LogLog.debug("Renaming file " + file + " to " + target);
break;
}
}
}
try {
// This will also close the file. This is OK since multiple
// close operations are safe.
this.setFile(fileName, false, bufferedIO, bufferSize);
} catch (IOException e) {
LogLog.error("setFile(" + fileName + ", false) call failed.", e);
}
scheduledFilename = datedFilename;
}
public// synchronization not necessary since doAppend is alreasy synched
boolean logsRollOver(File[] logFileDirList) {
File target;
File file;
LogLog.debug("rolling over count="
+ ((CountingQuietWriter) qw).getCount());
LogLog.debug("maxBackupIndex=" + maxBackupIndex);
String datedFilename = fileName;
for (File logFileDir : logFileDirList) {
if (logFileDir.exists()) {
FileUtils.delete(logFileDir.getAbsolutePath());
}
}
this.closeFile(); // keep windows happy.
try {
// This will also close the file. This is OK since multiple
// close operations are safe.
this.setFile(fileName, false, bufferedIO, bufferSize);
} catch (IOException e) {
LogLog.error("setFile(" + fileName + ", false) call failed.", e);
}
scheduledFilename = datedFilename;
return true;
}
public synchronized void setFile(String fileName, boolean append,
boolean bufferedIO, int bufferSize) throws IOException {
super.setFile(fileName, append, this.bufferedIO, this.bufferSize);
if (append) {
File f = new File(fileName);
((CountingQuietWriter) qw).setCount(f.length());
}
}
protected void setQWForFiles(Writer writer) {
this.qw = new CountingQuietWriter(writer, errorHandler);
}
/**
* Rollover the current file to a new file.
*/
// void timeRollOver() throws IOException {
//
// /* Compute filename, but only if datePattern is specified */
// if (datePattern == null) {
// errorHandler.error("Missing DatePattern option in rollOver().");
// return;
// }
//
// String datedFilename = fileName;
// // 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 = file.renameTo(target);
// if (result) {
// 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.
// super.setFile(fileName, false, this.bufferedIO, this.bufferSize);
// } catch (IOException e) {
// errorHandler.error("setFile(" + fileName + ", false) call failed.");
// }
// scheduledFilename = datedFilename;
// }
/**
* This method differentiates MyDailyRollingFileAppender from its super class.
*
* <p>
* Before actually logging, this method will check whether it is time to do
* a rollover. If it is, it will schedule the next rollover time and then
* rollover.
* */
protected void subAppend(LoggingEvent event) {
long n = System.currentTimeMillis();
if (now.getTime()+ONE_DATE_MILLIONS<n) {
now=DateUtil.dateStart(new Date());
String fileDatePatternStr = fdpsFormat.format(now);
fileName=replcaeFileName;
if(fileName.indexOf(place_holder)>-1) {
fileName=fileName.replaceAll(place_holder, fileDatePatternStr);
}
// int type = computeCheckPeriod();
// printPeriodicity(type);
// rc.setType(type);
File file = new File(fileName);
scheduledFilename = fileName;
//写死 只能2个 文件夹和文件后缀
int index=fileName.indexOf(fileDatePatternStr);
if(index>0) {
String subString=fileName.substring(0,index+fileDatePatternStr.length());
File parentFile=new File(subString);
if(!parentFile.exists()) {
parentFile.mkdir();
}
}
try {
this.setFile(fileName, true, this.bufferedIO, this.bufferSize);
} catch (IOException e) {
errorHandler.error("setFile(" + fileName + ", true) call failed.");
}
} /*else if ((fileName != null)
&& ((CountingQuietWriter) qw).getCount() >= maxFileSize) {
sizeRollOver();
} */
else if ((fileName != null)) {
File[] logFileDirList = getLogFileDirList();
if (logFileDirList.length > 0) {
logsRollOver(logFileDirList);
}
}
super.subAppend(event);
}
private File[] getLogFileDirList() {
String fileDatePatternStr = fdpsFormat.format(now);
int index=fileName.indexOf(fileDatePatternStr);
String subString=fileName.substring(0,index+fileDatePatternStr.length());
File parentFile=new File(subString);
File logFileDir = parentFile.getParentFile();
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 0-logKeepDays);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Date logFileDirDate = null;
try {
logFileDirDate = sdf.parse(name);
} catch (ParseException e) {
System.out.println("e:" + e);
LogLog.error("err:", e);
}
return logFileDirDate.before(calendar.getTime());
}
};
File[] logFileDirList = logFileDir.listFiles(filter);
return logFileDirList;
}
public String getFileDatePattern() {
return fileDatePattern;
}
public void setFileDatePattern(String fileDatePattern) {
this.fileDatePattern = fileDatePattern;
}
public SimpleDateFormat getFdpsFormat() {
return fdpsFormat;
}
public void setFdpsFormat(SimpleDateFormat fdpsFormat) {
this.fdpsFormat = fdpsFormat;
}
public static void main(String[] args) {
FileOutputStream fos = null;
try {
File file = new File(
"C:\\Users\\Administrator\\Desktop\\logs\\yyyyMMdd\\yyyyMMdd.log");
fos = new FileOutputStream(file);
// 2m
byte[] byte2m = new byte[1024 * 1024 * 2];
fos.write(byte2m);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.flush();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
/**
* RollingCalendar is a helper class to MyDailyRollingFileAppender. Given a
* periodicity type and the current time, it computes the start of the next
* interval.
* */
/*class RollingCalendar extends GregorianCalendar {
int type = MyDailyRollingFileAppender.TOP_OF_TROUBLE;
RollingCalendar() {
super();
}
RollingCalendar(TimeZone tz, Locale locale) {
super(tz, locale);
}
void setType(int type) {
this.type = type;
}
public long getNextCheckMillis(Date now) {
return getNextCheckDate(now).getTime();
}
public Date getNextCheckDate(Date now) {
this.setTime(now);
switch (type) {
case MyDailyRollingFileAppender.TOP_OF_MINUTE:
this.set(Calendar.SECOND, 0);
this.set(Calendar.MILLISECOND, 0);
this.add(Calendar.MINUTE, 1);
break;
case MyDailyRollingFileAppender.TOP_OF_HOUR:
this.set(Calendar.MINUTE, 0);
this.set(Calendar.SECOND, 0);
this.set(Calendar.MILLISECOND, 0);
this.add(Calendar.HOUR_OF_DAY, 1);
break;
case MyDailyRollingFileAppender.HALF_DAY:
this.set(Calendar.MINUTE, 0);
this.set(Calendar.SECOND, 0);
this.set(Calendar.MILLISECOND, 0);
int hour = get(Calendar.HOUR_OF_DAY);
if (hour < 12) {
this.set(Calendar.HOUR_OF_DAY, 12);
} else {
this.set(Calendar.HOUR_OF_DAY, 0);
this.add(Calendar.DAY_OF_MONTH, 1);
}
break;
case MyDailyRollingFileAppender.TOP_OF_DAY:
this.set(Calendar.HOUR_OF_DAY, 0);
this.set(Calendar.MINUTE, 0);
this.set(Calendar.SECOND, 0);
this.set(Calendar.MILLISECOND, 0);
this.add(Calendar.DATE, 1);
break;
case MyDailyRollingFileAppender.TOP_OF_WEEK:
this.set(Calendar.DAY_OF_WEEK, getFirstDayOfWeek());
this.set(Calendar.HOUR_OF_DAY, 0);
this.set(Calendar.SECOND, 0);
this.set(Calendar.MILLISECOND, 0);
this.add(Calendar.WEEK_OF_YEAR, 1);
break;
case MyDailyRollingFileAppender.TOP_OF_MONTH:
this.set(Calendar.DATE, 1);
this.set(Calendar.HOUR_OF_DAY, 0);
this.set(Calendar.SECOND, 0);
this.set(Calendar.MILLISECOND, 0);
this.add(Calendar.MONTH, 1);
break;
default:
throw new IllegalStateException("Unknown periodicity type.");
}
return getTime();
}
} */
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.apache.log4j.Logger;
import com.xxxx.core.annotation.Memo;
/**
* 日期工具类
*
* @author icc
*
*/
public class DateUtil {
private final static Logger log = Logger.getLogger(DateUtil.class);
public final static String DATE_FORMAT_LONG = "yyyy-MM-dd HH:mm:ss";
public final static String DATE_FORMAT_SHORT = "yyyy-MM-dd";
public final static String DATE_FORMAT_TIME = "HH:mm:ss";
public static long formatToLong(Date date, String formatStr) {
if (date == null || formatStr == null) {
return 0;
}
return Long.parseLong(new SimpleDateFormat(formatStr).format(date));
}
public static String format(Date date, DateFormat formatter) {
if (date == null || formatter == null) {
return null;
}
return formatter.format(date);
}
public static String format(Date date, String formatter) {
if (date == null || formatter == null || formatter.isEmpty()) {
return null;
}
DateFormat format = new SimpleDateFormat(formatter);
return format.format(date);
}
public static String format(Date date) {
return format(date, new SimpleDateFormat(DATE_FORMAT_LONG));
}
public static String formatShort(Date date) {
return format(date, new SimpleDateFormat(DATE_FORMAT_SHORT));
}
public static String formatTime(Date date) {
return format(date, new SimpleDateFormat(DATE_FORMAT_TIME));
}
public static String format(long timeMillis, DateFormat formatter) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeMillis);
return format(calendar.getTime(), formatter);
}
public static String format(long timeMillis) {
return format(timeMillis, new SimpleDateFormat(DATE_FORMAT_LONG));
}
public static String formatShort(long timeMillis) {
return format(timeMillis, new SimpleDateFormat(DATE_FORMAT_SHORT));
}
public static String formatTime(long timeMillis) {
return format(timeMillis, new SimpleDateFormat(DATE_FORMAT_TIME));
}
public static Date parse(String dateStr, DateFormat formatter) throws ParseException {
if (dateStr == null || dateStr.isEmpty() || formatter == null) {
return null;
}
return formatter.parse(dateStr);
}
public static Date parsetDateTime(String dateStr) {
try {
return parse(dateStr, new SimpleDateFormat(DATE_FORMAT_LONG));
} catch (ParseException e) {
return new Date();
}
}
public static Date parsetDate(String dateStr) throws ParseException {
return parse(dateStr, new SimpleDateFormat(DATE_FORMAT_LONG));
}
public static Date parsetShortDate(String dateStr) throws ParseException {
return parse(dateStr, new SimpleDateFormat(DATE_FORMAT_SHORT));
}
public static Date parseShortDate(String dateStr) {
return parseDate(dateStr, new SimpleDateFormat(DATE_FORMAT_SHORT));
}
public static Date parseDate(String dateStr, String formatStr) {
try {
return parse(dateStr, new SimpleDateFormat(formatStr));
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
public static Date parseDate(String dateStr, DateFormat format) {
try {
return parse(dateStr, format);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
public static Date parsetShortDate(String dateStr, DateFormat format) throws ParseException {
return parse(dateStr, format);
}
public static Date parse(String dateStr, String format) throws ParseException {
if (format == null || format.isEmpty()) {
return null;
}
DateFormat formatter = new SimpleDateFormat(format);
return parse(dateStr, formatter);
}
public static long getTimeInMillis(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.getTimeInMillis();
}
public static long getTimeInMillis() {
return getTimeInMillis(new Date());
}
public static long getTimeMinus(Date arg1, Date arg2) {
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.setTime(arg1);
calendar2.setTime(arg2);
return calendar1.getTimeInMillis() - calendar2.getTimeInMillis();
}
public static boolean isTheSameDay(Date arg1, Date arg2) {
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.setTime(arg1);
calendar2.setTime(arg2);
if (calendar1.get(Calendar.YEAR) != calendar2.get(Calendar.YEAR)) {
return false;
}
if (calendar1.get(Calendar.MONTH) != calendar2.get(Calendar.MONTH)) {
return false;
}
if (calendar1.get(Calendar.DATE) != calendar2.get(Calendar.DATE)) {
return false;
}
return true;
}
@Memo("db查询时,>=yyyy-MM-dd 00:00:00")
public static Date dateStart(Date date) {
Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
return c.getTime();
}
@Memo("db查询时,<=yyyy-MM-dd 23:59:59")
public static Date dateEnd(Date date) {
Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(Calendar.HOUR_OF_DAY, 23);
c.set(Calendar.MINUTE, 59);
c.set(Calendar.SECOND, 59);
return c.getTime();
}
@Memo("db查询时,>=yyyy-MM-dd 00:00:00")
public static Date dateGreater(String dataStr) {
String dStr = dataStr.substring(0, 10) + " 00:00:00";
try {
return parsetDate(dStr);
} catch (ParseException e) {
log.error("", e);
return new Date();
}
}
@Memo("db查询时,<=yyyy-MM-dd 23:59:59")
public static Date dateLess(String dataStr) {
String dStr = dataStr.substring(0, 10) + " 23:59:59";
try {
return parsetDate(dStr);
} catch (ParseException e) {
log.error("", e);
return new Date();
}
}
@Memo("date时间过去了day周")
public static boolean isPassesDay(Date date, int day) {
return isPassesDate(date, day * 7);
}
@Memo("date时间过去了dateNum天")
public static boolean isPassesDate(Date date, int dateNum) {
return isPassesHour(date, dateNum * 24);
}
@Memo("date时间过去了hour小时")
public static boolean isPassesHour(Date date, int hour) {
return isPassesMinutes(date, hour * 60);
}
@Memo("date时间过去了minutes分钟")
public static boolean isPassesMinutes(Date date, int minutes) {
return isPassesSecond(date, minutes * 60);
}
@Memo("date时间过去了second钞")
public static boolean isPassesSecond(Date date, int second) {
return (System.currentTimeMillis() - date.getTime()) > (second * 1000);
}
public static void main(String[] args) {
}
}
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
public class FileUtils {
protected static final Logger log = Logger.getLogger(FileUtils.class);
/**
* 复制文件,如目标文件存在并文件长度一样没不覆盖文件,否则覆盖文件
*
* @param from
* @param to
* @throws IOException
*/
public static void copy(String from, String to) {
try {
File fromFile = new File(from);
save(fromFile, to);
} catch (Exception ex) {
log.error("copy " + from + " to " + to, ex);
}
}
public static void save(File fromFile, String to) {
InputStream in = null;
OutputStream out = null;
try {
if (fromFile.exists() && fromFile.isFile()) {
File toFile = new File(to);
if (toFile.exists() && toFile.isFile()) {
if (toFile.length() == fromFile.length()) {
log.info(toFile.getAbsolutePath() + " 文件已存在!");
return;
} else {
log.info(toFile.getAbsolutePath() + " 删除文件!");
toFile.deleteOnExit();
}
}
log.info("copy " + fromFile.getPath() + " to " + to);
in = new BufferedInputStream(new FileInputStream(fromFile));
out = new BufferedOutputStream(new FileOutputStream(to));
for (int b = in.read(); b != -1; b = in.read()) {
out.write(b);
}
} else {
log.warn(" not exists file : " + fromFile.getPath());
}
} catch (Exception ex) {
log.error("copy file to " + to, ex);
}finally{
try {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static byte[] read(File file) {
FileInputStream fis = null;
ByteArrayOutputStream baos = null;
try {
baos = new ByteArrayOutputStream();
fis = new FileInputStream(file);
int bytesRead = 0;
int offSet = 0;
byte[] buffer = new byte[1024];
while ((bytesRead = fis.read(buffer, offSet, buffer.length)) > 0) {
baos.write(buffer, 0, bytesRead);
}
buffer = baos.toByteArray();
return buffer;
} catch (Throwable ex) {
log.error("read file ", ex);
return null;
} finally {
try {
if (fis != null)
fis.close();
if (baos != null)
baos.close();
} catch (Throwable ex) {
log.error("read file ", ex);
}
System.gc();
}
}
/**
*
* 直接覆盖文件
*
* @param from
* @param to
* @throws IOException
*/
public static void cover(String from, String to) {
InputStream in = null;
OutputStream out = null;
try {
File fromFile = new File(from);
if (fromFile.exists() && fromFile.isFile()) {
File toFile = new File(to);
if (toFile.exists() && toFile.isFile()) {
toFile.deleteOnExit();
}
log.warn("cover " + from + " to " + to);
in = new BufferedInputStream(new FileInputStream(fromFile));
out = new BufferedOutputStream(new FileOutputStream(to));
for (int b = in.read(); b != -1; b = in.read()) {
out.write(b);
}
} else {
log.warn(" not exists file : " + from);
}
} catch (Exception ex) {
log.error("cover " + from + " to " + to, ex);
}finally{
try {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 判断文件是否为图片<br>
* <br>
*
* @param pInput
* 文件名<br>
* @param pImgeFlag
* 判断具体文件类型<br>
* @return 检查后的结果<br>
* @throws Exception
*/
public static boolean isImage(String filename) throws Exception {
if (StringUtils.isEmpty(filename)) {
return false;
}
String tmpName = filename.substring(filename.lastIndexOf(".") + 1, filename.length());
String imgeArray[] = {"bmp", "dib", "gif", "jfif", "jpe", "jpeg", "jpg", "png", "tif", "tiff", "ico", "pcx"};
for (int i = 0; i < imgeArray.length; i++) {
if (imgeArray[i].equals(tmpName.toLowerCase())) {
return true;
}
}
return false;
}
/**
* 删除文件,可以是文件或文件夹
*
* @param fileName:要删除的文件名
* @return 删除成功返回true,否则返回false
*/
public static boolean delete(String fileName) {
File file = new File(fileName);
if (!file.exists()) {
System.out.println("删除文件失败:" + fileName + "不存在!");
log.info("删除文件失败:" + fileName + "不存在!");
return false;
} else {
if (file.isFile())
return deleteFile(fileName);
else
return deleteDirectory(fileName);
}
}
/**
* 删除单个文件
*
* @param fileName:要删除的文件的文件名
* @return 单个文件删除成功返回true,否则返回false
*/
public static boolean deleteFile(String fileName) {
File file = new File(fileName);
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if (file.exists() && file.isFile()) {
if (file.delete()) {
System.out.println("删除单个文件" + fileName + "成功!");
log.info("删除单个文件" + fileName + "成功!");
return true;
} else {
System.out.println("删除单个文件" + fileName + "失败!");
log.info("删除单个文件" + fileName + "失败!");
return false;
}
} else {
System.out.println("删除单个文件失败:" + fileName + "不存在!");
log.info("删除单个文件失败:" + fileName + "不存在!");
return false;
}
}
/**
* 删除目录及目录下的文件
*
* @param dir:要删除的目录的文件路径
* @return 目录删除成功返回true,否则返回false
*/
public static boolean deleteDirectory(String dir) {
// 如果dir不以文件分隔符结尾,自动添加文件分隔符
if (!dir.endsWith(File.separator))
dir = dir + File.separator;
File dirFile = new File(dir);
// 如果dir对应的文件不存在,或者不是一个目录,则退出
if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
System.out.println("删除目录失败:" + dir + "不存在!");
log.info("删除目录失败:" + dir + "不存在!");
return false;
}
boolean flag = true;
// 删除文件夹中的所有文件包括子目录
File[] files = dirFile.listFiles();
for (int i = 0; i < files.length; i++) {
// 删除子文件
if (files[i].isFile()) {
flag = deleteFile(files[i].getAbsolutePath());
if (!flag)
break;
}
// 删除子目录
else if (files[i].isDirectory()) {
flag = deleteDirectory(files[i].getAbsolutePath());
if (!flag)
break;
}
}
if (!flag) {
System.out.println("删除目录失败!");
log.info("删除目录失败!");
return false;
}
// 删除当前目录
if (dirFile.delete()) {
System.out.println("删除目录" + dir + "成功!");
log.info("删除目录" + dir + "成功!");
return true;
} else {
return false;
}
}
}