Максимальная длина, определенная на поле пароля, должна быть считана как ПРЕДУПРЕЖДЕНИЕ СИСТЕМЫ БЕЗОПАСНОСТИ : Любой разумный, безопасность сознательный пользователь должен принять худшее и ожидать, что этот сайт хранит Ваш пароль буквально (т.е. не хешированный, как объяснено epochwolf).
В том, который имеет место: (a) избегают использования этого сайта как эпидемия, если возможный [они, очевидно, знают гайки о безопасности] (b), если необходимо использовать сайт, удостоверьтесь, что пароль уникален - в отличие от любого пароля, который Вы используете в другом месте.
при разработке сайта, который принимает пароли, не помещайте глупый предел пароля, если Вы не хотите стать одним миром мазаными.
[Внутренне, конечно, Ваш код может рассматривать только первый 256/1028/2k/4k (безотносительно) байтов как "значительный", чтобы не уплотнять на гигантских паролях.]
это очень наивная реализация, но она подходит для моих целей, я видел достаточно людей с этой проблемой в сети, поэтому решил внести свой вклад. Реализация довольно специфична для моих нужд. Я почти полностью не обращал внимания на измененные события, учитывая характер моей проблемы, но люди могут добавить туда свой собственный код, если им нужно сделать что-то другое, это действительно созданный, который вызывает большинство проблем. Я не тестировал это полностью, но сначала напишу, что это выглядит хорошо
using System;
using System.Collections.Generic;
using System.IO;
using System.Timers;
namespace FolderSyncing
{
public class FTPFileSystemWatcher
{
private readonly string _path;
public event FileSystemEventHandler FTPFileCreated;
public event FileSystemEventHandler FTPFileDeleted;
public event FileSystemEventHandler FTPFileChanged;
private Dictionary<string, LastWriteTime> _createdFilesToCheck;
private readonly object _lockObject = new object();
private const int _milliSecondsSinceLastWrite = 5000;
private const int _createdCheckTimerInterval = 2000;
private readonly FileSystemWatcher _baseWatcher;
public FTPFileSystemWatcher(string path, string Filter)
{
_path = path;
_baseWatcher = new FileSystemWatcher(path,Filter);
SetUpEventHandling();
}
public FTPFileSystemWatcher(string path)
{
_path = path;
_baseWatcher = new FileSystemWatcher(path);
SetUpEventHandling();
}
private void SetUpEventHandling()
{
_createdFilesToCheck = new Dictionary<string, LastWriteTime>();
Timer copyTimer = new Timer(_createdCheckTimerInterval);
copyTimer.Elapsed += copyTimer_Elapsed;
copyTimer.Enabled = true;
copyTimer.Start();
_baseWatcher.EnableRaisingEvents = true;
_baseWatcher.Created += _baseWatcher_Created;
_baseWatcher.Deleted += _baseWatcher_Deleted;
_baseWatcher.Changed += _baseWatcher_Changed;
}
void copyTimer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (_lockObject)
{
Console.WriteLine("Checking : " + DateTime.Now);
DateTime dateToCheck = DateTime.Now;
List<string> toRemove = new List<string>();
foreach (KeyValuePair<string, LastWriteTime> fileToCopy in _createdFilesToCheck)
{
FileInfo fileToCheck = new FileInfo(_path + fileToCopy.Key);
TimeSpan difference = fileToCheck.LastWriteTime - fileToCopy.Value.Date;
fileToCopy.Value.Update(fileToCopy.Value.Date.AddMilliseconds(difference.TotalMilliseconds));
if (fileToCopy.Value.Date.AddMilliseconds(_milliSecondsSinceLastWrite) < dateToCheck)
{
FileSystemEventArgs args = new FileSystemEventArgs(WatcherChangeTypes.Created, _path, fileToCopy.Key);
toRemove.Add(fileToCopy.Key);
InvokeFTPFileCreated(args);
}
}
foreach (string removal in toRemove)
{
_createdFilesToCheck.Remove(removal);
}
}
}
void _baseWatcher_Changed(object sender, FileSystemEventArgs e)
{
InvokeFTPFileChanged(e);
}
void _baseWatcher_Deleted(object sender, FileSystemEventArgs e)
{
InvokeFTPFileDeleted(e);
}
void _baseWatcher_Created(object sender, FileSystemEventArgs e)
{
if (!_createdFilesToCheck.ContainsKey(e.Name))
{
FileInfo fileToCopy = new FileInfo(e.FullPath);
_createdFilesToCheck.Add(e.Name,new LastWriteTime(fileToCopy.LastWriteTime));
}
}
private void InvokeFTPFileChanged(FileSystemEventArgs e)
{
FileSystemEventHandler Handler = FTPFileChanged;
if (Handler != null)
{
Handler(this, e);
}
}
private void InvokeFTPFileDeleted(FileSystemEventArgs e)
{
FileSystemEventHandler Handler = FTPFileDeleted;
if (Handler != null)
{
Handler(this, e);
}
}
private void InvokeFTPFileCreated(FileSystemEventArgs e)
{
FileSystemEventHandler Handler = FTPFileCreated;
if (Handler != null)
{
Handler(this, e);
}
}
}
public class LastWriteTime
{
private DateTime _date;
public DateTime Date
{
get { return _date; }
}
public LastWriteTime(DateTime date)
{
_date = date;
}
public void Update(DateTime dateTime)
{
_date = dateTime;
}
}
}
вот реализация для синхронизации
using System;
using System.Configuration;
using System.IO;
using System.Threading;
namespace FolderSyncing
{
public class FolderSync
{
private readonly string masterDirectoryPath;
private readonly string slaveDirectoryPath;
public FolderSync()
{
masterDirectoryPath = ConfigurationManager.AppSettings.Get("MasterDirectory");
slaveDirectoryPath = ConfigurationManager.AppSettings.Get("SlaveDirectory");
if (Directory.Exists(masterDirectoryPath) && Directory.Exists(slaveDirectoryPath))
{
FTPFileSystemWatcher watcher = new FTPFileSystemWatcher(masterDirectoryPath);
watcher.FTPFileChanged += watcher_FTPFileChanged;
watcher.FTPFileCreated += watcher_FTPFileCreated;
watcher.FTPFileDeleted += watcher_FTPFileDeleted;
}
else
{
Console.WriteLine("Directories were not located check config paths");
}
}
void watcher_FTPFileDeleted(object sender, FileSystemEventArgs e)
{
DeleteFile(slaveDirectoryPath + e.Name, 5, 1);
}
void watcher_FTPFileCreated(object sender, FileSystemEventArgs e)
{
CopyFile(e.Name,5,1);
}
void watcher_FTPFileChanged(object sender, FileSystemEventArgs e)
{
}
private void DeleteFile(string fullPath, int attempts, int attemptNo)
{
if (File.Exists(fullPath))
{
try
{
File.Delete(fullPath);
Console.WriteLine("Deleted " + fullPath);
}
catch (Exception)
{
if (attempts > attemptNo)
{
Console.WriteLine("Failed deleting " + fullPath + "trying again "+ attemptNo.ToString()+ " of "+attempts);
Thread.Sleep(500);
DeleteFile(fullPath, attempts, attemptNo + 1);
}
else
{
Console.WriteLine("Critically Failed deleting " + fullPath);
}
}
}
}
private void CopyFile(string fileName,int attempts, int attemptNo)
{
string masterFile = masterDirectoryPath + fileName;
string slaveFile = slaveDirectoryPath + fileName;
if (File.Exists(masterFile))
{
try
{
File.Copy(masterFile,slaveFile);
Console.WriteLine("Copied " + masterFile);
}
catch (Exception)
{
if (attempts > attemptNo)
{
Console.WriteLine("Failed copying " + masterFile + "trying again " + attemptNo.ToString() + " of " + attempts);
Thread.Sleep(500);
CopyFile(fileName, attempts, attemptNo + 1);
}
else
{
Console.WriteLine("Critically Failed copying " + masterFile);
}
}
}
}
}
}
Попросите источник загрузить файл-заглушку сразу после завершения файла данных, а ваш FileSystemWatcher будет следить за файлом-заглушкой. Например, если имя файла данных - mydata_01234, тогда заглушкой будет mydata_01234_stub. Тогда FileSystemWatcher должен иметь маску «* _stub». Затем вы узнаете имя файла данных, удалив суффикс «_stub». И файл-заглушка не может быть загружен до завершения работы с файлом данных, поэтому файл данных будет свободным.
Если файлы-заглушки имеют размер всего один байт каждый, вы сможете удалить их после любой операции, выполняемой с файл данных без проблем. Если ваши операции выполняются особенно быстро, добавьте 100 мс сна перед удалением заглушки.