Illegal characters in path from class - c#

I'm stuck in a stupid error but I can't figure it out, could you please help me out?
What
I'm trying to create a class that will have several methods which will perform many different regex in a given text file. This text file is passed in from the main program to the class.
The class then consumes the text file and perform each regex where I call from the main program by instantiating each object in the class.
Problem
When I pass the file, I created a function within the class to count the lines of the file and loop through each line counting how many times such regex match happens.
//CountLines Function
static long CountLinesInFile(string f)
{
long count = 0;
using (StreamReader r = new StreamReader(f))
{
string line;
while ((line = r.ReadLine()) != null)
{
count++;
}
return count;
}
}
This CountLines function will provide the lines to be looped through by the object as in:
private string configfile;
public string ConfigFile
{
get { return this.configfile; }
set { this.configfile = value; }
}
public void objects()
{
//Counting Object Group Network
int objCount = Lines(configfile)
.Select(line => Regex.Matches(line, #"object-group network").Count)
.Sum();
//Ending of Counting Object Group Network
}
from the main program Im trying to call the class and get the results by doing this:
Cisco newCisco = new Cisco();
newCisco.ConfigFile = richTextBox1.Text;
newCisco.objects();
I'm getting stuck at the class at the using (StreamReader r = new StreamReader(f)) line with an Illegal characters in path:
Exception:Thrown: "Illegal characters in path." (System.ArgumentException)
A System.ArgumentException was thrown: "Illegal characters in path."
Time: 8/13/2014 1:58:01 AM
Thread:Main Thread[1304]
I know that I'm making a mistake but I can find where, and would appreciate if you could help me finding a solution for this issue.

The error you are receiving is most likely caused by the file name you are trying to open the StreamReader with, which I presume is invalid. Would you please post the filename you are trying to read, if checking it doesn't solve your problem?

Related

Having troubles trying to read and display a text file to the console in c#

I am trying to make a trivia game in c# using a console application. And I am having troubles getting the console to read the file. Currently what its doing is saying that the file could not be read and the the index was outside the bounds of the array. But then everything that is in the text file gets displayed. I am unsure on what I get the file could not be read but then the file gets displayed.
The file is a .txt file and here is what is looks like
What is another name for SuperMan?,the man of steel
What is Superman's only weakness?,kryptonite
What is the name of Batman's secret identity?,bruce wayne
Batman protects what city?,gotham city
How did Spiderman get his superpowers?,bitten by a radioactive sipder
This superheros tools include a bullet-proof braclets and a magic lasso.Who is she?,wonder woman
Which superhero has an indestructible sheild?,captain america
Which superhero cannot transformback into human form?,the thing
What villan got his distinctive appearance form toxic chemicals?,joker
What is the name of the archnemesis of the Fantastic Four?, dr doom
Here is the code that I have for reading and displaying the file.
static void Main(string[] args)
{
string filename = #"C:\Trivia\questions.txt";
List<string> questions = new List<string>();
List<string> answers = new List<string>();
LoadData(filename, questions, answers);
Console.WriteLine();
questions.ForEach(Console.WriteLine);
Console.WriteLine();
answers.ForEach(Console.WriteLine);
}
static void LoadData(string filename, List<string> questions, List<string> answers)
{
try
{
using(StreamReader reader = new StreamReader(filename))
{
string line;
while((line = reader.ReadLine()) != null)
{
string[] lineArray = line.Split(',');
string annswer = lineArray[1];
string question = lineArray[0];
questions.Add(question);
answers.Add(annswer);
}
}
}
catch(Exception e)
{
Console.WriteLine("File could not be read");
Console.WriteLine(e.Message);
}
}
Here is the output on the console.
File could not be read
Index was outside the bounds of the array.
What is another name for SuperMan?
What is Superman's only weakness?
What is the name of Batman's secret identity?
Batman protects what city?
How did Spiderman get his superpowers?
This superheros tools include a bullet-proof braclets and a magic lasso.Who is she?
Which superhero has an indestructible sheild?
Which superhero cannot transformback into human form?
What villan got his distinctive appearance form toxic chemicals?
What is the name of the archnemesis of the Fantastic Four?
the man of steel
kryptonite
bruce wayne
gotham city
bitten by a radioactive sipder
wonder woman
captain america
the thing
joker
dr doom
Thanks for the suggestions.
From playing around with your code, it looks like you might have some newlines at the end of your questions.txt file. Getting rid of those would fix your initial problem, but the real issue is that you're not checking each line to see if it contains a comma, nor are you discarding empty rows of data. Here's an approach that does both:
static void LoadData(string filename, List<string> questions, List<string> answers)
{
try
{
using (StreamReader reader = new StreamReader(filename))
{
string[] lines=
reader.ReadToEnd() //Read the whole file
.Trim() //Get rid of whitespace at the beginning and end of the file, no more random newlines at the end.
.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries) //Separate each line AND remove any empty lines.
;
foreach (string _line in lines)
{
string line = _line.Trim();
if (!line.Contains(','))
{
Console.Error.WriteLine("!!! Line did not contain comma for separation");
Console.Error.WriteLine("!!!!!! " + line);
continue; //Just go on to the next line.
}
string[] lineArray = line.Split(',');
string answer = lineArray[1];
string question = lineArray[0];
questions.Add(question);
answers.Add(answer);
}
}
}
catch (Exception e)
{
Console.WriteLine("File could not be read");
Console.WriteLine(e.Message);
}
}
Of course if you want to read each line in separately, just check each line to make sure that it has any length after being trimmed (skip it if not) and that it contains a comma (log the error)
I suspect that there's a blank line (or at least a line without a comma) at the end of the file, and then this line: string annswer = lineArray[1]; is throwing an exception because you've hard-coded index 1 without first checking the size of the lineArray. Then the error is shown, but only after the questions and answers have been populated, so you also see those output to the console.
To avoid this, it's a general good practice is to ensure that an array index exists before checking it. Something like this might be helpful:
while ((line = reader.ReadLine()) != null)
{
string[] lineArray = line.Split(',');
// If this line doesn't contain a comma, then skip it
if (lineArray.Length < 2) continue;
string annswer = lineArray[1];
string question = lineArray[0];
questions.Add(question);
answers.Add(annswer);
}
Alternatively, you could throw an exception:
// If this line doesn't contain a comma, throw an exception
if (lineArray.Length < 2)
{
throw new FormatException($"This line does not contain a comma: {line}");
}
Additionally, you could simplify your code slightly by using the System.IO.File class to read the file:
static void LoadData(string filename, List<string> questions, List<string> answers)
{
try
{
foreach (var line in File.ReadLines(filename))
{
var lineArray = line.Split(',');
// If this line doesn't contain a comma, skip it
if (lineArray.Length < 2) continue;
questions.Add(lineArray[0]);
answers.Add(lineArray[1]);
}
}
catch (Exception e)
{
Console.WriteLine($"Error reading file: {e.Message}");
}
}
This is one of technique to handle exception.
I've tried your code but it works well.
Apply my code it and look my comment.
static void LoadData(string filename, List<string> questions, List<string> answers)
{
string readText = ""; //for writing error at catch clause.
try
{
using (StreamReader reader = new StreamReader(filename))
{
string line;
while ((line = reader.ReadLine()) != null)
{
readText = line; //copy text line which is current.
string[] lineArray = line.Split(',');
string annswer = lineArray[1];
string question = lineArray[0];
questions.Add(question);
answers.Add(annswer);
}
}
}
catch (Exception e)
{
//print error with problem text.
Console.WriteLine("File could not be read from : {0}", readText);
Console.WriteLine(e.Message);
}
}
Also, this is another,
Move to : Menu -> DEBUG -> Windows -> Exception settings.
And then check "Common Language Runtime Exception".
This will allow stop where occur problem. It doesn't matter that is in try~catch clause or not.
This is one of best way to find problem in loop statement.

VisualStudio Express 2012: StreamReader gives [System.UnauthorizedAccessException] error

I have read a lot of answers on this issue, but none of them helps for me.
Now, it's been 5 years that I had C# and apperantly I've forgotten it all. But I like to get into the language again to use it for automation. So, here is the bit of code I already have:
{
string path = #"C:\Users\decraiec\Documents\Client Automated";
//In this folder I will find all my XML files that I just want to load in a textbox
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//create a way to read and write the files
//go get the files from my harddrive
StreamReader FileReader = new StreamReader(path);
//make something readable for what you have fetched
StreamWriter FileWriter = new StreamWriter(textBox1.ToString());
int c = 0;
while (c == FileReader.Read())
{
string load = FileReader.ReadToEnd();//read every xmlfile up to the end
string stream = FileWriter.ToString();//make something readable
}
try
{
textBox1.Text = FileWriter.ToString();//what you have made readable, show it in the textbox
FileWriter.Close();
}
finally
{
if (FileReader != null)
{ FileReader.Close(); }
}
if (FileWriter != null)
{ FileWriter.Close(); }
}
}
If I run this code like this I'll get:
An unhandled exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.dll
Additional information: Access to the path 'C:\Users\decraiec\Documents\Atrias Automated' is denied.
While I was hoping to see all the XML files in the textbox listed and clickable ( - although I need to insert the clickable code yet )
I've been looking in my folder and subfolder and files and I do have admin rights on everything. About the [ mscorlib.dll ] I have no clue where to find this.
Now if I wrap the StreamReader in a use ( var....;) VS doesn't recognizes it (red lines under the words) saying that I'm missing an instance of an object or something else of issue (just trying to glue the things together).
Could someone try to get me in the right direction please?
I think your path is a directory, not a file. Almost the exact same issue was addressed here: Question: Using Windows 7, Unauthorized Access Exception when running my application
What you can do is create a DirectoryInfo object on the path and then call GetFiles on it. For example:
DirectoryInfo di = new DirectoryInfo(directoryPath);
Foreach(var file in di.GetFiles())
{
string pathToUseWithStreamReader = file.FullName;
}
You need to use Directory.GetFiles to get any files residing in your "Client Automated" folder, then loop through them and load every single file into the stream.
var files = Directory.GetFiles(path);
foreach (var file in files)
{
var content = File.ReadAllText(file);
}
You can read more on it here:
https://msdn.microsoft.com/en-us/library/07wt70x2(v=vs.110).aspx
Also - in general, when working with files or directories like this, it's a good idea to programmatically check if they exist before working with them. You can do it like so:
if (Directory.Exists(path))
{
...
}
Or with files:
if (File.Exists(path))
{
...
}

