I am trying to do a foreach loop where it would select each string in my array and add it to the path which is a string and stores the path for the image, this is what I have so far:
string[] Images = new string[] { "Star_00001.png", "Star_00002.png", "Star_00003.png" };
string Path = "Assets/Images/";
if (LevelUp)
{
foreach()
{
}
}
As you can see I want the foreach loop to go through each string in the Images array, for each string in the Images array I want it to be added to the path string so the end result for example would be "Assets/Images/Star_00001.png"
Does anyone know how I should do this?
A foreach loop has the syntax:
foreach(T ident in collection) {
with T the type of the elements, ident the name of the variable and collection an object that supports the IEnumerable interface.
So you can implement:
string[] images = new string[] { "Star_00001.png", "Star_00002.png", "Star_00003.png" };
string path = "Assets/Images/";
if (LevelUp) {
foreach(string file in images) {
string thepath = Path.Combine(path,file);
//do something with file or thepath, like
Console.WriteLine(thepath);
}
}
A final note is that C#'s consensus is that variables start with a lowercase and type names with an uppercase.
It is not recommended to generate file paths by using string concatenation. The recommended way is to use Path.Combine which is provided in System.IO. Consider the example below:
string[] Images = new string[] { "Star_00001.png", "Star_00002.png", "Star_00003.png" };
string path = "Assets/Images/";
if (LevelUp)
{
foreach (string s in Images)
{
// You can store result in an array or sth depending on what you
// are trying to achieve
string result = Path.Combine(path, s);
}
}
string[] Images = new string[] { "Star_00001.png", "Star_00002.png", "Star_00003.png" };
string path = "Assets/Images/";
if (LevelUp)
Images = Images.Select(image => Path.Combine(path, image)).ToArray();
Related
I need someone to point me in the right direction.
Goal:
Return a list of Folder Names in a path that contain a string in their name. For example: The Path has a Directory named Pictures_New and Videos_New. The string I am searching with is "Pictures_" and "Videos_".
It all works with one string parameter being passed as a search string. My problem is getting it to work with multiple filters. I know it is easily done with file names and extensions.
This is being passed to GetFolders():
string[] filterStrings = { "Pictures_", "Videos_" }
Rest of my code:
public IEnumerable<string> GetFolders(string path, string[] filterStrings, SearchOption searchOption = SearchOption.AllDirectories)
{
IEnumerable<string> folders = Directory.EnumerateDirectories(path, "Pictures_*.*", searchOption);
var resultFolders = new List<string>();
if(filterStrings.Length > 0)
{
foreach (var foldername in folders)
{
string folderName = Path.GetFileName(Path.GetDirectoryName(foldername));
if (string.IsNullOrEmpty(folderName) || Array.IndexOf(filterStrings, "*" + folderName) < 0)
{
// This leaves us only with the Directory names. No paths.
var b = (foldername.Substring(foldername.LastIndexOf(#"\") + 1));
resultFolders.Add(b);
}
}
}
return resultFolders;
}
You can use Linq SelectMany to parse your list of filters and return a list of the results with Directory.GetDirectories();
It will of course return all the Sub Directories that match the filter. Use just "*".
public IEnumerable<string> GetFolders(string path, string[] filterStrings, SearchOption searchOption = SearchOption.AllDirectories)
{
List<string> resultFolders = filterStrings
.SelectMany(flt => Directory.GetDirectories(path, flt, searchOption))
.ToList();
return resultFolders;
}
try:
var patterns = new[] { "Pictures_*", "Videos_*" };
var dirsFound = new List<string>();
foreach (var dir in patterns.Select(pattern => Directory.GetDirectories(#"my path", pattern).ToArray()))
{
dirsFound.AddRange(dir);
}
Looks like you're not looping through each of your filter strings:
var folders = new List<string>();
foreach (var filterString in filterStrings)
{
folders.AddRange(Directory.EnumerateDirectories(path, filterString, searchOption););
}
I have a C# application which reads text files with lines such as:
c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\myfile2.cfm
c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\includes\my file1.blahh4
What I need are two values from each lines in such a way:
From line 1:
filename variable valued as 'myfile2.cfm' and filepath variable as "" [empty]
From line 2:
filename variable valued as 'my file1.blahh4' and filepath as 'includes' [also be \includes\subfolder]
I have tried code like indexof and substring but no success so far. I think some RegEx should help? Basically, the slashes will be constantly 3 before file or folder names begin.
Thanks!
You can use Path which parses paths.
Please see the following code for more details:
var path = #"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\myfile2.cfm";
var pathFileName = Path.GetFileName(path); // "myfile2.cfm"
var baseDirectory = #"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16";
var pathDirectory = Path.GetDirectoryName(path).Replace(baseDirectory, ""); // ""
Edit See the code below which sets the paths to LowerInvariant in order to ensure the replace works as expected.
var baseDirectory = #"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16".ToLowerInvariant();
var paths = new string[] {
#"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\myfile2.cfm",
#"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\includes\my file1.blahh4"
};
var sanitizedPaths = new List<Tuple<string,string>>();
foreach(var path in paths.Select(p => (p ?? String.Empty).ToLowerInvariant()))
{
var fileName = Path.GetFileName(path);
var directory = Path.GetDirectoryName(path).Replace(baseDirectory, String.Empty);
sanitizedPaths.Add(new Tuple<string, string>(fileName, directory));
}
// sanitizedPaths[0] -> "myfile2.cfm" | ""
// sanitizedPaths[1] -> "my file1.blahh4" | "\includes"
Edit 2 Using Uri and based on the fact your base directory is always 3 segments, the following should do:
var paths = new string[] {
#"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\myfile2.cfm",
#"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\includes\my file1.blahh4",
#"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\includes\subFolder\other file.extension"
};
var sanitizedPaths = new List<Tuple<string, string>>();
foreach (var path in paths.Select(p => (p ?? String.Empty).ToLowerInvariant()))
{
var uri = new Uri(path);
var pathWithoutBaseDirectory = String.Join("/", uri.Segments.Skip(4));
var fileName = Path.GetFileName(pathWithoutBaseDirectory);
var directory = Path.GetDirectoryName(pathWithoutBaseDirectory);
sanitizedPaths.Add(new Tuple<string, string>(fileName, directory));
}
Use Path class to get file names and file directories:
var baseDirectory = #"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\";
var files = new[]
{
#"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\myfile2.cfm",
#"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\includes\my file1.blahh4"
};
And here goes LINQ query
var query = from file in files
let directoryName = Path.GetDirectoryName(file)
select new
{
filename = Path.GetFileName(file),
filepath = directoryName.StartsWith(baseDirectory)
? directoryName.Substring(baseDirectory.Length) : ""
};
Output:
[
{
filename: "myfile2.cfm",
filepath: ""
},
{
filename: "my file1.blahh4",
filepath: "includes"
}
]
What I would do is use the FileInfo class in a recursive loop to get a list of all files. You can separate the path and filename using the FileInfo. Then using the string length of the base folder you are acting on and substring that from the path of each of the files.
Something like this?
using System;
using System.Collections.Generic;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
RelativePaths p = new RelativePaths(#"u:\test");
foreach (var str in p.MyFiles)
{
Console.WriteLine(str);
}
Console.ReadKey();
}
}
class MyFileInfo
{
public MyFileInfo(string path, string filename)
{
Path = path;
Filename = filename;
}
public string Path { get; private set; }
public string Filename { get; private set; }
public override string ToString() => $"{Path}, {Filename}";
}
class RelativePaths
{
List<MyFileInfo> myPaths = new List<MyFileInfo>();
public RelativePaths(string startingPath = #"U:\test")
{
DirectoryInfo dir = new DirectoryInfo(startingPath);
PathSeparator(dir.FullName, dir);
}
public MyFileInfo[] MyFiles => myPaths.ToArray();
public void PathSeparator(string originalPath, DirectoryInfo dir)
{
// Files in dir
foreach (var file in dir.GetFiles())
{
myPaths.Add(new MyFileInfo(file.DirectoryName.Substring(originalPath.Length),
file.Name));
}
foreach (var folder in dir.GetDirectories())
{
PathSeparator(originalPath, folder);
}
}
}
}
Original paths:
u:\test\subfolder
u:\test\testfile1.txt
u:\test\subfolder\fileinsub1.txt
u:\test\subfolder\subfolder2
u:\test\subfolder\subfolder2\two deep.txt
Where result is:
, testfile1.txt
\subfolder, fileinsub1.txt
\subfolder\subfolder2, two deep.txt
Note that the results are in a list of type MyFileInfo so you can just use the data output however you see fit. This is only and example. You may want to create a static class with an extension method instead but using the recursive method to look in each folder is the concept that might be helpful. Note you can copy the source code directly into a new console project and run it in Visual Studio just change the starting path.
Try this out:
var s1 =#"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\myfile2.cfm";
var s2 =#"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\includes\my file1.blahh4";
var filename = Path.GetFileName(s1);
var p1 = Path.GetDirectoryName(s1);
if (!p1.ToLowerInvariant().Contains(#"\includes"))
p1 = "";
var p2 = Path.GetDirectoryName(s2);
if (!p2.ToLowerInvariant().Contains(#"\includes"))
p2 = "";
I want to extract Guid from this below string array and want output like this:
Output:Log.txt,Logging.txt
string[] str = new string[] { "1250a2d5-cd40-4bcc-a979-9d6f2cd62b9fLog.txt", "bdb31966-e3c4-4344-b02c-305c0eb0fa0aLogging.txt" }; //file name are Log.txt and Logging.txt
List<string> list= new List<string>();
foreach (var item in str)
{
if (!string.IsNullOrEmpty(item))
{
list.Add(); // here i want to store Log.txt and Logging.txt
}
}
How to do this??
var str = new string[] { "1250a2d5-cd40-4bcc-a979-9d6f2cd62b9fLog.txt", "bdb31966-e3c4-4344-b02c-305c0eb0fa0aLogging.txt" }; //file name are Log.txt and Logging.txt
var arr = str.Select(s=>s.Substring(36)).Where(s=>s.Any()).ToArray();
You can see it in action here: https://dotnetfiddle.net/eHy6Fo
is it possible to include multiple "foreach" statements inside any of the looping constructs like while or for ... i want to open the .wav files from two different directories simultaneously so that i can compare files from both.
here is what i am trying to so but it is certainly wrong.. any help in this regard is appreciated.
string[] fileEntries1 = Directory.GetFiles(folder1, "*.wav");
string[] fileEntries2 = Directory.GetFiles(folder11, "*.wav");
while ( foreach(string fileName1 in fileEntries1) && foreach(string fileName2 in fileEntries2))
Gramatically speaking no. This is because a foreach construct is a statement whereas the tests in a while statement must be expressions.
Your best bet is to nest the foreach blocks:
foreach(string fileName1 in fileEntries1)
{
foreach(string fileName2 in fileEntries2)
I like this kind of statements in one line. So even though most of the answers here are correct, I give you this.
string[] fileEntries1 = Directory.GetFiles(folder1, "*.wav");
string[] fileEntries2 = Directory.GetFiles(folder11, "*.wav");
foreach( var fileExistsInBoth in fileEntries1.Where(fe1 => fileEntries2.Contains(fe1) )
{
/// here you will have the records which exists in both of the lists
}
Something like this since you only need to validate same file names:
IEnumerable<string> fileEntries1 = Directory.GetFiles(folder1, "*.wav").Select(x => Path.GetFileName(x));
IEnumerable<string> fileEntries2 = Directory.GetFiles(folder2, "*.wav").Select(x => Path.GetFileName(x));
IEnumerable<string> filesToIterate = (fileEntries1.Count() > fileEntries2.Count()) ? fileEntries1 : fileEntries2;
IEnumerable<string> filesToValidate = (fileEntries1.Count() < fileEntries2.Count()) ? fileEntries1 : fileEntries2;
// Iterate the bigger collection
foreach (string fileName in filesToIterate)
{
// Find the files in smaller collection
if (filesToValidate.Contains(fileName))
{
// Get actual file and compare
}
else
{
// File does not exist in another list. Handle appropriately
}
}
.Net 2.0 based solution:
List<string> fileEntries1 = new List<string>(Directory.GetFiles(folder1, "*.wav"));
List<string> fileEntries2 = new List<string>(Directory.GetFiles(folder2, "*.wav"));
List<string> filesToIterate = (fileEntries1.Count > fileEntries2.Count) ? fileEntries1 : fileEntries2;
filesToValidate = (fileEntries1.Count < fileEntries2.Count) ? fileEntries1 : fileEntries2;
string iteratorFileName;
string validatorFilePath;
// Iterate the bigger collection
foreach (string fileName in filesToIterate)
{
iteratorFileName = Path.GetFileName(fileName);
// Find the files in smaller collection
if ((validatorFilePath = FindFile(iteratorFileName)) != null)
{
// Compare fileName and validatorFilePath files here
}
else
{
// File does not exist in another list. Handle appropriately
}
}
FindFile method:
static List<string> filesToValidate;
private static string FindFile(string fileToFind)
{
string returnValue = null;
foreach (string filePath in filesToValidate)
{
if (string.Compare(Path.GetFileName(filePath), fileToFind, true) == 0)
{
// Found the file
returnValue = filePath;
break;
}
}
if (returnValue != null)
{
// File was found in smaller list. Remove this file from the list since we do not need to look for it again
filesToValidate.Remove(returnValue);
}
return returnValue;
}
You may or may not choose to make fields and methods static based on your needs.
If you want to iterate all pairs of files in both paths respectively, you can do it as follows.
string[] fileEntries1 = Directory.GetFiles(folder1, "*.wav");
string[] fileEntries2 = Directory.GetFiles(folder11, "*.wav");
foreach(string fileName1 in fileEntries1)
{
foreach(string fileName2 in fileEntries2)
{
// to the actual comparison
}
}
This is what I would suggest, using linq
using System.Linq;
var fileEntries1 = Directory.GetFiles(folder1, "*.wav");
var fileEntries2 = Directory.GetFiles(folder11, "*.wav");
foreach (var entry1 in fileEntries1)
{
var entries = fileEntries2.Where(x => Equals(entry1, x));
if (entries.Any())
{
//We have matches
//entries is a list of matches in fileentries2 for entry1
}
}
If you want to enable both collections "in parallel", then use their iterators like this:
var fileEntriesIterator1 = Directory.EnumerateFiles(folder1, "*.wav").GetEnumerator();
var fileEntriesIterator2 = Directory.EnumerateFiles(folder11, "*.wav").GetEnumerator();
while(fileEntriesIterator1.MoveNext() && fileEntriesIterator2.MoveNext())
{
var file1 = fileEntriesIterator1.Current;
var file2 = fileEntriesIterator2.Current;
}
If one collection is shorter than the other, this loop will end when the shorter collection has no more elements.
I want to add new item to string array or I can keep in List. Can somebody show how to do this?
string sourceDir = "C:\\Users\\ozkan\\Desktop\\foto\\"
string[] picList;
string pattern = "*.jpg|*.png|*.gif";
string[] filters = pattern.Split('|');
foreach (string filter in filters)
{
// I want to collect all files url in picList
// Directory.GetFiles returns string array
picList = Directory.GetFiles(sourceDir, filter);
}
try :
string sourceDir = "C:\\Users\\ozkan\\Desktop\\foto\\"
string[] picList;
string pattern = "*.jpg|*.png|*.gif";
string[] filters = pattern.Split('|');
picList = filters .SelectMany(f=> Directory.GetFiles(sourceDir , f)).ToArray();