Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
bb7d7886
提交
bb7d7886
authored
12 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Tool to detect duplicate files
上级
5f3ca200
master
noel-pr1
plus33-master
pr/267
stumc-Issue#576
version-1.4.198
version-1.4.197
version-1.4.196
version-1.4.195
version-1.4.194
version-1.4.193
version-1.4.192
version-1.4.191
version-1.4.190
version-1.4.188
version-1.4.187
version-1.4.186
version-1.4.185
version-1.4.184
version-1.4.183
version-1.4.182
version-1.4.181
version-1.4.178
version-1.4.177
version-1.3
无相关合并请求
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
172 行增加
和
1 行删除
+172
-1
FileContentHash.java
h2/src/tools/org/h2/dev/util/FileContentHash.java
+172
-0
FileViewer.java
h2/src/tools/org/h2/dev/util/FileViewer.java
+0
-1
没有找到文件。
h2/src/tools/org/h2/dev/util/FileContentHash.java
0 → 100644
浏览文件 @
bb7d7886
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
dev
.
util
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.util.New
;
import
org.h2.util.SortedProperties
;
import
org.h2.util.StringUtils
;
/**
* A utility to calculate the content hash of files. It should help detect
* duplicate files and differences between directories.
*/
public
class
FileContentHash
{
// find empty directories:
// find . -type d -empty
// find . -name .hash.prop -delete
private
static
final
boolean
WRITE_HASH_INDEX
=
true
;
private
static
final
String
HASH_INDEX
=
".hash.prop"
;
private
static
final
int
MIN_SIZE
=
0
;
private
HashMap
<
String
,
String
>
hashes
=
New
.
hashMap
();
private
long
nextLog
;
/**
* Run the viewer.
*
* @param args the command line arguments
*/
public
static
void
main
(
String
...
args
)
throws
IOException
{
new
FileContentHash
().
runTool
(
args
);
}
private
void
runTool
(
String
...
args
)
throws
IOException
{
if
(
args
.
length
==
0
)
{
System
.
out
.
println
(
"Usage: java "
+
getClass
().
getName
()
+
" <dir>"
);
return
;
}
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
Info
info
=
hash
(
args
[
i
]);
System
.
out
.
println
(
"size: "
+
info
.
size
);
}
}
private
static
MessageDigest
createMessageDigest
()
{
try
{
return
MessageDigest
.
getInstance
(
"SHA-256"
);
}
catch
(
NoSuchAlgorithmException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
private
Info
hash
(
String
path
)
throws
IOException
{
if
(
FileUtils
.
isDirectory
(
path
))
{
long
totalSize
=
0
;
SortedProperties
propOld
;
SortedProperties
propNew
=
new
SortedProperties
();
String
hashFileName
=
path
+
"/"
+
HASH_INDEX
;
if
(
FileUtils
.
exists
(
hashFileName
))
{
propOld
=
SortedProperties
.
loadProperties
(
hashFileName
);
}
else
{
propOld
=
new
SortedProperties
();
}
List
<
String
>
list
=
FileUtils
.
newDirectoryStream
(
path
);
Collections
.
sort
(
list
);
MessageDigest
mdDir
=
createMessageDigest
();
for
(
String
f
:
list
)
{
String
name
=
FileUtils
.
getName
(
f
);
if
(
name
.
equals
(
HASH_INDEX
))
{
continue
;
}
long
length
=
FileUtils
.
size
(
f
);
String
entry
=
"name_"
+
name
+
"-mod_"
+
FileUtils
.
lastModified
(
f
)
+
"-size_"
+
length
;
String
hash
=
propOld
.
getProperty
(
entry
);
if
(
hash
==
null
||
FileUtils
.
isDirectory
(
f
))
{
Info
info
=
hash
(
f
);
byte
[]
b
=
info
.
hash
;
hash
=
StringUtils
.
convertBytesToHex
(
b
);
totalSize
+=
info
.
size
;
entry
=
"name_"
+
name
+
"-mod_"
+
FileUtils
.
lastModified
(
f
)
+
"-size_"
+
info
.
size
;
}
else
{
totalSize
+=
length
;
checkCollision
(
f
,
length
,
StringUtils
.
convertHexToBytes
(
hash
));
}
propNew
.
put
(
entry
,
hash
);
mdDir
.
update
(
entry
.
getBytes
(
"UTF-8"
));
mdDir
.
update
(
hash
.
getBytes
(
"UTF-8"
));
}
String
oldFile
=
propOld
.
toString
();
String
newFile
=
propNew
.
toString
();
if
(!
oldFile
.
equals
(
newFile
))
{
if
(
WRITE_HASH_INDEX
)
{
propNew
.
store
(
path
+
"/"
+
HASH_INDEX
);
}
}
Info
info
=
new
Info
();
info
.
hash
=
mdDir
.
digest
();
info
.
size
=
totalSize
;
return
info
;
}
MessageDigest
md
=
createMessageDigest
();
InputStream
in
=
FileUtils
.
newInputStream
(
path
);
long
length
=
FileUtils
.
size
(
path
);
byte
[]
buff
=
new
byte
[
1024
*
1024
];
while
(
true
)
{
int
len
=
in
.
read
(
buff
);
if
(
len
<
0
)
{
break
;
}
md
.
update
(
buff
,
0
,
len
);
long
t
=
System
.
nanoTime
();
if
(
nextLog
==
0
||
t
>
nextLog
)
{
System
.
out
.
println
(
"Checking "
+
path
);
nextLog
=
t
+
5000
*
1000000L
;
}
}
in
.
close
();
byte
[]
b
=
md
.
digest
();
checkCollision
(
path
,
length
,
b
);
Info
info
=
new
Info
();
info
.
hash
=
b
;
info
.
size
=
length
;
return
info
;
}
private
void
checkCollision
(
String
path
,
long
length
,
byte
[]
hash
)
{
if
(
length
<
MIN_SIZE
)
{
return
;
}
String
s
=
StringUtils
.
convertBytesToHex
(
hash
);
String
old
=
hashes
.
get
(
s
);
if
(
old
!=
null
)
{
System
.
out
.
println
(
"Collision: "
+
old
+
"\n"
+
path
+
"\n"
);
}
else
{
hashes
.
put
(
s
,
path
);
}
}
/**
* The info for a file.
*/
static
class
Info
{
/**
* The content hash.
*/
byte
[]
hash
;
/**
* The size in bytes.
*/
long
size
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/dev/util/FileViewer.java
浏览文件 @
bb7d7886
...
...
@@ -15,7 +15,6 @@ import java.util.ArrayList;
import
org.h2.message.DbException
;
import
org.h2.util.Tool
;
/**
* A text file viewer that support very large files.
*/
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论