Can't write to filestream - c#

I've created a fileStream and a streamwriter to write to this. Problem is my file is not showing up with any text. The objects have instantiated correctly and the path and everything is write, just can't see anything writing. Maybe a problem with the streamwriter?
public class Logger {
StreamWriter sw;
FileStream logFileStream;
public enum LogLevel
{
Low,
Medium,
High
};
public Logger(string filePath)
{
//logStream = new StreamWriter(logFilePath, false);
logFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Write);
sw = new StreamWriter(logFileStream);
}
public void LogMessage(string message) {
LogMessage(message, LogLevel.Low, false);
}
public void LogMessage(string message, LogLevel level, bool excludeFromLogFile){
var prefix = string.Empty;
ConsoleColor color = ConsoleColor.White;
switch (level)
{
case LogLevel.Medium:
prefix = "?";
color = ConsoleColor.Yellow;
break;
case LogLevel.High:
prefix = "!";
color = ConsoleColor.Red;
break;
}
if (!excludeFromLogFile)
{
sw.WriteLine("{0} {1} {2}", prefix, DateTime.Now, message);
}
Console.ForegroundColor = color;
Console.WriteLine("{0}", message);
Console.ResetColor();
}
I am instantiating this class and then calling logger.LogMessage("poop", Logger.LogLevel.High, false); and nothing is showing.
Thanks

The writes are being buffered in memory, try calling logFileStream.Flush(); at the end of each Log function.
You really shouldn't be keeping the file handle open between calls though, if I were you I would open and close it in each function. If you're doing a lot of logging then buffer it yourself in memory and dump the whole thing once it reaches a certain size.

This is the correct version of your example
use autoflush = true in stream writer
open/close stream in every request - if it is correctly implemented, autoflush is unnecessary (flush will be done after dispose StreamWriter)
use FileMode.Append
public class Logger
{
public enum LogLevel
{
Low,
Medium,
High
};
private readonly string _filePath;
public Logger(string filePath)
{
//logStream = new StreamWriter(logFilePath, false);
_filePath = filePath;
}
public void LogMessage(string message)
{
LogMessage(message, LogLevel.Low, false);
}
public void LogMessage(string message, LogLevel level, bool excludeFromLogFile)
{
using (var fileStream = new FileStream(_filePath, FileMode.Append, FileAccess.Write))
{
using (var writer = new StreamWriter(fileStream) {AutoFlush = true})
{
var prefix = string.Empty;
var color = ConsoleColor.White;
switch (level)
{
case LogLevel.Medium:
prefix = "?";
color = ConsoleColor.Yellow;
break;
case LogLevel.High:
prefix = "!";
color = ConsoleColor.Red;
break;
}
if (!excludeFromLogFile)
{
writer.WriteLine("{0} {1} {2}", prefix, DateTime.Now, message);
}
Console.ForegroundColor = color;
Console.WriteLine("{0}", message);
Console.ResetColor();
}
}
}
}

Related

SSH.NET Verbose Mode