Quote-Enclosing 600+ CSV files in a directory c#

I currently have this method that can successfully quote-enclose a single CSV file but I am trying to loop through 600+ CSV files in a directory and perform the Quote Enclose method on each one. I am unsure how to do this effectively. Any feedback is appreciated.
Below is my code:
public void QuoteEnclosingCSV()
{
string fileNamePath = Path.GetTempPath() + #"\Reports\*.csv";
var stringBuilder = new StringBuilder();
foreach (var line in File.ReadAllLines(fileNamePath))
{
stringBuilder.AppendLine(string.Format("\"{0}\"", string.Join("\",\"", line.Split(','))));
}
File.WriteAllText(string.Format(fileNamePath, Path.GetDirectoryName(fileNamePath)), stringBuilder.ToString());
}
string marFolder = Path.GetTempPath() + #"\Reports\";
var dir = new DirectoryInfo(marFolder);
foreach (var file in dir.EnumerateFiles("*.csv"))
{
QuoteEnclosingCSV();
}
Below is the error I'm receiving:
Illegal characters in path.
My first step in unraveling this conundrum would be to guess what the error message is trying to tell me. My first guess would be that it's trying to say that the path has illegal characters in it. Did you stop to check what characters were in the path that you get the error on?
I'll show you:
C:\Users\YoungStamos\AppData\Local\Temp\\Reports\*.csv
That's the path you pass to File.ReadAllLines(). The single argument to that method is a path to one single file. You can't have an asterisk (*) in a filename in Windows, because it's a wildcard.
What you seem to be trying to do is pass a parameter to QuoteEnclosingCSV(). In this loop, you carefully list each file, but you never tell QuoteEnclosingCSV() about any of them.
foreach (var file in dir.EnumerateFiles("*.csv"))
{
QuoteEnclosingCSV();
}
This is more like what you want:
public void QuoteEnclosingCSV(string fileNamePath)
{
var stringBuilder = new StringBuilder();
foreach (var line in File.ReadAllLines(fileNamePath))
{
stringBuilder.AppendLine(string.Format("\"{0}\"", string.Join("\",\"", line.Split(','))));
}
// I don't know what string.Format() is meant to do here; I'm guessing your guess is
// as good as mine, so I'm eliminating it.
//File.WriteAllText(string.Format(fileNamePath, Path.GetDirectoryName(fileNamePath)), stringBuilder.ToString());
File.WriteAllText(fileNamePath, stringBuilder.ToString());
}
And then call it like this:
string marFolder = Path.Combine(Path.GetTempPath(), "Reports");
var dir = new DirectoryInfo(marFolder);
foreach (var fileInfo in dir.EnumerateFiles("*.csv"))
{
QuoteEnclosingCSV( fileInfo.FullName );
}

