I've set up the Enterprise Library Logging Application Block to log in a file called 'app.log' residing in the execution path of my application. This application is a Windows service which runs a configuration website on top of it, where I now want to show the contents of the log file.
Getting the log file was a rather easy task:
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var logSection = config.GetSection("loggingConfiguration") as LoggingSettings;
var lookup = logSection.TraceListeners
.Where(x => x is RollingFlatFileTraceListenerData).FirstOrDefault() as RollingFlatFileTraceListenerData;
if(lookup != null) {
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, lookup.FileName);
return File.ReadAllText(_logFilePath);
}
However, the RollingFlatFileTraceListener I've set up constantly BLOCKS the file I want to read from. Is there any possibility to access it?
Check this answer. That this is not the default behavior for File.ReadAllText is beyond me...
using (var logFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var logFileReader = new StreamReader(logFileStream))
{
return logFileReader.ReadToEnd();
}
Also note that you are mixing filePath and _logFilePath.
Related
I'm working with DocumentFormat.OpenXml.SpreadsheetDocument and opening a template of an Excel document, writing to it and saving it.
It works like charm from a normal File stream:
using (var documentStream = System.IO.File.Open("--somePath--", FileMode.Open, FileAccess.ReadWrite))
{
using (var document = SpreadsheetDocument.Open(documentStream, true))
{
// do something
}
}
Notice the SpreadsheetDocument.Open
Now, I'm rewriting this application to Azure, and using Azure storage and it's .NET File library in "WindowsAzure.Storage" package.
It works like a charm, all up to a point where I want to fill the same excel files in Azure.
using (var documentStream = _GetRootDirectoryOfAccount().GetFileReference("--someRelativePath--").OpenWrite(null))
{
using (var document = SpreadsheetDocument.Open(documentStream, true))
{
// do something
}
}
The first part "_GetRootDirectoryOfAccount().GetFileReference" works 100%, then OpenWrite(null) really opens a Stream.
However, when that Stream is pushed towards the Spreadsheet:
SpreadsheetDocument.Open(documentStream, true)
It breaks with:
System.IO.IOException: 'Cannot open package because FileMode or
FileAccess value is not valid for the stream.'
And it is because on the Stream the settings are not set:
System.IO.File.Open("--somePath--", FileMode.Open, FileAccess.ReadWrite)
Does anyone know how to get around this? Or a solution?
Please :)
Does anyone know how to get around this? Or a solution?
The return type of _GetRootDirectoryOfAccount().GetFileReference("--someRelativePath--").OpenWrite(null)) is CloudFileStream
`
It seems that CloudFileStream is not supported by SpreadsheetDocument.Open().
Please have a try to use the following code,it works correctly on my side. After update the content, we could use file.UploadFromFile() or file.UploadFromStream() to upload the file.;
var file = _GetRootDirectoryOfAccount().GetFileReference("--someRelativePath--");
var memoryStream = new MemoryStream();
file.DownloadToStream(memoryStream);
using (var document = SpreadsheetDocument.Open(memoryStream, true))
{
// do something
}
The following is my demo code.
var connectionString = "DefaultEndpointsProtocol=https;AccountName=accountName;AccountKey=xxxxx;EndpointSuffix=core.windows.net";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
CloudFileClient fileClient = storageAccount.CreateCloudFileClient();
// Get a reference to the file share we created previously.
CloudFileShare share = fileClient.GetShareReference("test"); //share name
if (share.Exists())
{
// Get a reference to the root directory for the share.
CloudFileDirectory rootDir = share.GetRootDirectoryReference();
// Get a reference to the directory we created previously.
CloudFileDirectory sampleDir = rootDir.GetDirectoryReference("custom");
// Ensure that the directory exists.
if (sampleDir.Exists())
{
// Get a reference to the file we created previously.
var file = sampleDir.GetFileReference("OpenXMl.xlsx"); //file name
// Ensure that the file exists.
if (file.Exists())
{
// Write the contents of the file to the console window.
Console.WriteLine(file.DownloadTextAsync().Result);
var memoryStream = new MemoryStream();
file.DownloadToStream(memoryStream);
using (var document = SpreadsheetDocument.Open(memoryStream, true))
{
// do something
}
}
}
}
I created a android app to create a stockage list by capturing code bars, the idea is to write a csv file in to a network folder, because I want the app to run as much offline as it's possible.
Currently my code looks like:
string path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
string filename = Path.Combine(path, "stock.csv");
using (var streamWriter = new StreamWriter(filename, true))
using (var writer = new CsvWriter(streamWriter))
{
foreach (var item in articulos)
{
writer.WriteField(item.codbar);
writer.WriteField(item.reference);
writer.WriteField(item.quantity);
writer.NextRecord();
}
}
string path2 = #"\\Desktop-jce8pl5\csv\stock.csv";
File.Copy(filename, path2,true);
But I keep geting a System.UnauthorizedAccessException
I tried to enter directly to the file from another computer and there
is no problem.
I give full permission to "all" and "network"
I tried directly with IP I tried not to copy, just to create
string path = #"\\Desktop-jce8pl5\csv\stock.csv";
FileStream fs = null;
if (File.Exists(path))
{
fs = File.Open(path, FileMode.Append);
}
else
{
fs = File.Create(path);
}
But there is no way.
Any help?
Thanks.
As #RobertN sugested, I tried to connect with EX File Ex and detected that I was unable to, so I checked the windows 10 general configuration to shared folders and it was only enabled to auth users.
I changed that, then I start with the cifsmanager but on that moment we decided that, if the user has access to local network he will most sure have acces to internet, so I will send the file by email.
I've build a File System Watcher solution, and, I would to retrieve the changes made on log file, extracting only the added line, but I can not in this because I always error that the process cannot access the file because it is being used by another process.
My code is this for retrieve the added line is this:
using (var file = new FileStream(FileName,
FileMode.Open,
FileAccess.Read,
FileShare.Read))
using (var sr = new StreamReader(file))
{
try
{
Thread thread = new Thread(delegate()
{
listBox1.Invoke((MethodInvoker)(() =>
{
listBox1.Items.Clear();//this is the listbox that list every added line and that I clear before of to be filled
string[] lines = File.ReadLines(fileName)
.Skip(LinecountStartPositionBUFF)
.Take(LinecountEndPosition - LinecountStartPositionBUFF)
.ToArray();
listBox1.Items.AddRange(lines);
}));
});
thread.Start();
while (thread.IsAlive)
Application.DoEvents();
}
catch
{ }
return sr.ReadLine();
}
You can not open the file in a FileStream and later access it via File.ReadLines, because FileStream locks the file. I would change the complete code.
I'm attempting to use StreamReader and StreamWriter to grab a temporary output log (.txt format) from another application.
The output log is always open and constantly written to.
Unhelpfully if the application closes or crashes, the log file ends up deleted - hence the need for a tool that can grab the information from this log and save it.
What my program currently does is:
Create a new .txt file, and stores the path of that file as the
string "destinationFile".
Finds the .txt log file to read, and stores the path of that file as
the string "sourceFile"
It then passes those two strings to the method below.
Essentially I'm trying to read the sourceFile one line at a time.
Each time one line is read, it is appended to destinationFile.
This keeps looping until the sourceFile no longer exists (i.e. the application has closed or crashed and deleted its log).
In addition, the sourceFile can get quite big (sometimes 100Mb+), and this program may be handling more than one log at a time.
Reading the whole log rather than line by line will most likely start consuming a fair bit of memory.
private void logCopier(string sourceFile, string destinationFile)
{
while (File.Exists(sourceFile))
{
string textLine;
using (var readerStream = File.Open(sourceFile,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
using (var reader = new StreamReader(readerStream))
{
while ((textLine = reader.ReadLine()) != null)
{
using (FileStream writerStream = new FileStream(destinationFile,
FileMode.Append,
FileAccess.Write))
using (StreamWriter writer = new StreamWriter(writerStream))
{
writer.WriteLine(textLine);
}
}
}
}
}
The problem is that my WPF application locks up and ceases to respond when it reaches this code.
To track down where, I put a MessageBox just before the writerStream line of the code to output what the reader was picking up.
It was certainly reading the log file just fine, but there appears to be a problem with writing it to the file.
As soon as it reaches the using (FileStream writerStream = new FileStream part of the code, it stops responding.
Is using the StreamWriter in this manner not valid, or have I just gone and dome something silly in the code?
Am also open to a better solution than what I'm trying to do here.
Simply what I understand is you need to copy a file from source to destination which may be deleted at any time.
I'll suggest you to use FileSystemWatcher to watch for source file changed event, then just simply copy the whole file from source to destination using File.Copy.
I've just solved the problem, and the issue was indeed something silly!
When creating the text file for the StreamWriter, I had forgotten to use .Dispose();. I had File.Create(filename); instead of File.Create(filename).Dispose(); This meant the text file was already open, and the StreamWriter was attempting to write to a file that was locked / in use.
The UI still locks up (as expected), as I've yet to implement this on a new thread as SteenT mentioned. However the program no longer crashes and the code correctly reads the log and outputs to a text file.
Also after a bit of refinement, my log reader/writer code now looks like this:
private void logCopier(string sourceFile, string destinationFile)
{
int num = 1;
string textLine = String.Empty;
long offset = 0L;
while (num == 1)
{
if (File.Exists(sourceFile))
{
FileStream stream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using (new StreamReader(stream))
{
stream.Seek(offset, SeekOrigin.Begin);
TextReader reader2 = new StreamReader(stream);
while ((textLine = reader2.ReadLine()) != null)
{
Thread.Sleep(1);
StreamWriter writer = new StreamWriter(destinationFile, true);
writer.WriteLine(textLine);
writer.Flush();
writer.Close();
offset = stream.Position;
}
continue;
}
}
else
{
num = 0;
}
}
}
Just putting this code up here in case anyone else is looking for something like this. :)
i wish to write to a protected text file note this content is important.
Can i write to a file to keep it protected i am going to use encryption
but do not wish anyone to read the content of the file. I have tried to
use File.WriteText? but the problem is that the file gets written then
unused so anyone can read the content.
Protection eg. Like the SAM file
In Microsoft Dotnet framework, TextFile attributes are available in c# will enable you to keep the file encrypted and readonly. The write protection can be done using FileIOPermissionAccesss If current user is administrator then he will able to give protect and delete permissions for particular can be given to the file. Below is sample code for adding permission.
var permissionSet = new PermissionSet(PermissionState.None);
var writePermission = new FileIOPermission(FileIOPermissionAccess.Write, filename);
permissionSet.AddPermission(writePermission);
if (permissionSet.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet))
{
using (FileStream fstream = new FileStream(filename, FileMode.Create))
using (TextWriter writer = new StreamWriter(fstream))
{
// try catch block for write permissions
writer.WriteLine("sometext");
}
}
else
{
//perform some recovery action here
}
I too faced similar problem, instead in my case the problem was the
data in my file should be visible to anyone even to the admin user,
and for every time the application runs the previous data should be
replaced by the new one.
Here's my code
string pathfile = #"C:\Users\Public\Documents\Filepath.txt";
if (File.Exists(pathfile))
{
File.Delete(pathfile);
}
if (!File.Exists(pathfile))
{
using (FileStream fs = File.Create(pathfile))
{
Byte[] info = new UTF8Encoding(true).GetBytes("Your Text Here");
fs.Write(info, 0, info.Length);
FileSecurity fsec = File.GetAccessControl(pathfile);
fsec.AddAccessRule(new FileSystemAccessRule("Everyone",
FileSystemRights.FullControl, AccessControlType.Deny));
File.SetAccessControl(pathfile, fsec);
}
}