I am trying to print more logs on the console while running my SSH.NET app, I know for OpenSSH client you can simply add ssh -vvv to get all traces
Is there anything similar to SSH.NET client as well?
Here is a custom ShellStream wrapper that has provision for logging. It also has other custom features for my main use, which is a CLI wrapper for network switch configuration.
public static class SshClientExt {
public static ExtShellStream CreateExtShellStream(this SshClient sc, string termName, uint cols, uint rows, uint width, uint height, int bufSize) =>
new ExtShellStream(sc.CreateShellStream(termName, cols, rows, width, height, bufSize));
}
public class ExtShellStream : IDisposable {
static Regex reEscVT100 = new Regex("\x1B\\[[^A-Z]+[A-Z]", RegexOptions.Compiled);
static TimeSpan ReadTimeout = new TimeSpan(0, 0, 10);
public bool Debug = false;
ShellStream ssh;
StreamReader sr;
StreamWriter sw;
public ExtShellStream(ShellStream anSSH) {
ssh = anSSH;
sr = new StreamReader(ssh);
sw = new StreamWriter(ssh);
}
public List<string> ReadLinesUpTo(string prompt, TimeSpan? timeout = null) {
if (Debug) {
Console.WriteLine($"{DateTime.Now:HH:mm:ss.ff}: >>>ReadLinesUpTo(\"{prompt}\", {timeout:%s})");
Console.WriteLine($"{DateTime.Now:HH:mm:ss.ff}: " + new String('v', 60));
}
var ans = new List<string>();
var now = DateTime.Now;
do {
var line = sr.ReadLine();
if (line != null) {
line = line.Remove(reEscVT100).TrimEnd();
if (Debug)
Console.WriteLine($#"<""{line}""");
if (line.EndsWith(prompt)) {
if (Debug)
Console.WriteLine($"{DateTime.Now:HH:mm:ss.ff}: Found prompt, done reading");
break;
}
ans.Add(line);
if (ssh.Length < 240) { // wait for more lines to come in
Thread.Sleep(50);
}
now = DateTime.Now; // reset timeout while data is available
}
else
Thread.Sleep(250); // if no prompt, wait for more data until timeout
} while (!timeout.HasValue || DateTime.Now - now <= timeout);
if (Debug) {
Console.WriteLine($"{DateTime.Now:HH:mm:ss.ff}: " + new String('^', 60));
Console.WriteLine($"{DateTime.Now:HH:mm:ss.ff}: <<<ReadLinesUpTo(\"{prompt}\")");
}
return ans;
}
static TimeSpan DumpTimeout = TimeSpan.FromSeconds(0.1);
public void DumpLines() => ReadLinesUpTo("#", DumpTimeout);
public void Send(string toSend, bool dumpLines = false) {
if (Debug)
Console.WriteLine($"Send(\"{toSend}\", {dumpLines})");
sw.Write(toSend);
sw.Flush();
if (dumpLines)
DumpLines();
}
public IEnumerable<string> DoCommand(string cmd, TimeSpan? timeout, string prompt) {
sr.DiscardBufferedData();
if (Debug)
Console.WriteLine($"Write>\"{cmd}\\r\"");
sw.Write(cmd);
Send("\r");
while (!ssh.DataAvailable)
Thread.Sleep(250);
return ReadLinesUpTo(prompt, timeout).Select(l => l.StartsWith(cmd) ? l.Substring(cmd.Length) : l);
}
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing) {
if (!disposedValue) {
if (disposing) {
// prevent double dispose
// don't dispose of sr or sw: their only resource is ssh
ssh.Dispose();
}
disposedValue = true;
}
}
// This code added to correctly implement the disposable pattern.
public void Dispose() {
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
}
#endregion
}
Here is how I create it in the program:
SSHStream = SSHClient.CreateExtShellStream("dumb", 240, 120, 512, 0, 65536);

"Unable to remove the file to be replaced" error during File.Replace, if FileSystemWatcher is active and executing a call to Path.GetDirectoryName

