提交 73ef660f authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add support for AutoCloseable objects to TempFileDeleter

上级 bc78d7a3
...@@ -21,7 +21,7 @@ import org.h2.store.fs.FileUtils; ...@@ -21,7 +21,7 @@ import org.h2.store.fs.FileUtils;
public class TempFileDeleter { public class TempFileDeleter {
private final ReferenceQueue<Object> queue = new ReferenceQueue<>(); private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
private final HashMap<PhantomReference<?>, String> refMap = new HashMap<>(); private final HashMap<PhantomReference<?>, Object> refMap = new HashMap<>();
private TempFileDeleter() { private TempFileDeleter() {
// utility class // utility class
...@@ -32,40 +32,47 @@ public class TempFileDeleter { ...@@ -32,40 +32,47 @@ public class TempFileDeleter {
} }
/** /**
* Add a file to the list of temp files to delete. The file is deleted once * Add a file or a closeable to the list of temporary objects to delete. The
* the file object is garbage collected. * file is deleted once the file object is garbage collected.
* *
* @param fileName the file name * @param resource the file name or the closeable
* @param file the object to monitor * @param monitor the object to monitor
* @return the reference that can be used to stop deleting the file * @return the reference that can be used to stop deleting the file or closing the closeable
*/ */
public synchronized Reference<?> addFile(String fileName, Object file) { public synchronized Reference<?> addFile(Object resource, Object monitor) {
IOUtils.trace("TempFileDeleter.addFile", fileName, file); if (!(resource instanceof String) && !(resource instanceof AutoCloseable)) {
PhantomReference<?> ref = new PhantomReference<>(file, queue); throw DbException.getUnsupportedException("Unsupported resource " + resource);
refMap.put(ref, fileName); }
IOUtils.trace("TempFileDeleter.addFile",
resource instanceof String ? (String) resource : "-", monitor);
PhantomReference<?> ref = new PhantomReference<>(monitor, queue);
refMap.put(ref, resource);
deleteUnused(); deleteUnused();
return ref; return ref;
} }
/** /**
* Delete the given file now. This will remove the reference from the list. * Delete the given file or close the closeable now. This will remove the
* reference from the list.
* *
* @param ref the reference as returned by addFile * @param ref the reference as returned by addFile
* @param fileName the file name * @param resource the file name or closeable
*/ */
public synchronized void deleteFile(Reference<?> ref, String fileName) { public synchronized void deleteFile(Reference<?> ref, Object resource) {
if (ref != null) { if (ref != null) {
String f2 = refMap.remove(ref); Object f2 = refMap.remove(ref);
if (f2 != null) { if (f2 != null) {
if (SysProperties.CHECK) { if (SysProperties.CHECK) {
if (fileName != null && !f2.equals(fileName)) { if (resource != null && !f2.equals(resource)) {
DbException.throwInternalError("f2:" + f2 + " f:" + fileName); DbException.throwInternalError("f2:" + f2 + " f:" + resource);
} }
} }
fileName = f2; resource = f2;
} }
} }
if (fileName != null && FileUtils.exists(fileName)) { if (resource instanceof String) {
String fileName = (String) resource;
if (FileUtils.exists(fileName)) {
try { try {
IOUtils.trace("TempFileDeleter.deleteFile", fileName, null); IOUtils.trace("TempFileDeleter.deleteFile", fileName, null);
FileUtils.tryDelete(fileName); FileUtils.tryDelete(fileName);
...@@ -73,20 +80,29 @@ public class TempFileDeleter { ...@@ -73,20 +80,29 @@ public class TempFileDeleter {
// TODO log such errors? // TODO log such errors?
} }
} }
} else if (resource instanceof AutoCloseable) {
AutoCloseable closeable = (AutoCloseable) resource;
try {
IOUtils.trace("TempFileDeleter.deleteCloseable", "-", null);
closeable.close();
} catch (Exception e) {
// TODO log such errors?
}
}
} }
/** /**
* Delete all registered temp files. * Delete all registered temp resources.
*/ */
public void deleteAll() { public void deleteAll() {
for (String tempFile : new ArrayList<>(refMap.values())) { for (Object resource : new ArrayList<>(refMap.values())) {
deleteFile(null, tempFile); deleteFile(null, resource);
} }
deleteUnused(); deleteUnused();
} }
/** /**
* Delete all unused files now. * Delete all unused resources now.
*/ */
public void deleteUnused() { public void deleteUnused() {
while (queue != null) { while (queue != null) {
...@@ -99,20 +115,21 @@ public class TempFileDeleter { ...@@ -99,20 +115,21 @@ public class TempFileDeleter {
} }
/** /**
* This method is called if a file should no longer be deleted if the object * This method is called if a file should no longer be deleted or a resource
* is garbage collected. * should no longer be closed if the object is garbage collected.
* *
* @param ref the reference as returned by addFile * @param ref the reference as returned by addFile
* @param fileName the file name * @param resource file name or closeable
*/ */
public void stopAutoDelete(Reference<?> ref, String fileName) { public void stopAutoDelete(Reference<?> ref, Object resource) {
IOUtils.trace("TempFileDeleter.stopAutoDelete", fileName, ref); IOUtils.trace("TempFileDeleter.stopAutoDelete",
resource instanceof String ? (String) resource : "-", ref);
if (ref != null) { if (ref != null) {
String f2 = refMap.remove(ref); Object f2 = refMap.remove(ref);
if (SysProperties.CHECK) { if (SysProperties.CHECK) {
if (f2 == null || !f2.equals(fileName)) { if (f2 == null || !f2.equals(resource)) {
DbException.throwInternalError("f2:" + f2 + DbException.throwInternalError("f2:" + f2 +
" " + (f2 == null ? "" : f2) + " f:" + fileName); " " + (f2 == null ? "" : f2) + " f:" + resource);
} }
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论