internal class EmailReaderWriter : IEmailReaderWriter
{
public List<string> AllReadEmails { get; private set; }
public List<string> AllWrittenEmails { get; private set; }
public string InputPath { get; }
public string OutputPath { get; }
private delegate void EmailReaderWriterHandler(string message);
private event EmailReaderWriterHandler _successNotification, _errorNotification;
private FileOptions _customFileOptions;
private object _locker;
public EmailReaderWriter(string inputpath = "..\\..\\..\\Input", string outputpath = "..\\..\\..\\Output")
{
InputPath = inputpath;
OutputPath = outputpath;
AllReadEmails = new List<string>();
AllWrittenEmails = new List<string>();
_successNotification += OperationSuccessNotifier.Success;
_errorNotification += OperationSuccessNotifier.Error;
_customFileOptions = FileOptions.Asynchronous | FileOptions.SequentialScan;
_locker = new object();
}
public List<string>? Read(string filepath)
{
if (!File.Exists(filepath))
{
_errorNotification($"File {filepath} doesn't exist!");
return null;
}
List<string> allReadEmailsFromFile;
using (FileStream fstream = new FileStream(filepath, FileMode.Open,
FileAccess.Read, FileShare.None, 0, _customFileOptions))
{
using (StreamReader reader = new StreamReader(fstream))
{
allReadEmailsFromFile = new List<string>(
(
reader.ReadToEnd()).
Split(new string[] { " ", ". ", ", " }, StringSplitOptions.RemoveEmptyEntries).
Where(x => x.Contains("@gmail.com"))
);
}
}
lock (_locker)
{
if (allReadEmailsFromFile.Count() == 0)
{
_errorNotification($"0 emails were found!");
return null;
}
List<string> readEmails = new List<string>();
foreach (var email in allReadEmailsFromFile)
{
if (AllReadEmails.Contains(email))
{
_errorNotification($"Email {email} is already read!");
continue;
}
else
{
readEmails.Add(email);
AllReadEmails.Add(email);
_successNotification($"Email {email} is read!");
}
}
if (readEmails.Count > 0)
_successNotification($"Such quantity of emails was read: {readEmails.Count}!");
return readEmails;
}
}
public bool Write(string filepath, string email)
{
if (!Directory.Exists(OutputPath))
Directory.CreateDirectory(OutputPath);
lock (_locker)
{
if (AllWrittenEmails.Contains(email))
{
_errorNotification($"Email {email} is already written on file!");
return false;
}
}
using (FileStream fstream = new FileStream(filepath, FileMode.Append,
FileAccess.Write, FileShare.None, 0, _customFileOptions |
FileOptions.WriteThrough))
{
using (StreamWriter writer = new StreamWriter(fstream))
{
writer.WriteLineAsync(email);
AllWrittenEmails.Add(email);
_successNotification($"Email {email} is successfully written on file!");
}
}
return true;
}
}
var allEmails = new ConcurrentBag<string>(
(
await reader.ReadToEndAsync()).
Split(new string[] { " ", ". ", ", " }, StringSplitOptions.RemoveEmptyEntries).
Where(x => x.Contains("@gmail.com"))
);
if (allEmails.Count() == 0)
{
reader.Close();
fstream.Close();
ErrorNotification($"0 emails were found!");
return null;
}
ConcurrentBag<string> nonReadEmails = new ConcurrentBag<string>();
int readEmailsAddedCounter = 0;
foreach (var email in allEmails)
{
if (ReadEmails.Contains(email))
{
ErrorNotification($"Email {email} is already read!");
continue;
}
else
{
readEmailsAddedCounter++;
nonReadEmails.Add(email);
ReadEmails.Add(email);
SuccessNotification($"Email {email} is read!");
}
}
if (readEmailsAddedCounter > 0)
SuccessNotification($"Such quantity of emails was read: {readEmailsAddedCounter}!");
reader.Close();
fstream.Close();
allEmails.Clear();
lock(locker)
{
if (ReadEmails.Contains(email))
{
ErrorNotification($"Email {email} is already read!");
continue;
}
else
{
readEmailsAddedCounter++;
nonReadEmails.Add(email);
ReadEmails.Add(email);
SuccessNotification($"Email {email} is read!");
}
}
public List<string> ReadEmails { get; private set; }
public async Task<ConcurrentBag<string>?> ReadAsync(string filepath)
{
if (!File.Exists(filepath))
{
ErrorNotification($"File {filepath} doesn't exist!");
return null;
}
FileStream fstream = new FileStream(filepath, FileMode.Open,
FileAccess.Read, FileShare.None, 0, customFileOptions);
StreamReader reader = new StreamReader(fstream);
var allEmails = new ConcurrentBag<string>(
(
await reader.ReadToEndAsync()).
Split(new string[] { " ", ". ", ", " }, StringSplitOptions.RemoveEmptyEntries).
Where(x => x.Contains("@gmail.com"))
);
if (allEmails.Count() == 0)
{
reader.Close();
fstream.Close();
ErrorNotification($"0 emails were found!");
return null;
}
ConcurrentBag<string> nonReadEmails = new ConcurrentBag<string>();
int readEmailsAddedCounter = 0;
foreach (var email in allEmails)
{
if (ReadEmails.Contains(email))
{
ErrorNotification($"Email {email} is already read!");
continue;
}
else
{
readEmailsAddedCounter++;
nonReadEmails.Add(email);
lock(locker)
{
ReadEmails.Add(email);
}
SuccessNotification($"Email {email} is read!");
}
}
if (readEmailsAddedCounter > 0)
SuccessNotification($"Such quantity of emails was read: {readEmailsAddedCounter}!");
reader.Close();
fstream.Close();
allEmails.Clear();
return nonReadEmails;
}