I would like to understand the root cause for this error:
Unable to remove the file to be replaced.
This error comes while executing File.Replace(), and having in parallel in another application an active FileSystemWatcher, which as a reaction to the events, is calling Path.GetDirectoryName() for the actual element received in the eventargs.
The code for the two console applications looks like this:
FileReplacerr:
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
namespace ConsoleApplication1
{
internal static class FileReplacer
{
private static void Main(string[] args)
{
Console.WriteLine("Test Started.");
Directory.CreateDirectory(rootPath);
CleanUp(new List<string> { livePath, tempPath }, -1);
for (int loopIndex = 0; loopIndex < 10000; loopIndex++)
{
WriteXmlFile(livePath + loopIndex, "LiveContent");
WriteXmlFile(tempPath + loopIndex, "TempContent");
ReplaceFiles(livePath + loopIndex, tempPath + loopIndex);
CleanUp(new List<string> { livePath + loopIndex, tempPath + loopIndex }, loopIndex);
}
Console.WriteLine("---------------------------------------------");
Console.WriteLine("Test Finished.");
Console.WriteLine("Exception count: {0}", exceptionCount);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
private static void ReplaceFiles(string replacedFile, string replacementFile)
{
try
{
File.Replace(replacedFile, replacementFile, null);
}
catch (Exception ex)
{
exceptionCount++;
string extendedErrorMessage = string.Format("Replacement of original:'{0}' and temporary:'{1}' xml file completed with error code: {2}", replacedFile, replacementFile, ex.Message);
Console.WriteLine("Exception happened during replace:");
Console.WriteLine(extendedErrorMessage);
Console.WriteLine("Press any key to continue");
Console.ReadKey();
}
}
private static void WriteXmlFile(string filePath, string elementText)
{
using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 32 * 1024, FileOptions.SequentialScan))
{
fileStream.Seek(0, SeekOrigin.Begin);
fileStream.SetLength(0);
XmlWriterSettings settings = new XmlWriterSettings { CheckCharacters = false };
using (XmlWriter xmlWriter = XmlWriter.Create(fileStream, settings))
{
xmlWriter.WriteStartDocument();
xmlWriter.WriteStartElement(elementText);
xmlWriter.WriteEndElement();
xmlWriter.WriteEndDocument();
}
}
}
private static void CleanUp(List<string> filePaths, int loopIndex)
{
foreach (string filePath in filePaths)
{
File.Delete(filePath);
}
}
private static int exceptionCount = 0;
static readonly string rootPath = #"C:\teststorage\";
static readonly string liveFile = "live.xml";
static readonly string tempFile = "temp.xml.tmp";
static readonly string livePath = rootPath + liveFile;
static readonly string tempPath = rootPath + tempFile;
}
}
FileSystemWatcherr:
using System;
using System.IO;
namespace FileSystemWatcherr
{
class FileSystemWatcherr
{
static void Main(string[] args)
{
using (FileSystemWatcher watcher = new FileSystemWatcher
{
Path = #"c:\",
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName,
IncludeSubdirectories = true
})
{
watcher.Changed += OnFolderStructureChanged;
watcher.Created += OnFolderStructureChanged;
watcher.Deleted += OnFolderStructureChanged;
watcher.Renamed += OnFolderStructureChanged;
watcher.EnableRaisingEvents = true;
Console.WriteLine("FileSystemWatcher is active");
Console.WriteLine("Press any key to stop watching and exit");
Console.ReadKey();
watcher.EnableRaisingEvents = false;
watcher.Changed -= OnFolderStructureChanged;
watcher.Created -= OnFolderStructureChanged;
watcher.Deleted -= OnFolderStructureChanged;
watcher.Renamed -= OnFolderStructureChanged;
}
}
private static void OnFolderStructureChanged(object sender, FileSystemEventArgs e)
{
string path = string.Empty;
switch (e.ChangeType)
{
case WatcherChangeTypes.Changed:
case WatcherChangeTypes.Deleted:
case WatcherChangeTypes.Renamed:
case WatcherChangeTypes.Created:
default:
path = Path.GetDirectoryName(e.FullPath);
break;
}
}
}
}
Just start the FileSystemWatcherr and then start the FileReplacerr and you will see the error happening.
The issue happens more frequently on Win7 machines. On my Win10 machine, it did not happen, but running the applications on a virtual machine with Win10, the issue happens many times during 10000 loops.
Does anyone have an idea what could be the root cause?
Up to now, I tried using Process Monitor, but from its output I do not understand what the root cause could be:
If you have an idea how to find the root-cause, or you know it, let me know :)

Cant write to a file using a thread

I'm writing a windows service (C#) that does a task repetitively. I'm using a thread to complete my requirement. Now I need to maintain a log file that keeps logs regarding the operation.
My service class is as follow
public partial class CPEService : ServiceBase
{
static ServiceBot bot = new ServiceBot();
static ProgramLog logger = new ProgramLog();//ProgramLog Object
private static bool state = true;
//private static int count = 1;
//private System.Timers.Timer timer;
public CPEService()
{
InitializeComponent();
}
internal void TestStartupAndStop()
{
Thread workerThread = new Thread(loopTrough);
workerThread.Start();
}
protected override void OnStart(string[] args)
{
Thread workerThread = new Thread(loopTrough);
workerThread.Start();
}
private void loopTrough()
{
logger.log("Thread fired");
while (state)
{
logger.log("Thread fired"); //This is not Working
bot.start();
Thread.Sleep(180000);
}
}
protected override void OnStop()
{
state = false;
}
}
I have a separate class call "ProgramLog" to handle all the log related operations.This is that class.
public class ProgramLog
{
string fileName = "";//Global variable to store file name
#region method to handle usual log records
public void log(string text)//create normal Log text
{
fileName = "Log\\" + DateTime.Now.Date.ToString("d").Replace('/', '_') + ".txt";
if (File.Exists(AppDomain.CurrentDomain.BaseDirectory+fileName))
{
using (FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + fileName, FileMode.Append))
using (TextWriter tw = new StreamWriter(fs))
{
tw.WriteLine(text);
tw.Flush();
tw.Close();
fs.Close();
}
}
else
{
createFolder();
log(text);
}
}
#endregion
#region log Error record
public void logError(string text, string className,int LineNumber, string Stacktrace)//create error text
{
fileName = "Log\\" + DateTime.Now.Date.ToString("d").Replace('/', '_') + ".txt";
if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + fileName))
{
using (FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + fileName, FileMode.Append))
using (TextWriter tw = new StreamWriter(fs))
{
tw.WriteLine("**************************ERROR****************************");
tw.WriteLine(text);
tw.WriteLine("In Class :{0}", className);
tw.WriteLine("In Line :{0}", LineNumber);
tw.WriteLine("ERROR :{0}",Stacktrace);
tw.WriteLine("***********************************************************");
}
}
else
{
createFolder();
logError(text,className,LineNumber,Stacktrace);
}
}
#endregion
#region create folder to store log files
public void createFolder()//create a folder for Log files
{
try
{
if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + "Log"))
{
string folderName = "Log";
Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + folderName);
FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + fileName, FileMode.Create);
StreamWriter sr = new StreamWriter(fs);
sr.Flush();
sr.Close();
fs.Close();
}
else
{
FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + fileName, FileMode.Create);
StreamWriter sr = new StreamWriter(fs);
sr.Flush();
sr.Close();
fs.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
}
}
#endregion
}
According to the above class, When I start the service it needs to create folder call "Log" where it does not exists, then it creates a text file inside that folder and lastly it starts to create the log entries.
Even though the thread is working correctly it never touches the "ProgramLog" methods. I checked by directly calling the method "loopTrough". then its working fine.
Please help me to resolve this bug.
Thank you
You declare a Thread workerThread = new Thread(loopTrough);, but you don't start this Thread. Just call workerThread.Start().

