下面的代码创建一个名称为当前日期的目录,并将日志文件存储在该目录中,但第二天日志文件将存储数据保存在同一目录中...我想每天创建一个与当前日期和商店同名的新目录新的日志文件在里面....
private static Date dir1 = new java.util.Date(System.currentTimeMillis());
private static Date dir = new java.util.Date(System.currentTimeMillis());
private static String baseDir1 =“/ home / gaurav / flinklogs /”;
private static String newDir1 = createDateBasedDirectory(baseDir1,dir1);
private static FileHandler fh1;
static {
try {
fh1 = new FileHandler(newDir1 + "/data.log", 0, 1, true);
} catch (IOException | SecurityException e) {
}
}
public static void main(String args [])throws Exception {
Logger logger = Logger.getLogger("MyLog");
// This block configure the logger with handler and formatter
logger.addHandler(fh);
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter);
// the following statement is used to log any messages
logger.info(e.getMessage());
}
public static String createDateBasedDirectory(String baseDirectory, Date argDate)
{
String newDir = null;
if (baseDirectory != null && argDate != null) {
try {
String format = "yyyy-MM-dd";
DateFormat dateFormatter = new SimpleDateFormat(format);
String date = dateFormatter.format(argDate);
// check if the directory exists:
String todaysLogDir = baseDirectory + "\\" + date;
Path todaysDirectoryPath = Paths.get(todaysLogDir);
// and check if this Path exists
if (Files.exists(todaysDirectoryPath)) {
// if present, just return it in order to write (into) a log file there
return todaysDirectoryPath.toUri().toString();
} else {
newDir = baseDirectory + date;
new File(newDir).mkdir();
return newDir.toString();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return newDir;
}
2 回答
这里的问题是您已将所有变量声明为静态,并在静态块中执行文件处理程序分配 .
因此,一旦你的程序启动它就会初始化所有内容,然后第二天没有重新初始化,因为程序已经从前一天开始运行 . 您需要使用更改日期重新分配文件处理程序 .
另外,我可以建议您查看log4j,因为您可以根据您的要求轻松配置它 .
您的日期时间处理可以使用一些帮助 .
首先,您使用的是几年前由java.time类取代的麻烦的旧日期时间类(
Date
,SimpleDateFormat
) . 你忽略了时区的关键问题(下面将进一步讨论) .java.util.Date
被java.time.Instant
取代SimpleDateFormat
被java.time.format.DateTimeFormatter
取代您所需的YYYY-MM-DD格式由ISO 8601标准定义 . 生成/解析字符串时,java.time类默认使用标准格式 . 因此无需指定格式化模式 .
瞬发
你的代码是多余的 . 简单地调用
new Date()
具有相同的效果,捕获自1970 UTC,1970-01-01T00:00:00Z的第一时刻的纪元参考以来的毫秒数的计数 .现代代码用
Instant
替换Date
. Instant类表示UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分的最多九(9)位数) .但我们真的不需要
Instant
为您的问题 . 请改用LocalDate
.LocalDate
LocalDate类表示没有时间且没有时区的仅日期值 .
时区对于确定日期至关重要 . 对于任何给定的时刻,日期在全球范围内因地区而异 . 例如,Paris France午夜后的几分钟是新的一天,而在Montréal Québec仍然是“昨天” .
如果未指定时区,则JVM会隐式应用其当前的默认时区 . 在运行时(!)期间,该默认值可能为change at any moment,因此您的结果可能会有所不同 . 最好明确指定[期望/预期时区] [2]作为参数 .
以
continent/region
的格式指定proper time zone name,例如America/Montreal,Africa/Casablanca或Pacific/Auckland
. 切勿使用3-4字母缩写,例如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!) .如果要使用JVM的当前默认时区,请求它并作为参数传递 . 如果省略,则隐式应用JVM的当前默认值 . 最好是显式的,因为默认情况下可以在运行期间随时由JVM中任何应用程序的任何线程中的任何代码更改 .
或者您可以选择始终使用UTC,因为人们运行Stack Overflow . 请注意您的日常声誉如何指向翻滚,例如美国西海岸时间下午4点左右 .
字符串
要生成标准ISO 8601格式的
String
,只需调用LocalDate::toString
即可 .记录框架
正如其他人所建议的那样,您不应该花费宝贵的时间重新发明日志框架来每天翻转文件夹 . 任何体面的日志框架都可以为您做到这一点 .
特别是,我建议您先考虑使用slf4jfaçadeAPI . 在您希望向日志发送信息的代码中,调用slf4j . 在slf4j后面可以找到许多不同的日志框架 . 您可以稍后为另一个日志框架切换一个日志框架,而无需更改应用程序的代码 .
如果尚未使用日志记录框架,请采用Logback . Logback项目是slf4j API的直接实现 . 所以不需要适配器 .
slf4j和Logback都是由发明log4j的同一个人编写的 . 所以他在这个领域有很多经验 .
关于java.time
java.time框架内置于Java 8及更高版本中 . 这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date,Calendar和SimpleDateFormat .
Joda-Time项目现在位于maintenance mode,建议迁移到java.time类 .
要了解更多信息,请参阅Oracle Tutorial . 并搜索Stack Overflow以获取许多示例和解释 . 规格是JSR 310 .
您可以直接与您的数据库交换java.time对象 . 使用符合JDBC 4.2或更高版本的JDBC driver . 不需要字符串,不需要
java.sql.*
类 .从哪里获取java.time类?
Java SE 8,Java SE 9,Java SE 10,以及之后
内置 .
具有捆绑实现的标准Java API的一部分 .
Java 9增加了一些小功能和修复 .
Java SE 6和Java SE 7
大部分java.time功能在ThreeTen-Backport中反向移植到Java 6&7 .
Android
更新版本的Android捆绑java.time类的实现 .
对于早期的Android(<26),ThreeTenABP项目适应ThreeTen-Backport(如上所述) . 见How to use ThreeTenABP… .