1 /******************************************************************************
2 *
3 * Copyright (C) 2005, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * ID: samefiles 17.10.06 0.0.A.
11 *
12 * Author: Alexey Krivonogov ( gentee )
13 *
14 ******************************************************************************/
15
16 type finf
17 {
18 str name
19 uint size
20 uint owner
21 }
22
23 global
24 {
25 arr dirs of finf
26 arr files of finf
27 arr sizes of uint
28 str output
29 }
30
31 func uint newdir( str name, uint owner )
32 {
33 uint i
34
35 i = dirs.expand( 1 )
36 dirs[ i ].name = name
37 dirs[ i ].owner = owner
38 return i
39 }
40
41 func uint newfile( str name, uint size owner )
42 {
43 uint i
44
45 i = files.expand( 1 )
46 files[ i ].name = name
47 files[ i ].size = size
48 files[ i ].owner = owner
49 return i
50 }
51
52 func scanfolder( str wildcard, uint owner )
53 {
54 ffind fd
55
56 fd.init( wildcard, $FIND_FILE | $FIND_DIR )
57 foreach cur, fd
58 {
59 if cur.attrib & $FILE_ATTRIBUTE_DIRECTORY
60 {
61 scanfolder( cur.fullname + "\\*.*", newdir( cur.name, owner ))
62 }
63 elif !cur.sizehi : newfile( cur.name, cur.sizelo, owner )
64 }
65 }
66
67 func scaninit( str folder )
68 {
69 str wildcard
70
71 folder.fdelslash()
72 @"Scanning \( folder )\n"
73 scanfolder( (wildcard = folder ).faddname( "*.*" ), newdir( folder, 0 ))
74 }
75
76 func int sortsize( uint left right )
77 {
78 return int( files[ left->uint ].size ) - int( files[ right->uint ].size )
79 }
80
81 func sortfiles
82 {
83 uint i
84
85 @"Sorting...\n"
86 sizes.expand( *files )
87 fornum i, *sizes : sizes[ i ] = i
88
89 sizes.sort( &sortsize )
90 }
91
92 func str getdir( uint id, str ret )
93 {
94 uint owner = dirs[ id ].owner
95
96 if owner : getdir( owner, ret )
97 return ret.faddname( dirs[ id ].name )
98 }
99
100 func str getfile( uint id, str ret )
101 {
102 ret.clear()
103
104 getdir( files[ id ].owner, ret )
105 return ret.faddname( files[ id ].name )
106 }
107
108 func compare
109 {
110 uint i id next j found count
111 str idname nextname
112
113 @"Looking for duplicates...\n"
114
115 fornum i, *sizes - 1
116 {
117 id = sizes[ i ]
118
119 if !*files[ id ].name : continue
120
121 found = 0
122 next = sizes[ j = i + 1 ]
123
124 while files[ id ].size == files[ next ].size
125 {
126 if *files[ next ].name &&
127 isequalfiles( getfile( id, idname ), getfile( next, nextname ))
128 {
129 if !found
130 {
131 output @ "\lSize: \(files[ id ].size) ========\l\( idname )\l"
132 }
133 count++
134 ( output @ nextname ) @"\l"
135
136 found = 1
137 files[ next ].name.clear()
138 }
139 if ++j == *sizes : break
140 next = sizes[ j ]
141 }
142 if i && !( i & 0x3F )
143 {
144 @ "\rApproved files: \(i) Found the same files: \(count)"
145 }
146 }
147 output @ "\l=================\lApproved files: \(*files) Found the same files: \(count)\l"
148 }
149
150 func init
151 {
152 dirs.reserve( 1000 )
153 files.reserve( 20000 )
154 output.reserve( 1000000 )
155 dirs.expand( 1 )
156 }
157
158 func search
159 {
160 @"All files : \( *files )\n"
161
162 if !*files : return
163 sortfiles()
164 compare()
165 output.write("samefiles.txt")
166 shell( "samefiles.txt" )
167 }
168
169 func main<main>
170 {
171 str folder
172
173 init()
174
175 congetstr("Specify a folder or a drive (C:) for searching: \n", folder )
176 scaninit( folder )
177 search()
178 }
Редактировать