C# TargetInvocationException and FormatException

Ok, I have a really weird situation happening here. First I need to give some background. I'm creating AI agents for a game that was made on the XNA engine. The way things are set up, people are supposed to use the agent's framework to generate a .dll that the game then uses to load the agents when it runs.
I have access to the code of the game (so I can see what's happening) and at this point I'm using someone else's agents as a starting point for my own. Recently, there were a few changes to the game (and consequentially, the framework), mostly in names of classes and interfaces which means I have to bring the agents up to speed. So, after I made all the updates necessary to be able to compile the agents with the new version of the framework, I came up with a problem. This is the code for the game loading the .dll
// dynamically load assembly from file GeometryFriendsAgents.dll
Assembly agentsDLL = Assembly.LoadFile(path);
// get type of classes BallAgent and SquareAgent from just loaded Assembly
Type circleType = AgentsDLL.GetType("GeometryFriendsAgents.CircleAgent");
Type rectangleType = AgentsDLL.GetType("GeometryFriendsAgents.RectangleAgent");
try {
// create instances of classes BallAgent and SquareAgent
npcCircle = (ICircleAgent)Activator.CreateInstance(circleType);
npcRectangle = (IRectangleAgent)Activator.CreateInstance(rectangleType);
}catch(TargetInvocationException e){
throw e.InnerException;
}
I can confirm that the path is correct. The lines inside the try/catch will throw a TargetInvocationException when I try to run the game (Which will automatically load the agents). I added the try/catch to see the inner exception, which is a FormatException, and VisualStudio gives the aditional information that the input string was not in the correct format.
I don't know what part of the agents code would be relevant for this, but I have yet to get to the weird part. In the implementation I'm using, the agents make use of a LearningCenter class. This class essentially reads and writes the learning files of the agents. at the start of the class it stores the path for the learning files:
protected const string path = #"..\..\..\..\Agents\";
So here's where things get weird. This is the correct path for the learning files. When earlier I made a mistake, I had this path (which before was repeated many times throughout the code) as
protected const string path = #"..\..\..\..\Agents";
When I build the .dll with the incorrect path, I can sucessfully load the agents and it will run the game. The problem then is that the path is incorrect, and when the LearningCenter tries to write the learning file, it will evidently fail with a DirectoryNotFoundException. The method in question is:
public void EndGame(float knownStatesRatio) {
if (_toSave) {
FileStream fileStream = new FileStream(path + _learningFolder + "\\Ratios.csv", FileMode.Append);
StreamWriter sw = new StreamWriter(fileStream);
sw.WriteLine(knownStatesRatio);
sw.Close();
fileStream.Close();
fileStream = new FileStream(path + _learningFolder + "\\IntraPlatformLearning.csv", FileMode.Create);
DumpLearning(fileStream, _intraplatformPlayedStates);
fileStream.Close();
if (interPlatform) {
fileStream = new FileStream(path + _learningFolder + "\\InterPlatformLearning.csv", FileMode.Create);
DumpLearning(fileStream, _interplatformPlayedStates);
fileStream.Close();
}
}
}
The exception occurs immediatly when creating the new filestream. I've tried shifting the missing \ to the _learningFolder variable, but when I do it goes back to the first problem. So long as the path is incorrect, I can run the game...
I should also mention that before this I initially encountered another TargetInvocationException at the same location. At the time the problem was fixed by changing the visibility of the agent classes to public.
I realize that the thing with the path is probably hiding the actual problem, but I just don't know where to look next.
edit: Here's the stack trace for the first problem
GeometryFriends.exe!GeometryFriends.AI.AgentsManager.LoadAgents() Line 396
GeometryFriends.exe!GeometryFriends.Levels.SinglePlayerLevel.LoadLevelContent() Line 78
GeometryFriends.exe!GeometryFriends.Levels.Level.LoadContent() Line 262
GeometryFriends.exe!GeometryFriends.ScreenSystem.ScreenManager.LoadContent() Line 253
Microsoft.Xna.Framework.Game.dll!Microsoft.Xna.Framework.DrawableGameComponent.Initialize()
GeometryFriends.exe!GeometryFriends.ScreenSystem.ScreenManager.Initialize() Line 221
Microsoft.Xna.Framework.Game.dll!Microsoft.Xna.Framework.Game.Initialize()
GeometryFriends.exe!GeometryFriends.Engine.Initialize() Line 203
Microsoft.Xna.Framework.Game.dll!Microsoft.Xna.Framework.Game.RunGame(bool useBlockingRun)
Microsoft.Xna.Framework.Game.dll!Microsoft.Xna.Framework.Game.Run()
GeometryFriends.exe!GeometryFriends.Program.Main(string[] args) Line 16
The agent that's failing first is the CircleAgent, here's the constructor:
public CircleAgent() {
//Change flag if agent is not to be used
SetImplementedAgent(true);
lastMoveTime = DateTime.Now;
lastRefreshTime = DateTime.Now;
currentAction = 0;
rnd = new Random(DateTime.Now.Millisecond);
model = new CircleWorldModel(this);
learningCenter = new CircleLearningCenter(model);
learningCenter.InitializeLearning();
startTime = DateTime.Now;
}
edit 2: Ok, I managed to zone in on the source of the FormatException.
The error occurs in this method of the CircleLearningCenter (the statement in the first if):
public override void addStateMovementValue(string[] lineSplit, string stateId, ref Dictionary<string, Dictionary<int, double>> lessons) {
if (!lineSplit[1].Equals("0")) {
lessons[stateId].Add(Moves.ROLL_LEFT, double.Parse(lineSplit[1]));
}
if (!lineSplit[2].Equals("0")) {
lessons[stateId].Add(Moves.ROLL_RIGHT, double.Parse(lineSplit[2]));
}
if (!lineSplit[3].Equals("0")) {
lessons[stateId].Add(Moves.JUMP, double.Parse(lineSplit[3]));
}
}
Which is called by this method in the LearningCenter:
private void createLearningFromFile(FileStream fileStream, ref Dictionary<string, Dictionary<int, double>> lessons) {
lessons = new Dictionary<string, Dictionary<int, double>>();
StreamReader sr = new StreamReader(fileStream);
string line;
while ((line = sr.ReadLine()) != null) {
string[] lineSplit = line.Split(',');
string stateId = lineSplit[0];
lessons.Add(stateId, new Dictionary<int, double>());
addStateMovementValue(lineSplit, stateId, ref lessons);
}
}
which in turn is called by this method (which it's called in the constructor of the circle):
public void InitializeLearning() {
if (File.Exists(Path.Combine(Path.Combine(path, _learningFolder), "IntraPlatformLearning.csv"))) {
FileStream fileStream = new FileStream(Path.Combine(Path.Combine(path, _learningFolder),"IntraPlatformLearning.csv"), FileMode.Open);
createLearningFromFile(fileStream, ref _intraplatformLessonsLearnt);
fileStream.Close();
} else {
createEmptyLearning(ref _intraplatformLessonsLearnt);
}
if (File.Exists(Path.Combine(Path.Combine(path, _learningFolder), "InterPlatformLearning.csv"))) {
FileStream fileStream = new FileStream(Path.Combine(Path.Combine(path, _learningFolder), "InterPlatformLearning.csv"), FileMode.Open);
createLearningFromFile(fileStream, ref _interplatformLessonsLearnt);
fileStream.Close();
} else {
createEmptyLearning(ref _interplatformLessonsLearnt);
}
}
In case it's not apparent, CircleLearningCenter is a subclass of LearningCenter. Also, sorry for the text wall, but I'm at my wits end.
Use System.IO.Path.Combine() to con-cat path parts. For example:
instead of :
FileStream(path + _learningFolder + "\\Ratios.csv")
use :
FileStream(Path.Combine(Path.Combine(path , _learningFolder) , "Ratios.csv"))
Just don't forget to remove \\ from each part.
And do the same for other FileStream paths.

Read permission on file denied

I have a problem with reading a bunch of files using the following C# code in my VS2008 project
public void FindFiles()
{
//Root
targetPath = Directory.GetDirectoryRoot(Directory.GetCurrentDirectory()) + "WriteToCSVFolder";
}
public void ReadFiles()
{
fileNameList_Original = Directory.GetFiles(targetPath);
string defaultFileName = "file_";
int counter = 0;
foreach (string fileName in Directory.GetFiles(targetPath))
{
fullFileText_Original[counter] = File.ReadAllText(targetPath);
//fileNameList_Original[counter]
counter++;
}
counter = 0;
}
Now please consider im just fast ticking this so I haven't bothered doing optimizations or anything yet. Just noticed that when I do a read action with the files NOT open and UAC (user account control) disabled on W7 64bit , and also not sharing it over network dropbox or anything else. It's just some ABC BLA FOO files I just made and wanted to test, they are in the correct directory marked targetpath in my system folder and the program is being run from the correct drive.
Is it just something stupid in the code or?
And oh yeah , the application was marked as full trust.
Any ideas?
EDIT:
With the new idea implemented from the comment section below:
Changed the code from
public void ReadFiles()
{
fileNameList_Original = Directory.GetFiles(targetPath);
string defaultFileName = "file_";
int counter = 0;
foreach (string fileName in Directory.GetFiles(targetPath))
{
fullFileText_Original[counter] = File.ReadAllText(targetPath);
//fileNameList_Original[counter]
counter++;
}
counter = 0;
}
TO
public void ReadFiles()
{
//Store all files names in a string array in one go
fileNameList_Original = Directory.GetFiles(targetPath);
string defaultFileName = "file_";
int counter = 0;
foreach (string fileName in Directory.GetFiles(targetPath))
{
//removed the storing file names, was redundant
//added the suggested idea to the proper array
fullFileText_Original[counter] = File.ReadAllText(fileName);
//fileNameList_Original[counter]
counter++;
}
counter = 0;
}
Gives me nullreference exception on File, not sure what my conclusion should be from this error. Admitting that I am pretty tired atm , probably going to realize exactly what it was on the way home :)
FINAL EDIT:
See answers my own post.
This code works fine. I had to be fired for not fixing this almost...... trying to assign values to uninitialized arrays and ignoring any mutable size....... Never happened!
foreach (string fileName in Directory.GetFiles(targetPath))
{
fileNameList_Original.Add(fileName);
foreach (string text in File.ReadAllLines(fileName))
{
fullFileText_Original.Add(text);
//fileNameList_Original[counter]
}
}
Thanks for spotting the fileName instead of targetPath SGB! That was also a mistake I made!
I fixed the rest of the problems on my own now.

Categories