我的问题是这样的:
我编写了一个客户端 HTTP 缓存,我需要以某种方式将 HTTP 有效负载存储在文件系统中。我不想用不必要的文件弄乱文件系统。
我写了这个类:
/* * 版权所有 (c) 2008,The Codehaus。版权所有。 * * 根据 Apache 许可证 2.0 版(“许可证”)获得许可; * 除非遵守许可,否则您不得使用此文件。 * 您可以在以下网址获取许可证的副本 * http://www.apache.org/licenses/LICENSE-2.0 * * 除非适用法律要求或书面同意,否则软件 *根据许可分发是在“原样”基础上分发的, * 不提供任何明示或暗示的保证或条件。 * 请参阅许可证以了解特定语言的管理权限和 * 许可证下的限制。 * */ 包 org.codehaus.httpcache4j.cache; 导入 org.apache.commons.lang.Validate; 导入 org.apache.commons.io.filefilter.AndFileFilter; 导入 org.apache.commons.io.filefilter.DirectoryFileFilter; 导入 org.apache.commons.io.filefilter.RegexFileFilter; 导入 org.codehaus.httpcache4j.util.DeletingFileFilter; 导入java.io.File; 导入 java.io.FileFilter; 导入 java.io.Serializable; 导入 java.util.ArrayList; 导入 java.util.Arrays; 导入 java.util.Collections; 导入 java.util.List; /** * 这个类是内部的,不应该被客户端使用。 * * 负责创建和维护文件生成的“池”。
* 文件在被访问时被提升,因此我们可以确定哪些文件可以删除。
* 已知问题:这需要与存储引擎的大小同步。
* 如果缓存中有很多项目时生成的代数太少,则可能 * 当您尝试访问它们时会丢失一些文件。 * * Despot 的注释:我正在研究另一种存储文件的方式,所以这个类可能会在某个时候消失, * 或更改为其他形式。 * */ 类 FileGenerationManager 实现 Serializable{ 私有静态最终长序列版本UID = -1558644426181861334L; 私有最终文件基目录; 私人最终 int generationSize; 私人最终 int numberOfGenerations; private final FileFilter generationFilter; 公共 FileGenerationManager(最终文件 baseDirectory,最终 int numberOfGenerations){ 这(baseDirectory,numberOfGenerations,100); } 公共 FileGenerationManager(最终文件 baseDirectory,最终 int numberOfGenerations,最终 int generationSize){ Validate.isTrue(numberOfGenerations > 0, "你不能创建 0 代"); Validate.notNull(baseDirectory, "你可能没有一个空的基本目录"); if (!baseDirectory.exists()) { Validate.isTrue(baseDirectory.mkdirs(), "无法创建基本目录:" + baseDirectory); } this.baseDirectory = baseDirectory; this.generationSize = generationSize; this.numberOfGenerations = numberOfGenerations; generationFilter = new AndFileFilter(DirectoryFileFilter.DIRECTORY, new RegexFileFilter("[0-9]*")); getGenerations(); } /** * 在基本目录中创建几代目录。 * * @return 创建的世代。 */ //TODO: 这个重吗? //TODO: 当我们错过 getFile() 时,也许我们应该这样做? 公共同步列表 getGenerations() { 最终列表世代 = new ArrayList(); //处理现有的世代... 文件[] 目录 = baseDirectory.listFiles(generationFilter); 如果(目录.长度> 0){ 对于(文件目录:目录){ generation.add(new Generation(baseDirectory, Integer.parseInt(directory.getName()))); } } 别的 { generation.add(new Generation(baseDirectory, 1)); } Collections.sort(世代); 一代 currentGeneration = generation.get(0); if (currentGeneration.getGenerationDirectory().list().length > generationSize) { generation.add(0, new Generation(baseDirectory, currentGeneration.getSequence() + 1)); removeLastGeneration(世代); } 而 (generations.size() > numberOfGenerations) { removeLastGeneration(世代); } 返回 Collections.unmodifiableList(generations); } 私人无效removeLastGeneration(列表世代){ if (generations.size() > numberOfGenerations) { 一代一代=generations.remove(generations.size() - 1); 代.删除(); } } /** * 返回最近创建的一代 * * @return 具有最高序列号的世代 */ 同步生成 getCurrentGeneration() { 返回 getGenerations().get(0); } 公共同步文件getFile(字符串文件名){ 文件目标 = new File(getCurrentGeneration().getGenerationDirectory(), fileName); for (世代: getGenerations()) { 候选文件 = new File(generation.getGenerationDirectory(), fileName); if (candidate.exists()) { if (!target.equals(candidate)) { //因为; http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4017593 目标.删除(); if (!candidate.renameTo(target)) { 返回候选人; } 别的 { 休息; } } } } 返回目标; } 静态类生成实现 Comparable { 私有文件生成目录; 私有 int 序列; public Generation(final File baseDir, final int generationNumber) { Validate.notNull(baseDir, "生成目录不能为空"); 文件 genFile = new File(baseDir, String.valueOf(generationNumber)); genFile.mkdirs(); this.generationDirectory = genFile; this.sequence = generationNumber; } 公共同步无效删除(){ File[] undeleteableFiles = generationDirectory.listFiles(new DeletingFileFilter()); if (undeleteableFiles == null || undeleteableFiles.length == 0) { generationDirectory.delete(); } 别的 { System.err.println("无法删除这些文件:" + Arrays.toString(undeleteableFiles)); } } 公共文件getGenerationDirectory(){ 返回生成目录; } 公共 int getSequence() { 返回序列; } public int compareTo(一代){ return 1 - (sequence - generation.sequence); } } }
问题是有时文件没有移动到正确的文件夹,我可能会泄漏文件描述符。
您对如何改善这一点有什么建议吗?
这可能有标准解决方案吗?不分语言?
这也很慢,欢迎提高速度。