我正在尝试编写一个简单的Windows控制台应用程序,该应用程序将执行以下操作:
为给定文件夹中的每个文件创建一个MD5哈希,并将文件名(包括文件目录)和生成的哈希写入文本文件。 我能够创建哈希并将带有哈希的文件名写入文本文件。 我无法解决的部分是我在文件名的前面加上目录的情况。
一个例子:
我的根目录是C:\temp
在C:\temp
中,我有3个文件:
a.txt
,b.txt
和c.txt
。
此外,C:\temp
中有2个文件夹:
001
和002
001
包含其他3个文件,002
包含一些文件和另一个目录。
粗略地说,我希望我的输出是:
a.txt 1B2M2Y8AsgTpgAmY7PhCfg2
b.txt 8pilZcutPpW5x6atctbWWQ2
c.txt 7wGB3hjvOVGAbArWO4l7pA2
001\d.txt _Uqz2gB17nv1Vxrh-MPrCw2
001\e.txt 1B2M2Y8AsgTpgAmY7PhCfg2
001\f.txt _Uqz2gB17nv1Vxrh-MPrCw2
002\g.txt 1B2M2Y8AsgTpgAmY7PhCfg2
002\h.txt 7wGB3hjvOVGAbArWO4l7pA2
002\test\i.txt _Uqz2gB17nv1Vxrh-MPrCw2
002\test\j.txt 7wGB3hjvOVGAbArWO4l7pA2
我当前的输出是
a.txt 1B2M2Y8AsgTpgAmY7PhCfg2
b.txt 8pilZcutPpW5x6atctbWWQ2
c.txt 7wGB3hjvOVGAbArWO4l7pA2
d.txt _Uqz2gB17nv1Vxrh-MPrCw2
e.txt 1B2M2Y8AsgTpgAmY7PhCfg2
f.txt _Uqz2gB17nv1Vxrh-MPrCw2
g.txt 1B2M2Y8AsgTpgAmY7PhCfg2
h.txt 7wGB3hjvOVGAbArWO4l7pA2
i.txt _Uqz2gB17nv1Vxrh-MPrCw2
j.txt 7wGB3hjvOVGAbArWO4l7pA2
这是我当前的代码。感谢您提出的任何建议或提示,以使我的代码变得更好。
using System;
using System.Linq;
using System.Security.Cryptography;
using System.IO;
using System.Web;
namespace MD5_Generator
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("MD5 Hash Generator");
Console.WriteLine("This program creates MD5 hashes for all files in the folder.");
Console.WriteLine("Work in progress...");
string root = Directory.GetCurrentDirectory();
string hashList = root + "/hashList.txt";
if (!File.Exists(hashList))
{
var initHastListFile = File.Create(hashList);
initHastListFile.Close();
}
else
{
File.Delete(hashList);
var hastListFile = File.Create(hashList);
hastListFile.Close();
}
int i = 0;
string[] allFiles = Directory.GetFiles(root, "*.*", SearchOption.AllDirectories);
string[] lines = new string[allFiles.Count()];
lines = DirSearch(root, lines, i);
File.AppendAllLines(hashList, lines);
Console.ReadKey();
}
static string[] DirSearch(string dir, string[] lines, int counter)
{
string hashListFileName = "hashList.txt";
foreach (string f in Directory.GetFiles(dir))
{
//2. Create an MD5 hash per file
using (var md5 = MD5.Create())
{
FileInfo info = new FileInfo(f);
string filename = info.FullName;
if (filename != hashListFileName)
{
using (var stream = File.OpenRead(filename))
{
byte[] fileMD5 = md5.ComputeHash(stream);
string hash = HttpServerUtility.UrlTokenEncode(fileMD5);
string currDir = Path.GetDirectoryName(filename);
lines[counter] = info.Name + " " + hash;
}
counter++;
}
}
}
foreach (string d in Directory.GetDirectories(dir))
{
DirSearch(d, lines, counter);
}
return lines;
}
}
}
答案 0 :(得分:1)
我猜是这样的
方法
public static IEnumerable<(string fileName, string hash)> GetHasList(string path, bool isRelative)
{
foreach (var file in Directory.GetFiles(path, "*.*", SearchOption.AllDirectories))
{
string hash;
using (var md5 = MD5.Create())
using (var stream = File.OpenRead(file))
hash = HttpServerUtility.UrlTokenEncode(md5.ComputeHash(stream));
if (isRelative)
yield return (file.Remove(0, path.TrimEnd('/').Length+1), hash);
else
yield return (file, hash);
}
}
用法
string output = Path.Combine(@"D:\", "hashList.txt");
// format results
var data = GetHasList(@"D:\Temp",true).Select(x => $"{x.fileName} {x.hash}");
// write file
File.WriteAllLines(output, data);
如果要使其对空间的容错性更高
// format results
var data = GetHasList(@"D:\Temp",true).Select(x => $"\"{x.fileName}\" {x.hash}");
输出
"2284804723016.xml" UBtEG5qItCVKf8VTdamoCQ2
"2301708833016.xml" vRiXj012Q9RlU9xEgZPjcA2
"New folder\2320158695015.xml" hpDYqQuy_wvQMD5tOMJxjA2
"New folder\2282121972016.xml" j-Y06SdEM3kHjbhTIqhTKg2
"New folder (2)\2281419740016.xml" 3GWrCgtrda-W4ymCNSi4MA2
"New folder (2)\2281593123016.xml" ncqGPehpHflpzjl0j0nFfQ2
答案 1 :(得分:0)
我现在用以下代码实现了
using System;
using System.Linq;
using System.Security.Cryptography;
using System.IO;
using System.Web;
namespace MD5_Generator
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("MD5 Hash Generator");
Console.WriteLine("This program creates MD5 hashes for all files in the folder.");
Console.WriteLine("Work in progress...");
string root = Directory.GetCurrentDirectory();
string hashList = root + "/hashList.txt";
if (!File.Exists(hashList))
{
var initHastListFile = File.Create(hashList);
initHastListFile.Close();
}
else
{
File.Delete(hashList);
var hastListFile = File.Create(hashList);
hastListFile.Close();
}
int i = 0;
string[] allFiles = Directory.GetFiles(root, "*.*", SearchOption.AllDirectories);
string[] lines = new string[allFiles.Count()];
lines = DirSearch(root, lines, i, root);
File.AppendAllLines(hashList, lines);
Console.ReadKey();
}
static string[] DirSearch(string dir, string[] lines, int counter, string root)
{
string hashListFileName = "hashList.txt";
foreach (string f in Directory.GetFiles(dir))
{
//2. Create an MD5 hash per file
using (var md5 = MD5.Create())
{
FileInfo info = new FileInfo(f);
string filename = info.FullName;
if (filename != hashListFileName)
{
using (var stream = File.OpenRead(filename))
{
byte[] fileMD5 = md5.ComputeHash(stream);
string hash = HttpServerUtility.UrlTokenEncode(fileMD5);
string currDir = Path.GetDirectoryName(filename);
lines[counter] = info.FullName.Substring(root.Length+1) + " " + hash;
}
counter++;
}
}
}
foreach (string d in Directory.GetDirectories(dir))
{
DirSearch(d, lines, counter, root);
}
return lines;
}
}
}
我只是使用Substring方法来“切除” root
为Directory.GetCurrentDirectory();
的不相关部分:
lines[counter] = info.FullName.Substring(root.Length+1) + " " + hash;
结果看起来就像我想要的一样!
MD5_Generator.exe NVt6BVhZyy0QQPA-Cumntg2
MD5_Generator.exe.config 7wGB3hjvOVGAbArWO4l7pA2
MD5_Generator.pdb _M_l1ka8Jg_c0LOtbXfF6g2
System.ValueTuple.dll mc7Hfb7gqxC5_E1SodQUvg2
System.ValueTuple.xml So9YKXUqAxilrTjfmxgVPQ2
Test\123.txt 1B2M2Y8AsgTpgAmY7PhCfg2
Test\Test2\dhf9.txt 1B2M2Y8AsgTpgAmY7PhCfg2
感谢您的贡献!