problems with filestream, streamreader and streamwriter - c#

my first problem comes in the form of if i declare my filestream etc in this manner
filestream file;
streamreader file_in;
streamwriter file_out;
try
{
file = new filestream("data.txt", FileMode.OpenOrCreate);
file_in = new streamreader(file);
file_out = new streamwriter(file);
}
catch(IOException exc)
{
Console.WriteLine(exc.Message);
}
throws an error which says "use of unassigned local variable", which i find odd because all streams are declared outside of the try block but within the main so they should exist within the main.
my other problem comes in the form that if i remove the try/catch block and just declare the streams as one line (eg: FileStream file = new FileStream("data.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);) my reading from file does work however i cannot write to file. my write to file function is as follows:
public bool write_to_file(ref StreamWriter file_out)
{
if (this.is_empty == true)
{
Console.WriteLine("error, there is nothing to write.");
Console.WriteLine("press any key to continue...");
Console.ReadKey();
return false;
}
try
{
string temp = this.is_empty + "," + this.movie_title + "," + this.year_released + "," + this.publisher + "," +
this.length + "," + this.acting_rating + "," + this.music_rating + "," + this.cinematography_rating + "," +
this.plot_rating + "," + this.duration_rating + "," + this.total_rating;
file_out.WriteLine(temp);
return true;
}
catch (IOException exc)
{
Console.WriteLine(exc.Message);
Console.WriteLine("press any key to continue...");
Console.ReadKey();
return false;
}
}
any help would be much appreciated, thanks.

Well, they're declared but unassigned... so, either set them to null or just do everything together.
try
{
using(var file = new FileStream("data.txt", FileMode.OpenOrCreate))
using(var file_in = new StreamReader(file))
using(var file_out = new StreamWriter(file))
{
// Do your thing
}
}
catch
{
throw;
}

You need to assign a value to your variables at the top, even if its just null
FileStream file = null;
StreamReader file_in = null;
StreamWriter file_out = null;

Before closing the files, try flushing the output streams and files.
file_out.Flush();
file.Flush(); // may be redundant but won't hurt

Related

C# Get files Outlook Attachments single-multiple selected files Win 7, Win 10

I have re-edited my question since the problem lies elsewhere.
I have this piece of code to drop the files from outlook (single or multiple) at specific win form. On windows 7 stations the copy is made, but on windows 10 cannot get the list of filename from class.
public class OutlookDataObject : System.Windows.Forms.IDataObject
Class shown on this post
This class is working on Working code for win 7 but no filename return on windwos 10. This huge class is way over my understanding.
There is a simple way to get from outlook the selected attachements to prepare them to drop ?
private void btn_Home_DragDrop(object sender, DragEventArgs e)
{
bool debug = true;
if (debug) { txt_FileInfo.AppendText("Entering drop method " + Environment.NewLine); }
folderBrowserDialog1.SelectedPath = LastSelectedFolder.GlobalVar;
if (debug)
{ txt_FileInfo.AppendText("Get last path " + Environment.NewLine); }
folderBrowserDialog1.Description = "Drop the files";
if (debug)
{ txt_FileInfo.AppendText("Show folder dialog " + Environment.NewLine); }
if (folderBrowserDialog1.ShowDialog() != DialogResult.OK)
{
return;
}
LastSelectedFolder.GlobalVar = folderBrowserDialog1.SelectedPath.ToString();
if (debug)
{ txt_FileInfo.AppendText("Path is selected " + LastSelectedFolder.GlobalVar + Environment.NewLine); }
string[] fileNames = null;
if (debug)
{ txt_FileInfo.AppendText("Prepare to transfer " + Environment.NewLine); }
if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
{
if (debug)
{ txt_FileInfo.AppendText("DataFormats.FileDrop " + Environment.NewLine); }
fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string fileName in fileNames)
{
// do what you are going to do with each filename
string destinationFile = Path.Combine(folderBrowserDialog1.SelectedPath, Path.GetFileName(fileName));
if (debug)
{ txt_FileInfo.AppendText("Destination File " + destinationFile + Environment.NewLine); }
if (Operation.CopyFile(fileName, destinationFile, ci))
{
txt_FileInfo.AppendText("File have been copied to " + destinationFile + Environment.NewLine);
}
}
}
else if (e.Data.GetDataPresent("FileGroupDescriptor"))
{
if (debug)
{ txt_FileInfo.AppendText("FileGroupDescriptor " + Environment.NewLine); }
OutlookDataObject dataObject = new OutlookDataObject(e.Data);
string[] filenames = (string[])dataObject.GetData("FileGroupDescriptor");
for (int fileIndex = 0; fileIndex < filenames.Length; fileIndex++)
{
if (debug)
{ txt_FileInfo.AppendText("Files in attachement " + filenames[fileIndex] + Environment.NewLine); }
string path = Path.GetTempPath();
// put the zip file into the temp directory
string theFile = path + filenames[fileIndex].ToString();
// create the full-path name
if (debug)
{ txt_FileInfo.AppendText("Get temp Path " + theFile + Environment.NewLine); }
//
// Second step: we have the file name.
// Now we need to get the actual raw
// data for the attached file and copy it to disk so we work on it.
//
// get the actual raw file into memory
MemoryStream ms = (MemoryStream)e.Data.GetData(
"FileContents", true);
// allocate enough bytes to hold the raw data
byte[] fileBytes = new byte[ms.Length];
// set starting position at first byte and read in the raw data
ms.Position = 0;
ms.Read(fileBytes, 0, (int)ms.Length);
// create a file and save the raw zip file to it
FileStream fs = new FileStream(theFile, FileMode.Create);
fs.Write(fileBytes, 0, (int)fileBytes.Length);
fs.Close(); // close the file
FileInfo tempFile = new FileInfo(theFile);
// always good to make sure we actually created the file
if (tempFile.Exists == true)
{
// for now, just delete what we created
string fileName = tempFile.FullName;
string destinationFile = Path.Combine(folderBrowserDialog1.SelectedPath, Path.GetFileName(fileName));
if (debug)
{ txt_FileInfo.AppendText("destinationFile " + destinationFile + Environment.NewLine); }
if (debug)
{ txt_FileInfo.AppendText("Prepare to copy " + destinationFile + Environment.NewLine); }
if (Operation.CopyFile(fileName, destinationFile, ci))
{
txt_FileInfo.AppendText("File have been copied to " + destinationFile + Environment.NewLine);
}
else
{
if (debug)
{ txt_FileInfo.AppendText("Copy failed " + " Source " + fileName + " Destination " + destinationFile + Environment.NewLine); }
}
tempFile.Delete();
if (debug)
{ txt_FileInfo.AppendText("Delete temp file " + tempFile + Environment.NewLine); }
}
else
{ Trace.WriteLine("File was not created!"); }
// catch (Exception ex)
//{
// Trace.WriteLine("Error in DragDrop function: " + ex.Message);
// // don't use MessageBox here - Outlook or Explorer is waiting !
//}
}
}
}
I will replay here quote from here. For above class to work on win 8 + couple of line to be changed (from int to long)
from:
IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));
to
IntPtr fileDescriptorPointer = (IntPtr)((long)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));
from:
fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
to
fileDescriptorPointer = (IntPtr)((long)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
Use this:
MemoryStream ms = (MemoryStream)dataObject.GetData("FileContents", fileIndex);
Instead of this:
MemoryStream ms = (MemoryStream)dataObject.GetData("FileContents", true);
So it parses every files.
EDIT:
Actually, it doesn't work neither unless program is compiled in Debug rather than Release... It will only work in Debug for some reason

IOException: The process cannot access the file 'file path' because it is being used by another process in Console Application in C#

I am running Console_Application-A in which I am calling another Console_Application-B (in which I am creating log file for Error/Exception).
But when I am running Console_Application-B individually its working properly but when I am running Console_Application-A at that time I am getting an Exception when Application need to write an Error in log file.(Error.txt).
IOException: The process cannot access the file 'Error.txt' because it
is being used by another process
please guide me in this issue.
Code for Writing Error log
public static bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
if (stream != null)
stream.Close();
}
return false;
}
catch (Exception e)
{
string filePath =Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\Error.txt";
FileInfo FInfo = new FileInfo(filePath);
var FileState = IsFileLocked(FInfo);
while (FileState){
FileState = IsFileLocked(FInfo);
}
if (!FileState){
using (StreamWriter writer = new StreamWriter(filePath, true))
{
writer.WriteLine("Message :" + e.Message + "<br/>" + Environment.NewLine + "StackTrace :" + e.StackTrace +"" + Environment.NewLine + "Date :" + DateTime.Now.ToString());
writer.WriteLine(Environment.NewLine + "-----------------------------------------------------------------------------" + Environment.NewLine);
writer.Dispose();
}
}
}
There is no need first to check if the file is locked and then access it, as between the check and the access some other process may still get a lock on the file.
using System;
using System.IO;
class DirAppend
{
public static void Main()
{
using (StreamWriter w = File.AppendText("log.txt"))
{
Log("Test1", w);
Log("Test2", w);
}
using (StreamReader r = File.OpenText("log.txt"))
{
DumpLog(r);
}
}
public static void Log(string logMessage, TextWriter w)
{
w.Write("\r\nLog Entry : ");
w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
DateTime.Now.ToLongDateString());
w.WriteLine(" :");
w.WriteLine(" :{0}", logMessage);
w.WriteLine ("-------------------------------");
}
public static void DumpLog(StreamReader r)
{
string line;
while ((line = r.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
Source - https://msdn.microsoft.com/en-us/library/3zc0w663(v=vs.110).aspx

Not able to write a Text on txt File using C#

I have tried to write a string on text file,but its not writing anything and there is no exceptions. My code is:
public void CreateLog(string sLogInfo)
{
string sDestionation = null;
string sFileName = DateTime.Now.ToString("yyyyMMdd") + "_log.txt";
sDestionation = #"D:\Log\";
//sDestionation = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + ConfigurationManager.AppSettings["DestinationPath"].ToString();
string sFile = sDestionation + sFileName;
if (!System.IO.Directory.Exists(sDestionation))
{
System.IO.Directory.CreateDirectory(sDestionation);
}
StreamWriter oWriter = null;
if (!System.IO.File.Exists(sFile))
{
oWriter = File.CreateText(sFile);
}
else
{
oWriter = File.AppendText(sFile);
}
oWriter.WriteLine(DateTime.Now.ToString() + ": " + sLogInfo.Trim());
}
StreamWriter is IDisposable object. You should dispose it after using. For this you can use using statement like this:
public void CreateLog(string sLogInfo)
{
string sDestionation = null;
string sFileName = DateTime.Now.ToString("yyyyMMdd") + "_log.txt";
sDestionation = #"D:\Log\";
var sFile = sDestionation + sFileName;
if (!Directory.Exists(sDestionation))
{
Directory.CreateDirectory(sDestionation);
}
using (var oWriter = new StreamWriter(sFile, true))
oWriter.WriteLine(DateTime.Now + ": " + sLogInfo.Trim());
}
Use File.AppendAllText that will do all the steps (except creating folder) for you.
Otherwise you should properly dispose writer when you are done, preferably with using in the same function:
using(oWriter)
{
oWriter.WriteLine(DateTime.Now.ToString() + ": " + sLogInfo.Trim());
}
Your code looks fine, however, I think you should add at the end of it the following:
oWriter.Close()
You should flush (disposing is enough) your data into the file at the end of your code:
oWriter.Flush(); //Save (Clears all buffers for the current writer and causes any buffered data to be written to the underlying stream.)
oWriter.Dispose(); //Then free this resource
As Yuval mentioned looking at C#'s StreamWriter.cs class it does indeed calls the Flush method internally. See here: Reference

Compress file - Sharing violation on path

I currentlywork on an android application, and I have to develop a function to compress files into directory.
To get all the files, I use the DirectoryInfo() and FileInfo() class and then the ZipArchive() and ZipArchiveEntry() class to create my .zip file.
The problem I have is when I open the file to compress with a FileStream to copy data into my ZipArchive entry. I got a sharing violation on path error when I use the OpenRead() function.
I already check the permissions in my Manifest and try several methods like ZipFile.CreateFromDirectory but I still have the same problem.
Thank you by advance for your help.
Here is my code :
public void Compress(DirectoryInfo directory)
{
string identifiantSC = currentSceneSelected.Id_Scene;
string typeSceneSelected = currentSceneSelected.type_Scene;
if (!Directory.Exists (Path.Combine (pathProject, "Archive"))) {
Directory.CreateDirectory (Path.Combine (pathProject, "Archive"));
}
string pathSceneDir = Path.Combine (pathProject, typeSceneSelected + "_" + identifiantSC);
string pathZipDir = Path.Combine (pathProject, "Archive");
foreach (var fileToCompress in directory.GetFiles ()) {
if (!File.Exists (Path.Combine (pathZipDir, typeSceneSelected + "_" + identifiantSC + ".zip"))) {
try {
var fileZip = new FileStream (Path.Combine (pathZipDir, typeSceneSelected + "_" + identifiantSC + ".zip"), FileMode.Create);
archive = new ZipArchive (fileZip, ZipArchiveMode.Create);
ZipArchiveEntry readmeEntry = archive.CreateEntry (fileToCompress.Name, CompressionLevel.Optimal);
FileStream originalFileStream = fileToCompress.OpenRead();
originalFileStream.CopyTo (readmeEntry.Open ());
} catch (FileLoadException e){
Console.WriteLine ("FILE LOAD EXCEPTION : " + e);
} catch (AccessViolationException e){
Console.WriteLine ("ACCESS VIOLATION EXCEPTION : " + e);
} catch (UnauthorizedAccessException e){
Console.WriteLine ("ACCESS EXCEPTION : " + e);
}
}
else {
using (var fileZip = new FileStream (Path.Combine (pathZipDir, typeSceneSelected + "_" + identifiantSC + ".zip"), FileMode.Open)) {
using (archive = new ZipArchive (fileZip, ZipArchiveMode.Update)) {
ZipArchiveEntry readmeEntry = archive.CreateEntry (fileToCompress.Name, CompressionLevel.Optimal);
FileStream originalFileStream = fileToCompress.OpenRead ();
originalFileStream.CopyTo (readmeEntry.Open ());
originalFileStream.Close ();
}
}
}
}
}

Disposing File Object Properly

Ok so heres the thing. When ever a trigger is hit i append my logs in a specific folder. The code works fine and it appends it correctly but if i try to manually delete the folder from the desktop its giving a "The action cannot be completed cause the folder/file is open in another program";
i guess im not disposing it right but i dont know where i missed it. I know its the folder that is attached to the process cause i tried to delete the .log file inside and it allowed me.
private void LogEvent(string filename,bool AppendTxt,string msg)
{
string sLogFormat = DateTime.Now.ToShortDateString().ToString() + " " + DateTime.Now.ToLongTimeString().ToString() + " ==> ";
msg = sLogFormat + msg;
// create directory
if (System.IO.Directory.Exists("C:\\Users\\DT-Npax\\Desktop\\LOGS1") != true)
{
Directory.CreateDirectory("C:\\Users\\DT-Npax\\Desktop\\LOGS1");
}
string dailyLog = "C:\\Users\\DT-Npax\\Desktop\\LOGS1" + "\\" + filename + ".log";
FileStream FS = null;
//write or append txt
if (!AppendTxt)
{
if (File.Exists(dailyLog))
{
File.Delete(dailyLog);
}
using (FS = File.Create(dailyLog)) { }
FS.Close();
StreamWriter TXT_WRITE = new StreamWriter(dailyLog);
TXT_WRITE.WriteLine(msg);
TXT_WRITE.Close();
}
else
{
if (!File.Exists(dailyLog))
{
using (FS = File.Create(dailyLog)) { }
FS.Close();
}
FileStream FSAppend = new FileStream(dailyLog, FileMode.Append, FileAccess.Write);
StreamWriter TXT_WRITE = new StreamWriter(FSAppend);
TXT_WRITE.WriteLine(msg);
TXT_WRITE.Close();
FSAppend.Close();
}
}
Your code does seem to close the file properly but not in an exception-safe manner.
You also have some unnecessary code in there (like using (FS = File.Create(dailyLog)) { } FS.Close(); ).
The smallest modification looks like this:
else
{
//if (!File.Exists(dailyLog))
//{
// using (FS = File.Create(dailyLog)) { }
// FS.Close();
//}
using (FileStream FSAppend = new FileStream(dailyLog, FileMode.Append, FileAccess.Write))
using (StreamWriter TXT_WRITE = new StreamWriter(FSAppend))
{
TXT_WRITE.WriteLine(msg);
}
//TXT_WRITE.Close();
//FSAppend.Close();
}
But I would rewrite this whole method like:
private void LogEvent(string filename,bool AppendTxt,string msg)
{
string sLogFormat = DateTime.Now.ToShortDateString().ToString() + " "
+ DateTime.Now.ToLongTimeString().ToString() + " ==> ";
msg = sLogFormat + msg;
// create directory
if (System.IO.Directory.Exists("C:\\Users\\DT-Npax\\Desktop\\LOGS1") != true)
{
Directory.CreateDirectory("C:\\Users\\DT-Npax\\Desktop\\LOGS1");
}
string dailyLog = "C:\\Users\\DT-Npax\\Desktop\\LOGS1" + "\\" + filename + ".log";
if (AppendText)
System.IO.File.AppendAllText(dailylog, msg);
else
System.IO.File.WriteAllText(dailylog, msg);
}
There is no need to pre-create or delete files.
Wrap the streams in a using block since they implement IDisposable.
I must say this code is a little odd...
using (FS = File.Create(dailyLog)) { }
FS.Close();
StreamWriter TXT_WRITE = new StreamWriter(dailyLog);
TXT_WRITE.WriteLine(msg);
TXT_WRITE.Close();
Shouldn't it be something like:
using (FileStream FS = File.Create(dailyLog))
{
using(StreamWriter TXT_WRITE = new StreamWriter(dailyLog))
{
TXT_WRITE.WriteLine(msg);
}
}

Categories

Resources