【发布时间】:2014-09-18 08:07:11
【问题描述】:
目前我正在编写一个小程序来检查文件是否在数据库中。此外,我检查数据库中的哈希是否已正确计算(此处:sha256)。文件名是文件中的(旧的并且可能是错误的)sha。
为了更好地理解小型工作流程:
- 从(子)目录(dir)获取文件
- 从文件计算 sha256 (shaNEW)
-
检查文件名(shaOLD)是否在数据库中
a) 在数据库中:检查是否 shaOLD = shaNEW(如果 sha 相等:移动到 dir_inDB;如果不是:在 DB 中更新,重命名并移动到 dir_inDB)
b) 不在数据库中:检查 shaOLD = shaNEW(如果 sha 相等:移动到 dir_NOTinDB;如果不是:重命名并移动到 dir_NOTinDB - 不要添加到数据库)
我正在像这样访问/获取 sourceFile:
public static void checkFiles(File file) throws NoSuchAlgorithmException, IOException
{
for (File sourceFile : file.listFiles())
{
if (sourceFile.isDirectory())
{
checkFiles(sourceFile);
}
else
{
// compute sha, check db, move, rename and so on
}
}
}
destinationFile 如下:
File destinationFile = null;
String fileName = sourceFile.getAbsolutePath();
shaNEW = Hash.SHA256(fileName);
char[] c = shaNEW.toCharArray();
String path = sourceFile.getAbsolutePath();
path = path.substring(0, path.lastIndexOf("\\") - 5) + c[0] + c[1] + "\\" + c[2] + c[3] + "\\" + shaNEW;
path = path.replace("dir", "dir_new"); // dir_new = dir_inDB resp. dir_NOTinDB
destinationFile = new File(path);
我的问题是:移动文件后,我想删除旧目录(dir)中的文件[但不是(子)目录本身]。移动也可以正常工作并删除(但仅在第一次)。但是从第二次开始源文件不会被删除。我正在这样移动/删除:
FileUtils.copyFile(sourceFile, destinationFile);
sourceFile.delete();
(除了自己构建的,我没有收到任何错误或异常)
我也试过
FileUtils.move(sourceFile, destinationFile);
但后来我(有时)得到一个 IOException(无法删除源文件)
有人知道为什么sourceFile.delete() 只能在第一次使用吗?
在此先致谢并致以最诚挚的问候,
久志
编辑:
我更喜欢像这样移动文件(而不是复制和删除):FileUtils.moveFile(sourceFile, destinationFile);
但它会抛出一个 IOExeption:
线程 "main" java.io.IOException 中的异常:复制到 .. 后无法删除原始文件 ...\dir\c [0]c[1]\c[2]c[3]\shaOLD .\dir_inDB\c[0]c[1]\c[0]c[1]\shaNEW
在 org.apache.commons.io.FileUtils.moveFile(FileUtils.java:2835) 在 metadatacheck.DatabaseCleanup.checkFiles(DatabaseCleanup.java:264) 在 metadatacheck.DatabaseCleanup.checkFiles(DatabaseCleanup.java:225) 在 metadatacheck.DatabaseCleanup.checkFiles(DatabaseCleanup.java:225) 在 metadatacheck.DatabaseCleanup.main(DatabaseCleanup.java:49)
DatabaseCleanup.java:264:FileUtils.moveFile(sourceFile, destinationFile);
DatabaseCleanup.java:225:checkFiles(sourceFile)(功能:见上文)
DatabaseCleanup.java:49:checkFiles(dir);
EDIT2:
现在我尝试了sourceFile.renameTo(destinationFile);,但这里没有执行函数renameTo()(我使用了一个简单的 if-else 来检查 renameTo() 是否已执行)。
EDIT3:(散列函数)
public static String SHA256(String path) throws FileNotFoundException, NoSuchAlgorithmException, IOException
{
MessageDigest md = MessageDigest.getInstance("SHA-256");
FileInputStream fis = new FileInputStream(path);
byte[] dataBytes = new byte[1024];
int nread = 0;
while ((nread = fis.read(dataBytes)) != -1)
{
md.update(dataBytes, 0, nread);
}
byte[] mdbytes = md.digest();
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < mdbytes.length; i++)
{
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
}
String sha256 = sb.toString();
return sha256;
}
【问题讨论】:
-
请注意,
delete()在失败时返回 false;它不会抛出异常。关于您的问题,文件是否打开? -
#copyFile()方法有什么作用?也许有一个流是打开的,这就解释了为什么只工作一次。 -
文件甚至没有被触及。我只是获取源文件的名称(sourceFile.getName())和路径(source.File.getAbsolutePath())并将其保存到另一个字符串,检查它是否是一个目录(sourceFile.isDirectory()),并且在结束,尝试删除它。所以我不在任何地方打开文件。 FileUtils.copyFile(source, dest) 复制 - 顾名思义 - 源到 dest(它来自 apache common io)。
-
@immibis 能回答你的问题吗?
-
@CristianSulea 我的哈希函数中有一个流。我在我的问题中编辑了它。你认为这会导致我的问题吗?