Files are not created when i run this code - c#

I have the following code:
List<String> suma = new List<String>();
if (File.Exists(Application.StartupPath + "/totalsold" + username))
suma = new List<String>(File.ReadAllLines(Application.StartupPath + "/totalsold" + username));
List<String> actual = new List<String>();
if (File.Exists(Application.StartupPath + "/totalsold" + username))
actual = new List<String>(File.ReadAllLines(Application.StartupPath + "/soldproducts" + username));
List<String> sumatotal = new List<String>();
if (File.Exists(Application.StartupPath + "/totalsoldadmin"))
sumatotal = new List<String>(File.ReadAllLines(Application.StartupPath + "/totalsoldadmin"));
StreamWriter vanzare = new StreamWriter(Application.StartupPath + "/soldproducts" + username);
StreamWriter total = new StreamWriter(Application.StartupPath + "/totalsold" + username);
StreamWriter totall = new StreamWriter(Application.StartupPath + "/totalsoldadmin");
Why the files vanzare,total and totall are not created after the code below is executed ?
vanzare.WriteLine("Hello World");
total.WriteLine("Helle World again!");
totall.WriteLine("Hello World again and again!");
Problem solved!

Do you close the file? Writes to files may not immediately occur, since probably both .NET and the OS are caching and thus delaying writes. The file should appear immediately when you open the StreamWriter, though.
For short-term usage of a file (e.g. for writing stuff and then closing it) you should definitely use the using statement:
using (StreamWriter vanzare = new StreamWriter(...)) {
vanzare.WriteLine("Hello World");
}
which will make sure to properly close the file immediately afterwards and not leave any unmanaged resources around longer than they are needed.
If you need to leave the file open for longer than a single method, then of course you have to do that manually. Make sure that when you no longer need the StreamWriter (and other IDisposables) you call the Dispose() method on them.

You are using slashes im your file paths, which might not work, depending on what platform you are using.
Use the Path.Combine method to concatenate the path and the filename, it will use the path separator that is correct for the file system:
string sold = Path.Combine(Application.StartupPath, "totalsold" + username);
if (File.Exists(sold)) {
suma = new List<String>(File.ReadAllLines(sold));
}

Related

How to make 2 process access the same path?

