C# Checking to see if files exist in folder [closed] - c#

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have a For Each Loop container where I process files that arrive nightly. I have three user variables defined: FolderPath ("I:\Data Analytics\Referral"), FileName (blank) -- read only variables, FileExistsFlg -- ReadWriteVariables. The first two are strings and the last one is an int. I have added "using System.IO;" to my Namespaces.The value for the FileExistsFlg is 0 -- the default value when I added the variable.
Here is my C# code:
public void Main()
{
// TODO: Add your code here
String FilePath = Dts.Variables["User::FolderPath"].Value.ToString()
+ Dts.Variables["User::FileName"].Value.ToString();
if ( File.Exists(FilePath))
{
Dts.Variables["User::FileExistsFlg"].Value = 1;
}
MessageBox.Show(FilePath);
MessageBox.Show(Dts.Variables["User::FileExistsFlg"].Value.ToString());
Dts.TaskResult = (int)ScriptResults.Success;
}
The task executes, but it always returns a value of 0 when in fact there are files. I'm using MessageBox.Show(. . . .) to test the script.
The code works correctly if I provide a specific file name in the variable, but the file names will change every day. If I leave the variable blank, then it returns 0.
This doesn't strike me as rocket science and I'm mystified why it keeps returning a false value.
Thanks.

I am assuming you want to get all the files from a folder. You can use System.IO.Directory.GetFiles to do this:
string mypath = "C:/myfolder/";
string[] files = Directory.GetFiles(mypath);
You can then run through all the files like this:
foreach(string item in files){
if(item.Contains("my file name without the extension")){
//Do Something
}
}
-----------EDIT #1
string mypath = "C:/myfolder/";
string[] files = Directory.GetFiles(mypath);
if(!files.Length == 0){
foreach(string item in files){
//Run rest of code using the item
}
}else{}
the foreach statement's string variable contains the file path of the file.
-----------EDIT #2
If an error occurs at the first if statement saying that the "!" operator cannot be applied to integers, then instead put the foreach code into the else statement.
string mypath = "C:/myfolder/";
string[] files = Directory.GetFiles(mypath);
if(files.Length == 0){
//do nothing. No files are in the folder.
}else{
foreach(string item in files){
//Do something. Files are in the folder.
}
}
From my understanding of the question, inside the foreach statement would be the code to process and archive the file. The string called "item" should contain the path to the file.

Related

Turn A Full Path Into A Path With Environment Variables

I want to turn a full path into an environment variable path using c#
Is this even possible?
i.e.
C:\Users\Username\Documents\Text.txt -> %USERPROFILE%\Documents\Text.txt
C:\Windows\System32\cmd.exe -> %WINDIR%\System32\cmd.exe
C:\Program Files\Program\Program.exe -> %PROGRAMFILES%\Program\Program.exe
It is possible by going over all environment variables and checking which variable's value is contained in the string, then replacing that part of the string with the corresponding variable name surrounded by %.
First naive attempt:
string Tokenify(string path)
{
foreach (DictionaryEntry e in Environment.GetEnvironmentVariables())
{
int index = path.IndexOf(e.Value.ToString());
if (index > -1)
{
//we need to make sure we're not already inside a tokenized part.
int numDelimiters = path.Take(index).Count(c => c == '%');
if (numDelimiters % 2 == 0)
{
path = path.Replace(e.Value.ToString(), $"%{e.Key.ToString()}%");
}
}
}
return path;
}
The code currently makes a faulty assumption that the environment variable's value appears only once in the path. This needs to be corrected, but let's put that aside for now.
Also note that not all environment variables represent directories. For example, if I run this method on the string "6", I get "%PROCESSOR_LEVEL%". This can be remedied by checking for Directory.Exists() on the environment variable value before using it. This will probably also invalidate the need for checking whether we are already in a tokenized part of the string.
You may also want to sort the environment variables by length so to always use the most specific one. Otherwise you can end up with:
%HOMEDRIVE%%HOMEPATH%\AppData\Local\Folder
instead of:
%LOCALAPPDATA%\Folder
Updated code that prefers the longest variable:
string Tokenify(string path)
{
//first find all the environment variables that represent paths.
var validEnvVars = new List<KeyValuePair<string, string>>();
foreach (DictionaryEntry e in Environment.GetEnvironmentVariables())
{
string envPath = e.Value.ToString();
if (System.IO.Directory.Exists(envPath))
{
//this would be the place to add any other filters.
validEnvVars.Add(new KeyValuePair<string, string>(e.Key.ToString(), envPath));
}
}
//sort them by length so we always get the most specific one.
//if you are dealing with a large number of strings then orderedVars can be generated just once and cached.
var orderedVars = validEnvVars.OrderByDescending(kv => kv.Value.Length);
foreach (var kv in orderedVars)
{
//using regex just for case insensitivity. Otherwise just use string.Replace.
path = Regex.Replace(path, Regex.Escape(kv.Value), $"%{kv.Key}%", RegexOptions.IgnoreCase);
}
return path;
}
You may still want to add checks to avoid double-tokenizing parts of the string, but that is much less likely to be an issue in this version.
Also you might want to filter out some variables like drive roots, e.g. (%HOMEDRIVE%) or by any other criteria.

