【发布时间】:2019-06-05 10:57:33
【问题描述】:
在对 dcm4che3 和 dicom 协议进行一些研究后,重新表述我的原始帖子。
我正在使用 dcm4che3 工具包构建一个应用程序,该应用程序本质上将是一个简单的Image Archive,能够按需将研究转发到其他模式。该工具还实现了一个 s-store scu 服务来查询自身以及其他模式.
要求是能够定期从该本地档案中“删除”研究。
我也是 dicom 协议和 dcm4che 的新手,因此我试图了解底层 dicomdir(由 dcm4che-tool-dcmqrscp 使用)的逻辑以及用于删除研究的任何可用服务或方法。
所以我的问题如下:
在 dicom 协议的上下文中,“删除研究”一词是否有效?
正如我在删除研究时看到的“dcm4che-tool-dcmdir”(使用该工具),实际发生的是“删除引用文件指定的 DICOM 文件的记录..或目录..来自现有目录的参数通过将其 Record In-use Flag = 0" 设置为文件,以便文件保留在文件系统中。
当我使用 c-find scu 查询存档时,如果我尝试以这种方式删除研究(tool-dicomdir 中的 -d 选项),我可以找到该研究。因此,即使 dicomdir 中的记录被标记为 Inactive,如果我对存档执行 c-find 查询,我仍然可以获取它。
如果我尝试从文件系统中手动删除研究文件,我猜 dicomdir 已损坏。
是否有任何其他方法(或协议的一部分)以一致的方式从 dicomdir 中删除研究(永久从 dicomdir 记录,但如果可能,也从文件系统中)?
我用来删除研究的代码(使用与 dicomdir 中的 -d 选项类似的方法)是:
public void deleteDicomDir(String studyDir) throws IOException {
DcmDir1 main = new DcmDir1();
long start = System.currentTimeMillis();
LOG.info("$$$ Trying to delete dicomdir: " + studyDir);
main.open(new File("C:\\dicomrouter_dev\\dcmrouter_root\\dicomdir"));
main.removeReferenceTo(new File(studyDir));
main.close();
long end = System.currentTimeMillis();
System.out.println();
System.out.println(MessageFormat.format(
rb.getString("deleted"),
num, main.getFile(), (end - start)));
}
“removeReferenceTo()”方法实际上是在最后调用 DicomDirWritter 方法:
public synchronized boolean deleteRecord(Attributes rec)
throws IOException {
if (rec.getInt(Tag.RecordInUseFlag, 0) == INACTIVE)
return false; // already disabled
for (Attributes lowerRec = readLowerDirectoryRecord(rec);
lowerRec != null;
lowerRec = readNextDirectoryRecord(lowerRec))
deleteRecord(lowerRec);
rec.setInt(Tag.RecordInUseFlag, VR.US, INACTIVE);
markAsDirty(rec);
return true;
}
感谢您抽出宝贵的时间,我期待任何可以声明这一点的信息
实际上,在对 dicom 协议以及 dcm4che 工具包进行了一些研究之后,我能够通过 3 个步骤删除一项研究并同步我的 DICOMDIR 并删除 Record In-use Flag = 0 的研究(或文件):
//delete records referring DICOM files specified by <directory:studyDir> arguments from existing directory file <dicomdir> by setting its Record In-use Flag = 0
public void deleteDicomDir(String studyDir) {
String dicomdir = "C:\\dicomrouter_dev\\dcmrouter_root\\DICOMDIR";
DcmDir1 main = new DcmDir1();
long start = System.currentTimeMillis();
try {
LOG.info("$$$ Trying to delete dicomdir: " + studyDir);
main.open(new File(dicomdir));
int num = 0;
main.removeReferenceTo(new File(studyDir));
main.close();
long end = System.currentTimeMillis();
System.out.println();
System.out.println(MessageFormat.format(
rb.getString("deleted"),
num, main.getFile(), (end - start)));
} catch (IOException ex) {
java.util.logging.Logger.getLogger(DcmDir1.class.getName()).log(Level.SEVERE, null, ex);
} finally {
main.close();
}
}
//purge records without file references from directory file <dicomdir> by setting its Record In-use Flag = 0
public void purgeDicomDir() {
String dicomdir = "C:\\dicomrouter_dev\\dcmrouter_root\\DICOMDIR";
DcmDir1 main = new DcmDir1();
long start = System.currentTimeMillis();
try {
main.open(new File(dicomdir));
int num = main.purge();
main.close();
long end = System.currentTimeMillis();
System.out.println(MessageFormat.format(
rb.getString("purged"),
num, main.getFile(), (end - start)));
} catch (IOException ex) {
java.util.logging.Logger.getLogger(DcmDir1.class.getName()).log(Level.SEVERE, null, ex);
} finally {
main.close();
}
}
//compact existing directory file <dicomdir> by removing records with Record In-use Flag != 0
public void compactDicomDir() {
String fpath = "C:\\dicomrouter_dev\\dcmrouter_root\\DICOMDIR";
File f = new File(fpath);
File bak = new File(fpath + "~");
DcmDir1 main = new DcmDir1();
long start = System.currentTimeMillis();
try {
LOG.info("$$$ Trying to compact dicomdir: " + fpath);
main.compact(f, bak);
long end = System.currentTimeMillis();
System.out.println(MessageFormat.format(
rb.getString("compacted"),
f, bak.length(), f.length(), (end - start)));
} catch (IOException ex) {
java.util.logging.Logger.getLogger(DcmDir1.class.getName()).log(Level.SEVERE, null, ex);
} finally {
main.close();
}
}
然后我也可以安全地从磁盘中删除文件。
【问题讨论】: