Why file access is denied - c#

I have the following code which...
Checks if a folder exists
If it exists, check if a file exists
if file exists, read all the lines from the file
once all the line has been read, show the length of the line in a messagebox
Code:
private void button2_Click(object sender, EventArgs e)
{
strPath = #"C:\QRXS";
string strFile = #"C:\QRXS\download.lst";
if (Directory.Exists(strPath))
{
try
{
if (File.Exists(strFile))
{
try
{
ln = File.ReadAllLines(strPath);
}
catch (Exception ex)
{
// inform user or log depending on your usage scenario
MessageBox.Show(ex.Message, "FILE ACCESS");
}
if (ln != null)
{
MessageBox.Show(ln.Length + "");
// do something with lines
}
}
}
catch (Exception ce)
{
MessageBox.Show(ce.Message, "FOLDER ACCESS");
}
}
}
Everytime I run the application (used Run as Administrator as well), the following line keeps being invoked:
MessageBox.Show(ex.Message, "FILE ACCESS");
How can I fix it?

Replace:
File.ReadAllLines(strPath);
with:
File.ReadAllLines(strFile);
Reason: strPath denotes a directory. You're trying to read its contents as if it were a file, and that obviously won't work.

You need to use :
File.ReadAllLines(strFile);

Related

C# - Using loop to open dialog box

I'm trying to make a program that loads a configuration file from another application.
If the file exists, it loads it and displays a message, but if the configuration file is not valid, it displays an error message and then opens a dialog box to load the correct file. But if the user reloads the wrong file, the same dialog box should appear again but that's when my code fails.
Similarly, if the file did not exist from the beginning, it displays a dialog box to load the file, but if it is given to cancel the dialog box or an incorrect file is selected again, my code fails.
I know that the solution would be to use loops but I'm not sure how to structure it.
Pd: searchfile() is my function to open dialog box and readconfig() is my function to read config file of another application.
strfilenamepath = #"C:\Users\test\dogs.exe.config";
if (File.Exists(strfilenamepath))
{
onlyFilename = System.IO.Path.GetFileName(strfilenamepath);
textBox1.Text = onlyFilename;
try
{
string[] valores = readConfig(strfilenamepath);
MessageBox.Show(valores[0] + valores[1] + valores[2]);
}
catch (Exception ex)
{
MessageBox.Show("Error loading config file." + ex.Message);
searchFile();
onlyFilename = System.IO.Path.GetFileName(strfilenamepath);
textBox1.Text = onlyFilename;
string[] valores = readConfig(strfilenamepath);
MessageBox.Show(valores[0] + valores[1] + valores[2]);
}
}
else
{
searchFile();
onlyFilename = System.IO.Path.GetFileName(strfilenamepath);
textBox1.Text = onlyFilename;
try
{
readConfig(strfilenamepath);
string[] valores = readConfig(strfilenamepath);
MessageBox.Show(valores[0] + valores[1] + valores[2]);
}
catch (Exception ex)
{
MessageBox.Show("Error loading config file." + ex.Message);
searchFile();
onlyFilename = System.IO.Path.GetFileName(strfilenamepath);
textBox1.Text = onlyFilename;
string[] valores = readConfig(strfilenamepath);
MessageBox.Show(valores[0] + valores[1] + valores[2]);
}
}
It is easier to design it if you extract the reading logic to another method that handles exceptions and returns a Boolean to signal the success and the computed result. The TryDoSomething pattern does exactly this.
In pseudo code
public bool TryReadConfig(string path, out string[] valores)
{
valores = null;
try {
valores = read the values;
return true;
} catch {
Display message;
return false;
}
}
The main loop in pseudo code
strfilenamepath = #"C:\Users\test\dogs.exe.config";
while (true) {
if (File.Exists(strfilenamepath) && TryReadConfig(strfilenamepath, out var valores)) {
Do something with the valores;
break;
}
var ofd = new OpenFileDialog{ ... };
if (ofd.ShowDialog() == DialogResult.OK) {
strfilenamepath = ofd.Filename;
} else {
break; // The user canceled the operation.
}
}
You can do something like this:
try
{
//Code to try open the file to memory
}
catch (Exception ex)
{
while (true)
{
MessageBox.Show(#"Select an valid file");
var path = searchFile();
if (string.IsNullOrWhiteSpace(path))
continue;
try
{
//Code to try open the file to memory
}
catch (Exception ex2)
{
MessageBox.Show(#"The selected file is not valid");
continue;
}
break;
}
}

How to catch a "FileNotFoundException" exception?

I am pretty new to programming and am trying to figure out how to to catch the error "FileNotFoundException." My code is suppose to search for the existing text document (from what is typed into the text box)and load it to my listbox1. I got this problem solved. However, a new problem has arisen! If the user inputs the wrong name/numbers it just crashes the application with the error that it couldn't find the file. Is there any way to get the program to display an error message "File not found." or simply not crash the entire program? Thanks in advance!
private void btnEnter_Click(object sender, EventArgs e)
{
FileInfo file = new FileInfo(txtExisting.Text + ".txt");
StreamReader stRead = file.OpenText();
while (!stRead.EndOfStream)
{
listBox1.Items.Add(stRead.ReadLine());
}
}
You should use a try-catch statement to handle exceptions.
private void btnEnter_Click(object sender, EventArgs args)
{
try
{
FileInfo file = new FileInfo(txtExisting.Text + ".txt");
StreamReader stRead = file.OpenText();
while (!stRead.EndOfStream)
{
listBox1.Items.Add(stRead.ReadLine());
}
}
catch (FileNotFoundException e)
{
// FileNotFoundExceptions are handled here.
}
}
Basically, the code in the try block will be executed as it would normally be but if an error should arise the catch block will be executed, in particular:
When an exception is thrown, the common language runtime (CLR) looks for the catch statement that handles this exception.
This means that a try-catch statement can have multiple catch blocks if you expect to encounter different types of exceptions so they can be handled accordingly.
More information can be found here.
As for UX, it would be nice to communicate to the user that something went wrong by displaying a message.
Just add a try/catch block with your code in the btnEnter_Click function like this:
try
{
//your code here
}
catch (FileNotFoundException ex)
{
MessageBox.Show(ex.Message);//if you want to show the exception message
}
catch (Exception ex1)
{
/* Exceptions other than the above will be handled in this section,
this should be used when you are not aware the type of exception
can occur in your code for a safe side*/
}
Using a try/catch statement :
private void btnEnter_Click(object sender, EventArgs e)
{
try
{
FileInfo file = new FileInfo(txtExisting.Text + ".txt");
StreamReader stRead = file.OpenText();
while (!stRead.EndOfStream)
{
listBox1.Items.Add(stRead.ReadLine());
}
}
catch (FileNotFoundException ex)
{
// Handle exception
}
}
Use System.IO.File.Exist("path\\File.extension");
File.Exists / MSDN
It will return a Boolean value, true for File Found and false for File Not Found.
Use the try/catch statements when you don't WHAT could cause a problem.
Example:
private void btnEnter_Click(object sender, EventArgs e)
{
if(!System.IO.File.Exists(txtExisting.Text + ".txt")
{
MessageBox.Show("File not found");
return;
}
FileInfo file = new FileInfo(txtExisting.Text + ".txt");
StreamReader stRead = file.OpenText();
while (!stRead.EndOfStream)
{
listBox1.Items.Add(stRead.ReadLine());
}
}
FileInfo file = new FileInfo(txtExisting.Text + ".txt");
if (!File.Exists(file.FullName))
{
Console.WriteLine("File Not Found!");
}
else
{
StreamReader stRead = file.OpenText();
while (!stRead.EndOfStream)
{
lenter code hereistBox1.Items.Add(stRead.ReadLine());
}
}

Get the message of manually thrown exception

I'm deliberately throwing an exception for a particular scenario, but I would implicitly like to get the error message in string format. I'm aware that one of the overloads for the following exception is string message, but how do I access that string?
Here is the relevant snippet:
string errMsg;
private void Compress()
{
if (sourcePath.EndsWith(".zip"))
{
throw new FileLoadException
("File already compressed. Unzip the file and try again.");
errMsg = //I want the above string here
}
}
Do you mean this:?
try
{
throw new FileLoadException
("File already compressed. Unzip the file and try again.");
}
catch (Exception ex)
{
errMsg = ex.GetBaseException().Message;
}
You can't access the string THERE I'll explain a bit there:
string errMsg;
private void Compress()
{
if (sourcePath.EndsWith(".zip"))
{
throw new FileLoadException
("File already compressed. Unzip the file and try again.");
// The following line is unreachable as the throw ends the function and gets the exception to the calling function as there is no try catch block to catch the exception.
errMsg = //I want the above string here
}
}
A possibility would be to try/catch the exception in the method where you want to set the variable:
private void Compress()
{
if (sourcePath.EndsWith(".zip"))
{
try
{
throw new FileLoadException
("File already compressed. Unzip the file and try again.");
}
catch (Exception e)
{
errMsg = e.Message;
}
}
}
Or to catch the exception in the calling method instead:
try
{
Compress();
}
catch (Exception e)
{
}
regardless of method used the e.Message gives you the message of the exception as a string.
There is no point to try catch the exception and set the message. Unless you re-throw it
try
{
throw new FileLoadException("File already compressed. Unzip the file and try again.");
}
catch (Exception ex)
{
errMsg = ex.GetBaseException().Message;
throw;
}
I would rather do this
private void Compress()
{
if (sourcePath.EndsWith(".zip"))
{
errMsg = "File already compressed. Unzip the file and try again.";
return;
}
}
Not sure I 100% understand but if you want the message from that exception you can catch it and examine the Exception.Message
try
{
throw new FileLoadException("Custom error string");
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
here should be an solution for you :)
if (sourcePath.EndsWith(".zip"))
{
FileLoadException ex = new FileLoadException("File already compressed. Unzip the file and try again.");
errMsg = ex.ToString();
}
Console.WriteLine(errMsg);
To throw the exception that you made I would do soemthing like this
static string sourcePath = "test.zip"; //hardcoded file
static string errMsg; //the error string
private static void Compress()
{
try
{
if (!sourcePath.EndsWith(".zip"))
{
Console.WriteLine("File doesn't end with zip so it can be compressed"); //if it does not end with zip its rdy for compressing and here you can indput your code to compress
}
else
{
throw new Exception(); //instead of using try catch you can also generate the code in here instead of throwing an exception.
//when throwing a new exception you make it stop the if setting and jump into the catch if you use break it wont enter the catch but instead it will just jump over it.
}
}
catch
{
//Here it will generate the custom exception you wanted and put it inside the errMsg
errMsg = new FileLoadException("File already compressed. Unzip the file and try again.").ToString();
Console.WriteLine(errMsg);
}
ofc this is made in console that is why I use the console.writeline you can just change those out

Copy File in local Network

This is a web application
I have 2 pc's: A: 192.168.1.200 and B: 192.168.1.201, I want copy from A to B, this code working is single pc, but it's not working in network.
protected void Button1_Click(object sender, EventArgs e)
{
string sourcePath = #"D:\Source\";
string[] filePaths = Directory.GetFiles(sourcePath, "*.txt");
foreach (string a in filePaths)
{
CopyFiles(a, a.Replace("D:\\Source\\", "D:\\Source1\\New\\"));
//CopyFiles(a, a.Replace("D:\\Source\\", "192.168.1.201\\Source1\\New\\"));
}
}
private bool CopyFiles(string Source, string Destn)
{
try
{
if (File.Exists(Source) == true)
{
File.Copy(Source, Destn);
return true;
}
else
{
Response.Write("Source path . does not exist");
return false;
}
}
catch (FileNotFoundException exFile)
{
Response.Write("File Not Found " + exFile.Message);
return false;
}
catch (DirectoryNotFoundException exDir)
{
Response.Write("Directory Not Found " + exDir.Message);
return false;
}
catch (Exception ex)
{
Response.Write(ex.Message);
return false;
}
}
Try with:
CopyFiles(a, a.Replace("D:\\Source\\", "\\192.168.1.201\\Source1\\New\\"));
You also need to make sure that the Source1 folder is shared on B, and that you have write access to it.
Did you create the Windows share "Source1" on the receiver machine?
If you did, I would try to mount it on your sender machine and change the code to:
CopyFiles(a, a.Replace("D:\\Source\\", "\\\\192.168.1.201\\Source1\\New\\"));
You have to be allowed to write on the target machine. A work round can be used here, you can make a virtual drive pointing to a network place e.g Z:. Now you can use local notation. But before anything, get sure about permissions on the remote pc.

C# linq Files.ReadAllLines() fails for large 650MB CSV file

The following code works when I work with CSV files under 1MB but fails when I try to read 600MB file. Any reason why? Or any fixes?
What I am trying to do is read a large raw CSV file in Visual C# 2010 and manipulate the contents, could be line by line or to memory at one go and export 5 files with certain selections using LINQ. These 5 files are to be used in various processes so need them to be split into 5 different files with very different content.
When the file is small the codes work perfect but when it's too big it gives me the messagebox from Exception handling "Cannot write to source destination". I have tried both ReadAllLines() and ReadLines() Please could you advise me. Thanks.
public void button2_Click(object sender, EventArgs e)
{
string file_name = textBox1.Text.ToString();
// Get the directories to split the file in.
string directoryPath = Path.GetDirectoryName(textBox1.Text.ToString());
if (File.Exists(file_name) == true)
{
try
{
StreamReader readerfile = new StreamReader(file_name);
var BillSummaryQuery1 =
(from line in File.ReadAllLines(file_name)
let linerecord = line.Split(',').ToList()
select line).ToList();
#region Start Writing BillSummary.CSV
//lines removed
#endregion End writing BillSummary.CSV
#region Start writing Notes.CSV
//lines removed
#endregion Notes.CSV
string message =
"Bill Translated Successfully! \r\nFiles located in: " + directoryPath;
MessageBox.Show(message, "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception)
{
string message2 = "Cannot write to source destination";
MessageBox.Show(message2, "Error");
}
}
else
{
MessageBox.Show("No such file exists","Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
If you are using a StreamReader, why don't use it ?
public void button2_Click(object sender, EventArgs e)
{
string file_name = textBox1.Text.ToString();
// Get the directories to split the file in.
string directoryPath = Path.GetDirectoryName(textBox1.Text.ToString());
if (File.Exists(file_name) == true)
{
try
{
using (StreamReader reader= new StreamReader(file_name))
{
string line = null;
while ((line = reader.ReadLine()) != null)
{
// Do your stuff
}
}
}
catch (Exception ex)
{
Trace.TraceError(ex.Message);
string message2 = "Cannot write to source destination";
MessageBox.Show(message2, "Error");
}
}
else
{
MessageBox.Show("No such file exists", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Rolling your own CSV reader is a waste of time unless the files that you're reading are guaranteed to be very simple. Use a pre-existing, tried-and-tested implementation instead.

Categories