C# Split File Name Beginner Exercise

I have a directory filled with multiple excel files that I would like to rename. The names all have leading integers and a '-'. For example: 0123456-Test_01. I would like to rename all of the files within this directory by removing this prefix. 0123456-Test_01 should just be Test_01. I can rename a hard coded instance of a string, but am having trouble getting the files and renaming all of them.
My code is below. Any help is appreciated, as I am clearly new to C#.
public static void Main()
{
//Successfully splits hardcoded string
var temp = "0005689-Test_01".Split('-');
Console.WriteLine(temp[1]);
Console.ReadLine();
//Unsuccessful renaming of all files within directory
List<string> files = System.IO.Directory.GetFiles(#"C:\Users\acars\Desktop\B", "*").ToList();
System.IO.File.Move(#"C:\Users\acars\Desktop\B\", #"C:\Users\acars\Desktop\B\".Split('-'));
foreach (string file in files)
{
var temp = files.Split('-');
return temp[1];
};
}
There are some errors to fix in your code.
The first one is the wrong usage of the variable files. This is the full list of files, not the single file that you want to split and move. As explained comments you should use the iterator result stored in the variable file
The most important problem is the fact that the File.Move method throws an exception if the destination file exists. After removing the first part of your filename string, you cannot be sure that the resulting name is unique in your directory.
So a check for the existance of the file before the Move is mandatory.
Finally, it is better use Directory.EnumerateFiles because this method allows you to start the execution of your moving code without loading first all filenames in memory in a list. (In a folder full of files this could make a noticeable difference in speed)
public static void Main()
{
string workPath = #"C:\Users\acars\Desktop\B";
foreach (string file in Directory.EnumerateFiles(workPath)
{
string[] temp = file.Split('-');
if(temp.Length > 1)
{
string newName = Path.Combine(workPath, temp[1]);
if(!File.Exists(newName))
File.Move(file, newName);
}
}
}
Pay also attention to the comment below from CodeNotFound. You are using an hard-coded path so the problem actually doesn't exist, but if the directory contains a single "-" in its name then you should use something like this to get the last element in the splitted array
string newName = Path.Combine(workPath, temp[temp.Length-1]);

Search string , if no match then delete line [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am looking for code to open a text file , then read the text file line by line , if the line in the text file (each line will store approx 5 values) does not contain a certain value e.g "hart" then I wand to remove that line. I am using c# and vs2012 , could anyone show me how to do this ? the file being read from is a csv file. I have no code example here as my current code does not work and I feel givin example will only cause more confusion than asking for someone to show me a clean fresh approach to doing this.
I have added the code I currently have which adds all of the data to a text file however the code I need to figure out is to take these results and filter them
foreach (DataRow dr in this.CalcDataSet.Items)
{
foreach (object field in dr.ItemArray)
{
str.Append(field.ToString() + ",");
}
str.Replace(",", "\n", str.Length - 1, 1);
}
try
{
System.IO.File.WriteAllText(Filepath, str.ToString());
}
catch (Exception ex)
{
MessageBox.Show("Write Error :" + ex.Message);
}
var lines = System.IO.File.ReadAllLines(Filepath).ToList();
var acceptedLines = new List<string>();
foreach (var line in lines)
if (Matches(line))
acceptedLines.Add(line);
System.IO.File.WriteAllLines(Filepath, acceptedLines);
}
private bool Matches(string s)
{
if (s == cmbClientList.SelectedText.ToString())
{
return true;
}
else return false;
}
Use the TextFieldParser class to open and read the file, and split the values into an array. You can then examine each item on each line to see if it contains the value you want.
If the line contains the value, then write the line to a new file. If it doesn't contain the value, then do not write to the new file.
When you're done, close the input and output files. Then delete the original input file and rename the output file.
You can't easily read and modify a text file in-place.
Another option would be to read using TextFieldParser and write to an in-memory stream. At the end, write from the memory stream back to the original file. This will work if the file is small enough to fit in memory.
This will basically do what you want:
var lines = System.IO.File.ReadAllLines("somefile.csv");
var acceptedLines = new List<string>();
foreach (var line in lines)
if (Matches(line))
acceptedLines.Add(line);
System.IO.File.WriteAllLines("output.csv", acceptedLines);
private bool Matches(string s) {
// Whatever you want, return true to include the line, false to exclude)
}
you can do this
string[] lines = File.ReadAllLines("yourfile.csv");
List<string> linesToWrite = new List<string>();
int currentCount = 0;
foreach(string s in lines)
{
if(s.Contains("YourKeyValue"))
linesToWrite.Add(s);
}
File.WriteAllLines("yourfile.csv", linesToWrite );

Retrieving a Single File and the Behavior of Directory.GetFiles C#

public int RunStageData(string rootDirectory, stringdataFolder)
{
string[] files = new string[] { };
files = Directory.GetFiles(rootDirectory + dataFolder);
string[] tableOrder = new string[] { };
tableOrder = Directory.GetFiles(#"C:\_projects\ExampleProject\src", "TableOrder.txt");
System.IO.StreamReader tableOrderReader = new System.IO.StreamReader(tableOrder[0]);
for (int count = 0; count < files.Length; count++)
{
string currentTableName =tableOrderReader.ReadLine();
//files[count] = Directory.GetFiles(#"C:\_projects\ExampleProject\src", currentTableName);
}
}
Hi everyone, sorry if my code is a bit sloppy. I'm having an issue primarily with the line I have commented out. So basically what I'm trying to do here is to populate a string array of file names based on the ordering of these names in a txt file. So I read the first line from the txt file, then retrieve the name of that file in the directory(assuming it exists) and put it in the first spot of the array, then move on.
For Example if the txt file had these words in the following order:
Dog
Sheep
Cat
I would want the array to have Dog first, then Sheep, then Cat. My issue is that the line that I have commented gives me an error that says "Error 41 Cannot implicitly convert type 'string[]' to 'string'"
I'm guessing the reason for this is that Directory.GetFiles has the possibility of returning multiple files. So, is there another method I could use to achieve the results I'm looking for? Thank you.
I am assuming you want the contents of the file (if you just want the file name and need to check for existance a different solution will be required).
files[count] = File.ReadAllText(Path.Combine(#"C:\_projects\ExampleProject\src", currentTableName));
And a couple other suggestions:
Don't initialize your variables with bogus data, = new string[] {} can be removed
Don't use count as an indexer, it is confusing (count is a property of the array after all)
Use Path.Combine when joining paths. It is much easier as it handles the \ for you.
From your question:
So basically what I'm trying to do here is to populate a string array
of file names based on the ordering of these names in a txt file. So I
read the first line from the txt file, then retrieve the name of that
file in the directory(assuming it exists) and put it in the first spot
of the array, then move on.
So, your TableOrder.txt already contains the files in the correct order, thus you can do:
string[] files = File.ReadAllLines(#"C:\_projects\ExampleProject\src\TableOrder.txt")
If your array files contains only paths, you can do it as:
path = #"C:\_projects\ExampleProject\src\" + currentTableName;
If(File.Exists(path))
{
files[count] = path;
}

Increment filename [duplicate]

This question already has answers here:
How would you make a unique filename by adding a number?
(22 answers)
Closed 8 months ago.
I want to create algorithm, to generate name for new file which I want to add to main directory.
All files in this directory must has unique name and start with "myFile"
What do you think about this algorithm ? Can I optimize it ?
string startFileName="myFile.jpg";
string startDirectory="c:\MyPhotosWithSubFoldersAndWithFilesInMainDirectory";
bool fileWithThisNameExists = false;
string tempName = null;
do
{
tempName = startFileName +"_"+ counter++ + Path.GetExtension(startFileName);
foreach (var file in Directory.GetFiles(startDirectory)
{
if (Path.GetFileName(tempName) == Path.GetFileName(file))
{
fileWithThisNameExists = true;
}
}
if (fileWithThisNameExists) continue;
foreach (var directory in Directory.GetDirectories(startDirectory))
{
foreach (var file in Directory.GetFiles(directory))
{
if (Path.GetFileName(tempName) == Path.GetFileName(file))
{
fileWithThisNameExists = true;
}
}
}
} while (fileWithThisNameExists);
If you are not worried about the rest of the file name (except the starting as "myFile", then you can simply create a GUID and concat it to the worg "myFile". This is the simplest way. The other way might be taking the syste ticks and add it as a string to the word "myFile".
If you construct your filenames so that they sort alphabetically
base000001
base000002
...
base000997
Then you can get a directory listing and just go to the end of the list to find the last file.
Be careful though: what happens if two instances of your program are running at the same time? There's a little window of opportunity between the test for the file existing and its creation.

Categories