大家好我有一个字典,必须在两个不同的exe文件之间共享。第一个应用程序创建一个密钥,然后将其存储在字典中,然后另一个应用程序创建一个密钥并将其存储在字典中。
目前我这样做:
private static void WriteToFile(Dictionary<string, byte[]> dictionary, string path)
{
Contract.Requires(dictionary != null);
Contract.Requires(!string.IsNullOrEmpty(path));
if (!(timestamp == File.GetLastWriteTime(DatabasePath)))
{
using (FileStream fs = File.OpenWrite(path))
using (var writer = new BinaryWriter(fs))
{
// Put count.
writer.Write(dictionary.Count);
// Write pairs.
foreach (var pair in dictionary)
{
writer.Write(pair.Key);
writer.Write(pair.Value);
}
timestamp = DateTime.Now;
File.SetLastWriteTime(DatabasePath, timestamp);
}
}
}
/// <summary>
/// This is used to read a dictionary from a file
/// http://www.dotnetperls.com/dictionary-binary
/// </summary>
/// <param name="path">The path to the file</param>
/// <returns>The dictionary read from the file</returns>
private static Dictionary<string, byte[]> ReadFromFile(string path)
{
Contract.Requires(!string.IsNullOrEmpty(path));
var result = new Dictionary<string, byte[]>();
using (FileStream fs = File.OpenRead(path))
using (var reader = new BinaryReader(fs))
{
// Determine the amount of key value pairs to read.
int count = reader.ReadInt32();
// Read in all the pairs.
for (int i = 0; i < count; i++)
{
string key = reader.ReadString();
//// The byte value is hardcoded as the keysize is consistent
byte[] value = reader.ReadBytes(513);
result[key] = value;
}
}
return result;
}
然后,当我想存储一个密钥时,我称之为:
public static bool StoreKey(byte[] publicKey, string uniqueIdentifier)
{
Contract.Requires(ValidPublicKeyBlob(publicKey));
Contract.Requires(publicKey != null);
Contract.Requires(uniqueIdentifier != null);
Contract.Requires(uniqueIdentifier != string.Empty);
bool success = false;
if (File.Exists(DatabasePath))
{
keyCollection = ReadFromFile(DatabasePath);
}
if (!keyCollection.ContainsKey(uniqueIdentifier))
{
if (!keyCollection.ContainsValue(publicKey))
{
keyCollection.Add(uniqueIdentifier, publicKey);
success = true;
WriteToFile(keyCollection, DatabasePath);
}
}
return success;
}
当程序生成密钥时,当我们尝试访问它们时,它只有1个密钥,我做错了什么?键和字符串存储得很完美,但我只是担心它们会覆盖文件或其他东西。
非常感谢您,非常感谢任何帮助
PS:databasePath是我想要保存文件的路径,创建为字段。
答案 0 :(得分:3)
由于您未提供有关字典中有多少项目等的信息,因此很难说究竟发生了什么,但您似乎遇到了某种文件访问问题从多个进程访问同一文件。
您可以使用命名的Mutex作为跨进程同步对象,因此在访问文件之前,您必须确保释放Mutex句柄,以便您可以获取所有权,其他进程可以在访问之前等待文件。
// Create a mutex
Mutex mutex = new Mutex(false, "DictionaryAccessMutex");
// Acquire an ownership
mutex.WaitOne();
// Release
mutex.ReleaseMutex();
编辑:新发现
此外,您尝试在读取后立即写入,因此可能FileSystem操作尚未完成,因此写入失败,我不确定100%在这个可能的.NET托管类中,如File / StreamReader / etc已经处理过案件,但我认为值得仔细检查你的情况,因为不是100%清楚发生了什么。因此,请尝试在读取和写入操作之间添加一些超时,如Thread.Sleep(500)
。
编辑:您可以做的另一件事是下载Process Monitor SysInternals utility并查看在访问给定文件时哪些操作失败。所以只需添加一个新的过滤器Path=file name
,您就可以看到低级别的内容。
答案 1 :(得分:2)
并行写入文件通常不是最好的主意。你有两个选择:
答案 2 :(得分:0)
因此,Process 1加载字典,添加项目,调用write。 因此,Process 2加载字典,添加一个项目,调用write。
你得到的是第二个写的,你不知道它会是哪一个。
尝试使这项工作比它的价值更麻烦,它将作为充气飞镖的未来证明。
Mutex在推送或第三个进程中维护字典。