Retrieving Only File Name from a Directory - c#

Using Directory class library I am trying to retrieve all files Name existing in a Folder as below:
private void button1_Click(object sender, EventArgs e)
{
string[] filePaths = Directory.GetFiles(#"d:\Images\", "*.png");
foreach (string img in filePaths)
{
listBox1.Items.Add(img.ToString());
}
}
As you know this method returns Full path and name of the file but I need to get ONLY the name of files.Is it possible to do this in Directory Class? Do I have to use the Path class for this? if yes, how I can assign a path to a variable without file name?
Thanks,

Try this:
using System.IO;
...
private void button1_Click(object sender, EventArgs e)
{
string[] filePaths = Directory.GetFiles(#"d:\Images\", "*.png");
foreach (string img in filePaths)
{
listBox1.Items.Add(Path.GetFileName(img));
}
}

you can use Path.GetFileName method
var file = Path.GetFileName(img);

You can use
var files = Directory.EnumerateFiles(path,searchpattern);
var files = Directory.EnumerateFiles(#"C:\Users\roberth\Programming_Projects\Common\UI\bin\Debug\",
"*.xml");
var filename = new List<string>();
Console.WriteLine("Parsing Files...");
foreach (var file in files)
{
filename.Add(file);
Console.WriteLine("Parsing file: " + file);
....

Use DirectoryInfo instead of Directory. It returns a FileInfo which you can get the Name property of.
private void button1_Click(object sender, EventArgs e)
{
var filePaths = new DirectoryInfo.GetFiles(#"d:\Images\", "*.png").Select(x => x.Name);
foreach (string img in filePaths)
{
listBox1.Items.Add(img.ToString());
}
}

From MSDN
string fileName = #"C:\mydir\myfile.ext";
string path = #"C:\mydir\";
string result;
result = Path.GetFileName(fileName);
Console.WriteLine("GetFileName('{0}') returns '{1}'",
fileName, result);
result = Path.GetFileName(path);
Console.WriteLine("GetFileName('{0}') returns '{1}'",
path, result);
// This code produces output similar to the following:
//
// GetFileName('C:\mydir\myfile.ext') returns 'myfile.ext'
// GetFileName('C:\mydir\') returns ''

string aPath= #"course\train\yes\";
var fileNames=Directory.GetFiles(aPath).Select(name=>Path.GetFileName(name)).ToArray();

Related

in c# how to get filenames in dropdown without the full path

I want the list of files in a folder to be populated into my dropdown list.
in c# i use this to get filenames into dropdown:
private void CasparRefresh_Click(object sender, EventArgs e)
{
string[] fileArray = Directory.GetFiles(#"C:\Users\JoZee\Desktop\Energy\Caspar\Server\media\");
foreach (string name in fileArray)
{
cbxV1.Items.Add(name);
}
How to i get only the filenames without the full path
You can use Path.GetFileName() method on the output of Directory.GetFiles()
string[] fileArray = Directory.GetFiles(#"C:\Users\JoZee\Desktop\Energy\Caspar\Server\media\");
foreach (string name in fileArray)
{
cbxV1.Items.Add(Path.GetFileName(name));
}
There is another option to do same:
var dirInfo = new DirectoryInfo(#"C:\Users\JoZee\Desktop\Energy\Caspar\Server\media\");
foreach (var fileInfo in dirInfo.GetFiles())
{
cbxV1.Items.Add(fileInfo.Name);
}

Creating subfolder

I have little problem with converting, I try to convert folder where is subfolders but its not creating subfolders, makes only one folder "_converted" and in the folder is all converted subfolder images.
My code:
private void btnConvert_Click(object sender, EventArgs e)
{
string[] originalImage = Directory.GetDirectories(txtFilePath.Text, "*.*",
SearchOption.AllDirectories);
foreach (var directory in originalImage)
{
Debug.WriteLine(directory);
}
foreach (string dir in originalImage)
{
string folderPath = #"C:\test\" + "_converted";
folderPath = folderPath.Substring(folderPath.IndexOf(#"\") + 1);
DirectoryInfo di = Directory.CreateDirectory(folderPath);
if (Directory.Exists(folderPath))
{
DirectoryInfo dInfo = new DirectoryInfo(dir);
foreach (var filename in dInfo.GetFiles())
{
FileInfo fInfo = new FileInfo(filename.FullName);
var fileExtension = fInfo.Extension;
var fileOriginalDate = fInfo.CreationTime;
if (fileExtension.ToUpper() == ".JPG" || fileExtension.ToUpper() == ".PNG")
{
using (Bitmap bitmap = new Bitmap(filename.FullName))
{
string fn = Path.GetFileNameWithoutExtension(filename.FullName);
VariousQuality(bitmap, fn, fileExtension,
fileOriginalDate, folderPath);
}
}
}
}
}
}
I tried to use this method:
folderPath = folderPath.Substring(folderPath.IndexOf(#"\") + 1);
How I can resolve this problem?
You are not handling the folders' names correctly. Try this:
private void btnConvert_Click(object sender, EventArgs e)
{
string[] originalImage = Directory.GetDirectories(txtFilePath.Text, "*.*", SearchOption.AllDirectories);
foreach (var directory in originalImage)
{
Debug.WriteLine(directory);
}
foreach (string dir in originalImage)
{
// The name of the current folder (dir)
// This will convert "C:\Users\User\Desktop\Myfolder\Image1" to simply "Image1" since we create a substring after the LAST backslash ('\')
string folderName = dir.Substring(dir.LastIndexOf('\\') + 1); // Ex. "Image1"
// This will now be "C:\test\FOLDERNAME_converted"
string folderPath = #"C:\test\" + folderName + #"_converted\"; // Ex. "C:\test\image1_converted\";
// This can now create the folders
DirectoryInfo di = Directory.CreateDirectory(folderPath);
// Below is unchanged for now
if (Directory.Exists(folderPath))
{
DirectoryInfo dInfo = new DirectoryInfo(dir);
foreach (var filename in dInfo.GetFiles())
{
FileInfo fInfo = new FileInfo(filename.FullName);
var fileExtension = fInfo.Extension;
var fileOriginalDate = fInfo.CreationTime;
if (fileExtension.ToUpper() == ".JPG" || fileExtension.ToUpper() == ".PNG")
{
using (Bitmap bitmap = new Bitmap(filename.FullName))
{
string fn = Path.GetFileNameWithoutExtension(filename.FullName);
VariousQuality(bitmap, fn, fileExtension,
fileOriginalDate, folderPath);
}
}
}
}
}
}
I Hope this helps.
I just have one question. When getting the directories in your directory path (txtFilePath.Text), you get all folders including subfolders (SearchOptions.AllDirectories). When saving the converted folders to the "C:\test" folder, you don't take into account that a folder could have been a subfolder. Because of this the following problem happens. Let's say you have a folder with a folder with a folder:
"HeadFolder -> Image1 -> Image1.2"
What the program will find:
1. "Path\\To\\Image1"
2. "Path\\To\\Image1.2"
After converting you'll get:
"HeadFolder"
"Image1"
"Image1.2"
Notice that "Image1.2" does NOT end up inside "Image1" as prior to conversion
You're creating the same folder in each iteration of the loop. Just create a folder using the current directory by replacing the below lines:
string folderPath = #"C:\test\" + "_converted";
folderPath = folderPath.Substring(folderPath.IndexOf(#"\") + 1);
With this line:
string folderPath = Path.Combine(#"C:\test\", dir + "_converted");

FIND A SPECIFIC FILE IN A FOLDER "C:\TEST" THAT CONTAINS MULTIPLE ARCHIVES ".ZIP" USING C#

I have a folder "c:\test" which contains multiple archives. How do I search through all the archives in this folder for a specific file.
This only search a particular archive using ZipPath:
private void button1_Click(object sender, EventArgs e)
{
string zipPath = #"C:\Test\archive1.zip";
string filetosearch = "testfile";
using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
var position = entry.Name.IndexOf(filetosearch , StringComparison.InvariantCultureIgnoreCase);
if (position > -1)
{
listView1.Items.Add(entry.Name);
}
}
}
}
Is it possible to search all the archives in this folder i.e archive1 to archive70
You can use the following code:
foreach(var zipPath in Directory.GetFiles("C:\\Test"))
{
using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
var position = entry.Name.IndexOf(filetosearch , StringComparison.InvariantCultureIgnoreCase);
if (position > -1)
{
listView1.Items.Add(entry.Name);
}
}
}
}
The code gets all the files in the directory and iterates through them. If you need to filter the files by extension you can check it inside the foreach loop.
You probably want something along the lines of
string[] filePaths = Directory.GetFiles(#"c:\Test\", "*.zip")
Then change you click code to
foreach(var filePath in filePaths){
//your code here for each path
}
You may use following code
string[] filePaths = Directory.GetFiles(#"c:\test", "*.zip");
string filetosearch = "testfile";
foreach (var item in filePaths)
{
string name = Path.GetFileName(item);
if (name.IndexOf(filetosearch, StringComparison.InvariantCultureIgnoreCase) != -1)
{
//item is path of that file
}
}

Make C# Search Hard-Drive Exclude Directory

Program goes through directories and prints Avi files to textbox
public FileList()
{
InitializeComponent();
//Sets Drive Choices
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo d in drives)
{
driveChoice.Items.Add(d);
}
}
//Find Video Files
private void btnStart_Click(object sender, EventArgs e)
{
String path = driveChoice.Text;
if (path != "C:\\")
{
String[] allfiles = Directory.GetFiles(path, "*.avi*", System.IO.SearchOption.AllDirectories);
foreach (String file in allfiles)
{
tbFileList.Text = tbFileList.Text + file + "\r\n";
}
}
else
{
Application.Exit();
}
}
}
When ran I get an error.
Unauthorized Access 'I:\$RECYCLE.BIN\S-1-5-21-1332477098-3306142970-3529014387-1000\'
Can I set the program to just skip 'I:\$RECYCLE.BIN'
Looks like you need to switch to a recursive solution or some other loop rather than using 'AllDirectories'. That way you can provide some skip logic.
see this link http://support.microsoft.com/kb/303974
and this code snippet from that page:
void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d, txtFile.Text))
{
lstFilesFound.Items.Add(f);
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}
In that code you would just check your sDir for the values you want to skip.
Now there is no way to have the AllDirectories option skip specific directories or ignore exceptions that occur from traversing. You will need to manually search the directory structure and deal with errors that occur
if !filePath.Contains("I:\$RECYCLE.BIN")
Use a lambda statement to exclude the system directories:
public FileList()
{
InitializeComponent();
//Sets Drive Choices
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo d in drives)
{
driveChoice.Items.Add(d);
}
}
//Find Video Files
private void btnStart_Click(object sender, EventArgs e)
{
String path = driveChoice.Text;
if (path != "C:\\")
{
DirectoryInfo root = new DirectoryInfo(path);
var rootFiles = root.GetFiles("*.avi");
var rootDirs = root.GetDirectories("*", SearchOption.TopDirectoryOnly).Where(d => !d.Name.Equals("System Volume Information") && !d.Name.Equals("$RECYCLE.BIN"));
foreach (var file in rootFiles)
{
tbFileList.Text = tbFileList.Text + file.FullName + "\r\n";
}
foreach (var dir in rootDirs)
{
foreach (var dirFile in dir.GetFiles("*.avi", SearchOption.AllDirectories))
{
tbFileList.Text = tbFileList.Text + dirFile.FullName + "\r\n";
}
}
}
else
{
Application.Exit();
}
}
I just tried the usage of the Lambda expression of excluding both folders from the returned string list in VS 2017. I observed something strange. If the lambda expression is directly added to the retrieval of the directories as in the string shown above the list still returns $RECYCLEBIN, however SVI folder is not returned. In order to make the lambda working correctly I needed to separate the 2 actions i.e:
var allDirs = rootDir.GetDirectories("*",SearchOption.TopDirectoryOnly);
var filteredDirs = allDirs.Where(d=> !d.Name.Equals("System Volume Information") && !d.Name.Equals("$RECYCLE.BIN"));

Seeing duplicates in my output. Why?

The output of my app is producing duplicates of filenames...and i'm not 100% sure why that is.
My app "cleans" the file name by finding the regex pattern in the filename. If there is none, it dumps it into a "normal" list and ignores it.
Here is the code i'm using to display my output: [this keeps showing me duplicates of filenames!!]
public partial class DriveRecursion_Results : Form
{
List<string> paths = new List<string>();
public DriveRecursion_Results()
{
InitializeComponent();
}
public void DriveRecursion(string retPath)
{
string pattern = (#"[~#&!%+{}]+");
Regex regEx = new Regex(pattern);
string[] fileDrive = Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);
List<string> normal = new List<string>();
List<string> fileNameOnlyList = new List<string>();
dataGridView1.Rows.Clear();
try
{
foreach (string fileNames in fileDrive)
{
string strippedFileName = System.IO.Path.GetFileName(fileNames);
fileNameOnlyList.Add(strippedFileName);
foreach (string nameOnly in fileNameOnlyList)
{
if (regEx.IsMatch(strippedFileName))
{
//string fileNameOnly = Path.GetFileName(fileNames);
string pathOnly = Path.GetDirectoryName(fileNames);
DataGridViewRow dgr = new DataGridViewRow();
dgr.CreateCells(dataGridView1);
dgr.Cells[0].Value = pathOnly;
dgr.Cells[1].Value = nameOnly;
dataGridView1.Rows.Add(dgr);
string pathforInvalidName = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(nameOnly), pathOnly);
paths.Add(pathforInvalidName);
}
else
{
normal.Add(strippedFileName);
}
}
}
}
catch (Exception e)
{
StreamWriter sw = new StreamWriter(retPath + "ErrorLog.txt");
sw.Write(e);
}
}
private void button1_Click_1(object sender, EventArgs e)
{
this.Close();
CleanNames clean = new CleanNames();
clean.Sanitizer(paths);
clean.Show();
}
Once it's done identifying which files need to be renamed, it cleans up the "dirty" names:
public partial class CleanNames : Form
{
public CleanNames()
{
InitializeComponent();
}
public void Sanitizer(List<string> paths)
{
string regPattern = (#"[~#&!%+{}]+");
string replacement = " ";
Regex regExPattern = new Regex(regPattern);
Regex regExPattern2 = new Regex(#"\s{2,}");
StreamWriter errors = new StreamWriter(#"S:\Test\Errors.txt", true);
var filesCount = new Dictionary<string, int>();
dataGridView1.Rows.Clear();
try
{
foreach (string files2 in paths)
{
string filenameOnly = System.IO.Path.GetFileName(files2);
string pathOnly = System.IO.Path.GetDirectoryName(files2);
string sanitizedFileName = regExPattern.Replace(filenameOnly, replacement);
sanitizedFileName = regExPattern2.Replace(sanitizedFileName, replacement);
string sanitized = System.IO.Path.Combine(pathOnly, sanitizedFileName);
if (!System.IO.File.Exists(sanitizedFileName))
{
DataGridViewRow clean = new DataGridViewRow();
clean.CreateCells(dataGridView1);
clean.Cells[0].Value = pathOnly;
clean.Cells[1].Value = filenameOnly;
clean.Cells[2].Value = sanitizedFileName;
dataGridView1.Rows.Add(clean);
System.IO.File.Move(files2, sanitized);
}
else
{
if (filesCount.ContainsKey(sanitizedFileName))
{
filesCount[sanitized]++;
}
else
{
filesCount.Add(sanitized, 1);
}
string newFileName = String.Format("{0}{1}{2}",
System.IO.Path.GetFileNameWithoutExtension(sanitized),
filesCount[sanitized].ToString(),
System.IO.Path.GetExtension(sanitized));
string newFilePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(sanitized), newFileName);
newFileName = regExPattern2.Replace(newFileName, replacement);
System.IO.File.Move(files2, newFilePath);
sanitized = newFileName;
DataGridViewRow clean = new DataGridViewRow();
clean.CreateCells(dataGridView1);
clean.Cells[0].Value = pathOnly;
clean.Cells[1].Value = filenameOnly;
clean.Cells[2].Value = newFileName;
dataGridView1.Rows.Add(clean);
}
}
}
catch (Exception e)
{
errors.Write(e);
}
}
private void SanitizeFileNames_Load(object sender, EventArgs e)
{ }
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
What i'm trying to do here is ONLY show files that need to be renamed (not all files). I want to take those dirty filenames and clean them with my 2nd class.
Anybody know why i'm seeing multiples of the same file on the output? Anybody know how to fix this?!?!
My immediate observation is that your foreach (string nameOnly in fileNameOnlyList) loop should not be nested where it is. Your logic looks like this.
For each filename:
Add it to the list.
For *everything in the list*...
So you'll add one. Then process it. Then add another. Then process both. Then add. Then process all three. Etcetera.
Try this.
foreach (string fileNames in fileDrive)
{
string strippedFileName = System.IO.Path.GetFileName(fileNames);
fileNameOnlyList.Add(strippedFileName);
}
foreach (string strippedFileName in fileNameOnlyList)
{
if (regEx.IsMatch(strippedFileName))
// ...
}
Edit
Even better, why have two loops?
foreach (string fileNames in fileDrive)
{
string strippedFileName = System.IO.Path.GetFileName(fileNames);
fileNameOnlyList.Add(strippedFileName);
if (regEx.IsMatch(strippedFileName))
// ...
}
My first guess is that you are seeing duplicates because you have the loop over fileNameOnlyList inside the loop over fileDrive. This when you are processing second file name from fileDrive collection, you will add the first one to your data grid as well.
There are two possible ways to fix it:
- move the inner loop out of the outer loop and put it just under it
- remove the inner loop (but leave the code that is inside it) and use strippedFileName instead of nameOnly variable in the code
You search recursively through your directory structure
Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);
but you use only the filename
System.IO.Path.GetFileName(fileNames);
So if you have the same file in nested folders, it will show up twice.

Categories

Resources