I'm using c#. I'm receiving an error about a path is currently accessed by other processes. What my system is trying to do is to access the path: #"C:\temps\" + client_ids + "_" + rown + ".pdf" and use the same path for attachment before sending it to client's email.
here's what I've done so far. I comment out some of my code because I'm not sure what to do.
FileStream fs = null;
using (fs = new FileStream(#"C:\\temps\\" + client_ids + "_" +
rown + ".pdf",
FileMode.Open,FileAccess.Read,FileShare.ReadWrite))
{
TextReader tr = new StreamReader(fs);
//report.ExportToDisk
//(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat,tr);
//report.Dispose();
//Attachment files = new Attachment(tr);
//Mailmsg.Attachments.Add(files);
//Clients.Send(Mailmsg);
}
you can make temp copy of file before you use it in mail attachment and then use the copy instead of the original file
You cannot attach a file to an email if that file is open. You must close (save) the file first.
While #ali answer is technically correct, it is unnecessary. Why go through the overhead of creating a copy of the file which then needs to be deleted, etc.?
Assuming I understand what you are trying to do correctly, simply move your code for mail to after the file is successfully created and saved. And, I don't think you need the overhead of either the filestream or the textreader. As long as your report object can save the file to disk someplace, you can attach that file to your email message and then send it.
While I do not claim to know anything about how Crystal Decisions handles exports, etc. Perhaps something like this would work:
(I got this code from: https://msdn.microsoft.com/en-us/library/ms226036(v=vs.90).aspx)
private void ExportToDisk (string fileName)
{
ExportOptions exportOpts = new ExportOptions();
DiskFileDestinationOptions diskOpts =
ExportOptions.CreateDiskFileDestinationOptions();
exportOpts.ExportFormatType = ExportFormatType.RichText;
exportOpts.ExportDestinationType =
ExportDestinationType.DiskFile;
diskOpts.DiskFileName = fileName;
exportOpts.ExportDestinationOptions = diskOpts;
Report.Export(exportOpts);
}
You will need to change the ExportFormatType property.
Then, simply attach the file to your email and send:
Attachment Files = new Attachment(filename);
Mailmsg.Attachments.add(files);
Clients.Send(Mailmsg);

Writing files to a path with name incrementation

In a Unity3D script, I have the following that simply writes a file (an image) to a path:
var path = Application.persistentDataPath + "/ocr.jpg";
FileOperations.Create(blah, path);
Of course in a static Utility program elsewhere, I have implemented this helper function as follows:
public static void Create(byte[] bytes, string path)
{
var file = File.Open(path, FileMode.Create);
using ( var binary = new BinaryWriter(file) )
{
binary.Write(bytes);
file.Close();
}
}
I realised my implementation would only create one file; i.e. over-write an existing file with the same name (ocr.jpg) so I wrote the following code:
public static void Create(byte[] bytes, string path)
{
if ( !File.Exists(path) )
{
var file = File.Open(path, FileMode.Create);
using ( var binary = new BinaryWriter(file) )
{
binary.Write(bytes);
file.Close();
}
}
else
{
int counter = 1;
path = Application.persistentDataPath + "/ocr" + "_" + counter + ".jpg";
var file = File.Open(path, FileMode.Create);
using ( var binary = new BinaryWriter(file) )
{
binary.Write(bytes);
file.Close();
}
}
}
Then, I realised every time I run the app, the counter is set back to 1, so now my ocr_1.jpg is over-written!
(Never mind that this half-solution is already ugly, because it brings in some Unity-specific stuff. I was hoping not to include the using UnityEngine in my helper utility class.)
Next, I tried to do it recursively, as follows:
public static void Create(byte[] bytes, string path)
{
if ( !File.Exists(path) )
{
var file = File.Open(path, FileMode.Create);
using ( var binary = new BinaryWriter(file) )
{
binary.Write(bytes);
file.Close();
}
}
else
{
int counter = 1;
path = Application.persistentDataPath + "/ocr" + "_" + counter + ".jpg";
Create(bytes, path);
}
}
But I got a StackOverFlow error message. I don't understand why though, because the checking should go on until there is no file with the same name, etc...
Could someone please help me understand what I am doing wrong, and how I can achieve my goal of running the app as many times as I want and getting images created sequentially: ocr.jpg, ocr_1.jpg, ocr_2.jpg, ocr_3.jpg, etc...
Also, it would be great if I find out how to do this in a way that my utility class does not have to include unity-related stuff; i.e. only have using System.IO
In case you pass in a path that already exists and
path = Application.persistentDataPath + "/ocr" + "_" + counter + ".jpg";
also exists, you keep on calling Create method without incrementing counter, hence stack overflow. Consider passing counter value to the recursive create method, and updating it in every iteration, until it hits a filename that doesn't exist.
The reason why you are getting a StackOverflow is due to the filling of the methods Call Stack. In your code, the counter variable is a local variable to the method and is never incremented. Therefore, every time there is a recursive call to the Create method, an identical call (argument-wise) is made.
As a high-level solution, you should do two things:
Track the value of the counter throughout the recursive calls
Make sure to increment the value of the counter with every recursive call of Create
You could track the state of the counter variable either by having it as a global variable (which sometimes is not a good idea) or to keep it part of the Create method arguments.
I was hoping not to include the using UnityEngine in my helper utility
class
You don't have to. You can use its fully qualified name that includes its namespace:
UnityEngine.Application.persistentDataPath
Few things to know:
1.Always catch Exceptions when reading or writing to a file.
2.Don't do something like this: Application.persistentDataPath + "/ocr" + "_" + counter + ".jpg";.
Not a good idea to concatenate file name with "+" since that is not portable across platforms. Use Path.Combine for that.
Here is how I would implement this:
Use PlayerPrefs.SetInt to save the counter. Each time you want to save the image, use PlayerPrefs.GetInt to read the counter then save the image with File.WriteAllBytes. If saving is successful, increment the counter then save it with PlayerPrefs.SetInt.
Roughly something like below:
public static void Create(byte[] dataToSave)
{
//Load old counter
int counter = PlayerPrefs.GetInt("_counter_", 0);
//Concatenate file name
string tempPath = Path.Combine(UnityEngine.Application.persistentDataPath, "ocr");
tempPath = Path.Combine(tempPath, "_");
tempPath = Path.Combine(tempPath, counter.ToString() + ".jpg");
//Create Directory if it does not exist
if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(tempPath));
}
//Debug.Log(path);
try
{
File.WriteAllBytes(tempPath, dataToSave);
Debug.Log("Saved Data to: " + tempPath.Replace("/", "\\"));
//Increment Counter
counter++;
//Save current Counter
PlayerPrefs.SetInt("_counter_", counter);
PlayerPrefs.Save();
}
catch (Exception e)
{
Debug.LogWarning("Failed To PlayerInfo Data to: " + tempPath.Replace("/", "\\"));
Debug.LogWarning("Error: " + e.Message);
}
}

Using TextWriter with StreamWriter and Reading/Writing Simultaneously

