Java:每隔几秒钟创建一次文件
我正在使用ScheduledThreadPoolExecutor每隔fileIntervalInSeconds创建一个文件:Java:每隔几秒钟创建一次文件,java,multithreading,file-io,concurrency,thread-safety,Java,Multithreading,File Io,Concurrency,Thread Safety,我正在使用ScheduledThreadPoolExecutor每隔fileIntervalInSeconds创建一个文件: executorService = new ScheduledThreadPoolExecutor(1); executorService.scheduleAtFixedRate(new Runnable() { @Override public void run()
executorService = new ScheduledThreadPoolExecutor(1);
executorService.scheduleAtFixedRate(new Runnable()
{
@Override
public void run()
{
File file = new File(fileName);
if (file.exists())
{
Log.debug("creating new file");
openFileWriter(file);
}
}
}, fileIntervalInSeconds, fileIntervalInSeconds, TimeUnit.SECONDS);
}
private void openFileWriter() throws FileSystemNotificationException
{
// 1 - close exist writer
writer.close();
// 2 - rename to backup file name
...
// 3 - create new file
FileWriter writerFile = new FileWriter(fileName, true);
writer = new PrintWriter(writerFile);
}
我一直在向文件中写入警告消息:
private synchronized void writeLine(String line) throws InterruptedException
{
writer.println(line);
}
我的问题是:
在写入文件之前检查文件是否存在如何。不需要反向绑定线程或同步
private synchronized void writeLine(String line) {
if (!file.exists())
reopenWritingFile();
writer.println(line);
}
你有两个选择:
volatile PrintWriter writer;
ReadWriteLock lock = new ReentrantReadWriteLock();
Lock writeLock = lock.writeLock();
Lock readLock = lock.readLock();
private void openFileWriterWithLock() throws IOException {
if (writeLock.tryLock()) {
try {
// 1 - close exist writer
writer.close();
// 2 - rename to backup file name
//...
// 3 - create new file
FileWriter writerFile = new FileWriter(fileName, true);
writer = new PrintWriter(writerFile);
} finally {
writeLock.unlock();
}
}
}
private synchronized void writeLineWithLock(String line) throws InterruptedException {
readLock.lock();
try {
writer.println(line);
} finally {
readLock.unlock();
}
}
private void openFileWriterWithoutLock() throws IOException {
// 0. Note old file.
PrintWriter oldWriter = writer;
// 1. Create new file.
FileWriter writerFile = new FileWriter(fileName, true);
// 2. Swap the new one in.
writer = new PrintWriter(writerFile);
// 3 - close old writer
oldWriter.close();
}
private synchronized void writeLineWithoutLock(String line) throws InterruptedException {
writer.println(line);
}
您可以在write方法中每小时创建一个新文件。您可能会有一些轻微的时间检查开销,但这应该可以忽略不计。下面的示例将每小时创建一个新的日志文件,并在文件名前面添加以毫秒为单位的时间。您可以根据自己的情况设置时间格式
public class LogWriter {
private long lastCreationTime;
PrintWriter writer;
String logFileName;
public LogWriter(String logFileName) {
this.logFileName = logFileName;
createLogFile(logFileName);
}
private void createLogFile(String fileName) {
if(writer != null) {
writer.close();
}
lastCreationTime = System.currentTimeMillis();
FileWriter writerFile;
try {
writerFile = new FileWriter(lastCreationTime + "_" + fileName, true);
writer = new PrintWriter(writerFile);
} catch (IOException e) {
e.printStackTrace();
}
}
private synchronized void writeLine(String line) {
if(lastCreationTime < System.currentTimeMillis() - 3600000) {
createLogFile(logFileName);
}
writer.write(line);
}
}
公共类日志编写器{
私人长时间创作;
版画作家;
字符串日志文件名;
公共日志编写器(字符串日志文件名){
this.logFileName=logFileName;
创建日志文件(日志文件名);
}
私有void createLogFile(字符串文件名){
if(writer!=null){
writer.close();
}
lastCreationTime=System.currentTimeMillis();
文件编写器写入文件;
试一试{
writerFile=新文件编写器(lastCreationTime+“”+文件名,true);
writer=新的PrintWriter(writerFile);
}捕获(IOE异常){
e、 printStackTrace();
}
}
专用同步无效写入线(字符串行){
如果(lastCreationTime
让一个单独的线程来处理日志记录,而不是那个相当复杂的构造,怎么样
public class Logger extends Thread {
private final LinkedBlockingQueue<String> linesToWrite = new LinkedBlockingQueue<>();
private final String filename;
private Logger(String filename) {
super("Logging thread");
this.filename = filename;
this.setDaemon(true);
this.setPriority(Thread.MIN_PRIORITY);
}
@Override
public void run() {
try (BufferedWriter out = new BufferedWriter(new FileWriter(filename, true))) {
String line;
while (this.isInterrupted() == false) {
line = linesToWrite.take();
out.write(line);
out.newLine();
out.flush();
}
} catch (InterruptedException e) {
} catch (IOException ex) {
System.out.println("Failed to access log file: " + ex);
}
}
public void log(final String line) {
this.linesToWrite.add(line);
}
然后,您可以在任何地方以线程安全的方式使用它,如下所示:
logger.log("Test message");
logger.interrupt();
您不需要停止记录器,因为Java将使用try构造确保文件正确关闭。但是,如果您愿意,可以这样停止:
logger.log("Test message");
logger.interrupt();
现在,您可以通过单线程方式执行所有文件操作,因为任何时候都只有一个线程访问日志文件。像logback这样的日志框架可以为您完成所有这一切,开箱即用是,但logback不知道每1小时创建一个文件,甚至没有人写入它-空文件你说得对,但我如何知道我的对象PrintWriter是否未关闭?我不想丢失这一行,我想把它写到文件中,如果你关闭了它,文件只会被关闭。除了单元测试之外,我不会关闭该文件,而是继续刷新输出。如果您想知道PrintWriter是否出错,可以检查PrintWriter.checkError(),或者可以使用BufferedWriter,它会引发IOException。是的,但我希望每1小时创建一个文件,即使没有人写入它-空file@user2143023-如果没有人对文件进行写入,则会使文件保持打开状态超过一小时,但一旦有人这样做,它就会创造一个新的。你永远不会在一个文件中写入超过一小时的数据。