(Pause) Stop download without dropping connection

I want to be able to pause a download. I can stop them by dropping the existing connections.
What I'm referring to is almost similar to what's described here: https://superuser.com/questions/170509/whats-the-difference-in-using-pause-stop-in-%C2%B5torrent
My download class:
public class Download
{
public event EventHandler<DownloadStatusChangedEventArgs> DownloadStatusChanged;
public event EventHandler<DownloadProgressChangedEventArgs> DownloadProgressChanged;
public event EventHandler DownloadCompleted;
public bool stop = true; // by default stop is true
public void DownloadFile(string DownloadLink, string Path)
{
stop = false; // always set this bool to false, everytime this method is called
long ExistingLength = 0;
FileStream saveFileStream;
if (File.Exists(Path))
{
FileInfo fileInfo = new FileInfo(Path);
ExistingLength = fileInfo.Length;
}
if (ExistingLength > 0)
saveFileStream = new FileStream(Path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
else
saveFileStream = new FileStream(Path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
var request = (HttpWebRequest)HttpWebRequest.Create(DownloadLink);
request.Proxy = null;
request.AddRange(ExistingLength);
try
{
using (var response = (HttpWebResponse)request.GetResponse())
{
long FileSize = ExistingLength + response.ContentLength; //response.ContentLength gives me the size that is remaining to be downloaded
bool downloadResumable; // need it for sending empty progress
if ((int)response.StatusCode == 206)
{
Console.WriteLine("Resumable");
var downloadStatusArgs = new DownloadStatusChangedEventArgs();
downloadResumable = true;
downloadStatusArgs.ResumeSupported = downloadResumable;
OnDownloadStatusChanged(downloadStatusArgs);
}
else // sometimes a server that supports partial content will lose its ability to send partial content(weird behavior) and thus the download will lose its resumability
{
Console.WriteLine("Resume Not Supported");
ExistingLength = 0;
var downloadStatusArgs = new DownloadStatusChangedEventArgs();
downloadResumable = false;
downloadStatusArgs.ResumeSupported = downloadResumable;
OnDownloadStatusChanged(downloadStatusArgs);
// restart downloading the file from the beginning because it isn't resumable
// if this isn't done, the method downloads the file from the beginning and starts writing it after the previously half downloaded file, thus increasing the filesize and corrupting the downloaded file
saveFileStream.Dispose(); // dispose object to free it for the next operation
File.WriteAllText(Path, string.Empty); // clear the contents of the half downloaded file that can't be resumed
saveFileStream = saveFileStream = new FileStream(Path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); // reopen it for writing
}
using (var stream = response.GetResponseStream())
{
byte[] downBuffer = new byte[4096];
int byteSize = 0;
long totalReceived = byteSize + ExistingLength;
var sw = new Stopwatch();
sw.Start();
while ((byteSize = stream.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
saveFileStream.Write(downBuffer, 0, byteSize);
totalReceived += byteSize;
var args = new DownloadProgressChangedEventArgs();
args.BytesReceived = totalReceived;
args.TotalBytesToReceive = FileSize;
float currentSpeed = totalReceived / (float)sw.Elapsed.TotalSeconds;
args.CurrentSpeed = currentSpeed;
if (downloadResumable == true)
{
args.ProgressPercentage = ((float)totalReceived / (float)FileSize) * 100;
long bytesRemainingtoBeReceived = FileSize - totalReceived;
args.TimeLeft = (long)(bytesRemainingtoBeReceived / currentSpeed);
}
else
{
//args.ProgressPercentage = Unknown;
//args.TimeLeft = Unknown;
}
OnDownloadProgressChanged(args);
if (stop == true)
return;
}
sw.Stop();
}
}
var completedArgs = new EventArgs();
OnDownloadCompleted(completedArgs);
saveFileStream.Dispose();
}
catch (WebException e)
{
string filename = System.IO.Path.GetFileName(Path);
Console.WriteLine(e.Message);
saveFileStream.Dispose();
return; //not needed because this is the last line of the method, but let's keep it here
}
}
public void StopDownload()
{
stop = true;
}
protected virtual void OnDownloadStatusChanged(DownloadStatusChangedEventArgs e)
{
EventHandler<DownloadStatusChangedEventArgs> handler = DownloadStatusChanged;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnDownloadProgressChanged(DownloadProgressChangedEventArgs e)
{
EventHandler<DownloadProgressChangedEventArgs> handler = DownloadProgressChanged;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnDownloadCompleted(EventArgs e)
{
EventHandler handler = DownloadCompleted;
if (handler != null)
{
handler(this, e);
}
}
}
public class DownloadStatusChangedEventArgs : EventArgs
{
public bool ResumeSupported { get; set; }
}
public class DownloadProgressChangedEventArgs : EventArgs
{
public long BytesReceived { get; set; }
public long TotalBytesToReceive { get; set; }
public float ProgressPercentage { get; set; }
public float CurrentSpeed { get; set; } // in bytes
public long TimeLeft { get; set; } // in seconds
}
Can anybody help me with this?
Note: I can already resume downloads, that's not what I want, if you were wondering.
In your code (you should copy it into your question, by the way), you have a loop that reads bytes from a stream. You have a flag that will stop the loop.
You do the exact same thing except for pausing instead of stopping. It could be another flag, but you will also need to know when to resume, so you need something for the loop to wait on. One fairly neat way to do this would be with a lock (mutex).
I don't know C# so I can't give you working code, but here is pseudocode for it. With your pointer to the reference docs, it looks like SemaphoreSlim is the simplest thing suitable for this purpose.
bool stop = false
bool paused = false
SemaphoreSlim pauseLock = new SemaphoreSlim(1)
method download():
while (stuff to read):
read from stream
write to file
if stop:
break
// This will do nothing if not paused, or will block if paused
pauseLock.Wait()
pauseLock.Release()
method stop():
stop = true
self.unpause() // stop waiting on lock if needed
method pause()
if not paused:
paused = true
// Note this cannot block for more than a moment
// since the download thread doesn't keep the lock held
pauseLock.Wait()
method unpause()
if paused:
paused = false
pauseLock.Release()
Of course, doing this may cause the server to drop your connection eventually (at which point you need to resume anyway, and you'll only notice this after unpausing).

Not being able to write output to text file

Please suggest whats wrong with the following code to write names to text file. The file is being created but nothing is written in it. Although program is running fine and there is no exception yet not getting anything in txt file.
class IO
{
public void write(string name)
{
try
{
FileStream fs = new FileStream(#"D:\Infogain\ObjSerial.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
sw.BaseStream.Seek(0, SeekOrigin.Current);
sw.Write(name);
fs.Close();
}
catch (Exception ex)
{
Console.WriteLine("Issue in writing: " + ex.Message);
}
}
public static void Main(string[] args)
{
string name;
int ch;
List<string> list = new List<string>();
do
{
Console.WriteLine("Enter name");
name = Console.ReadLine();
IO io = new IO();
io.write(name);
Console.WriteLine("Enter 1 to continue");
ch = Convert.ToInt32(Console.ReadLine());
}while(ch==1);
}
}
You should read up on Object Oriented Programming a little. Creating a new IO object within that loop makes no sense. Also your write function is kind of messed up.
Fixed version:
(note: "write" function appends to file)
public class IO
{
public static void write(string name)
{
try
{
string path = #"e:\mytxtfile.txt";
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine(name);
}
}
catch (Exception ex)
{
Console.WriteLine("Issue in writing: " + ex.Message);
}
}
public static void Main(string[] args)
{
string name;
int ch;
List<string> list = new List<string>();
do
{
Console.WriteLine("Enter name");
name = Console.ReadLine();
write(name);
Console.WriteLine("Enter 1 to continue");
ch = Convert.ToInt32(Console.ReadLine());
} while (ch == 1);
}
}

Categories

Resources