As the title suggests, I'm attempting to read and write to a file at the same time. I have researched this topic but the answers I have found don't seem to work for me because of the circumstances in my program. I am using multiple FileSystemWatchers to track a large amount of files that are constantly passing through a flow in my network. As the files pass through each part of my flow, a text file is updated(one text file per spot in the flow) that marks the name of the file and the time it was created within the folder. It is unpredictable when files might be passing through, and when they might be writing to the tracker text files. My goal is to be able to read and write to the file simultaneously, in case a user attempts to read to from a text file that is being written to at the exact same time. How would I accomplish this?
//Write to File
private void WriteToFile(string info,string path,string tr)
{
if (!File.Exists(path+#"\"+#tr))
{
var myFile =
File.Create(path + #"\" + #tr);
myFile.Close();
TextWriter tw = new StreamWriter(path + #"\" + #tr, true);
tw.WriteLine(info,true);
tw.Close();
}
else if (File.Exists(path + #"\" + #tr))
{
TextWriter tw = new StreamWriter(path + #"\" + #tr, true);
tw.WriteLine(info);
tw.Close();
}
}
The circumstances you are alluding to seem to say that while multiple attempts can be made to read/write the file at a given time, you still want to ensure that the operations are performed one after another in the correct order that the read or writes got called.
One simple method of ensuring that the read and write operations are synchronized would be to just put a lock or Monitor around the methods. Try the following code for your write method:
private readonly object _locker = new object();
// write the file
private void WriteToFile(string info, string path, string tr)
{
Monitor.Enter(this._locker);
try
{
if (!File.Exists(path + #"\" + #tr))
{
var myFile =
File.Create(path + #"\" + #tr);
myFile.Close();
TextWriter tw = new StreamWriter(path + #"\" + #tr, true);
tw.WriteLine(info, true);
tw.Close();
}
else if (File.Exists(path + #"\" + #tr))
{
TextWriter tw = new StreamWriter(path + #"\" + #tr, true);
tw.WriteLine(info);
tw.Close();
}
}
finally
{
Monitor.Exit(this._locker);
}
}
Then, I would use a very similar construct for reading the file.
// read the file
private string ReadFile(string path)
{
Monitor.Enter(this._locker);
try
{
// read the file here...
}
finally
{
Monitor.Exit(this._locker);
}
}
What the Monitor will do is ensure that the file will not be read until an on-going write operation is complete (and vice-versa). This will ensure that you will not get the old data when you read it, and you will also not over-write the new data (which has not yet been read). This method verifies the integrity of your files at all times.

program not writing to file but will write to console in c#

I have a C# program and it will not write to a file but does write to console, even though the file write line is before console. i have tried several modifications and run through debug as well, and it never writes to the file or it puts one line in the file only
// Read the file and display it line by line.
System.IO.StreamReader file = new System.IO.StreamReader("urltest.txt");
string myFileName = String.Format("{0}_{1}", DateTime.Now.ToString("yyyyMMddhh"), "-urlcheck.log");
while((line = file.ReadLine()) != null)
{
Uri myUri = new Uri(line);
using (StreamWriter writer = new StreamWriter(myFileName))
try
{
// create the web request and response based on the url that has been
// just read from the file urltest.txt
HttpWebRequest reqFP = (HttpWebRequest)HttpWebRequest.Create(myUri);
HttpWebResponse rspFP = (HttpWebResponse)reqFP.GetResponse();
if (HttpStatusCode.OK == rspFP.StatusCode)
{
// HTTP = 200 - Internet connection available, server online
// Write status of the URL to the log file
writer.WriteLine("================================================================= =========");
writer.WriteLine("Status code of returned: OK " + myUri + " THIS URL IS NOT BLOCKED!");
Console.WriteLine("Status code of returned: OK " + myUri + " THIS URL IS NOT BLOCKED!");
var _uri = myUri.ToString();
string _catstr1 = catURL(_uri);
//regex to get the last 8-9 items of the line and replace them
Regex pat = new Regex(#"</(.*?)a");
string _catstr = pat.Replace(_catstr1, "\x20");
// Write the Catagory of the URL to file and continue
writer.WriteLine("URL " + _catstr);
Console.WriteLine("URL " + _catstr);
}
}
Most anything that writes out to a file should be either within a using block or manually fushed and closed.
using (var writer = ...)
{
// Do your writing
} // <- upon leaving the using block writer will automatically be cleaned up.
Note: I'm not a huge fan of var but as I don't know what class you're using it at least makes a valid example of code
You didn't provide the code for File access, but 99% sure that you didn't close the stream.
call Flush() if you want to force output before you close your writer

getting the path of a MailMessage attachment

I'm using a MailMessage Queue and upon exiting the program I want to save the content of the queue.
I created a temp list and pass the contents of the queue to that. After that use a simple
StreamWriter to write each info out.
The only thing I can't seem to get is the path of the attachment. As far as I know I can't just simply save out the mailmessages so I thought this will work just as well, but if there is simpler/different solution that's great.
List<MailMessage> temp = queue.ToList<MailMessage>();
Stream stream = File.Open("Queue" +".osl", FileMode.Create);
StreamWriter s = new StreamWriter(stream);
foreach (MailMessage x in temp)
{
s.WriteLine(x.From.Address + x.To[0].Address + x.Body + x.Subject + x.Attachments[0].Name);
}
s.Close();
stream.Close();
I know it is an old question, but there is no answer here, and this really works:
(attachmentObject.ContentStream as System.IO.FileStream).Name
In your specific case it would be:
s.WriteLine(x.From.Address + x.To[0].Address + x.Body + x.Subject + (x.Attachments[0].ContentStream as System.IO.FileStream).Name);
Hope it helps somebody!
You can also use:
Path.GetFullPath(x.Attachments[0].Name);

Categories

Resources