Convert string or list to Renci.SshNet.Sftp - c#

I want to download the specific files from SFTP server(root and Subdirectories). I am trying to get a list of files and subdirectories from SFTP recursively which i could not do. but with the following code it is only listing only files and directory names. I am trying to add the directory path to a directory of type (Renci.SshNet.Sftp.SftpFile) I am getting the following exception.
Any alternative way to handle this issue.
using (var sftp = new SftpClient(host, 22, username, password))
{
sftp.Connect();
var directory = sftp.ListDirectory("/").ToList();
string FileName = "Dir1/abc.txt,file1.txt,file2.txt"
var fileNameList = FileName.Contains(',') ? FileName.Split(',') : String.IsNullOrEmpty(FileName) ? new string[0] : new string[1] { FileName };
HashSet<string> filenameHash = new HashSet<string>(fileNameList.Select(x => x));
directory.RemoveAll(x => !filenameHash.Contains(x.Name));
directory.RemoveAll(x => (!x.IsRegularFile));
string dir = "";
SftpFile fl = (SftpFile)Convert.ChangeType(dir, typeof(SftpFile));
foreach (var f in fileNameList)
{
if (f.Contains('/'))
{
fl += f;
}
}
Exception:
System.InvalidCastException: 'Invalid cast from 'System.String' to 'Renci.SshNet.Sftp.SftpFile'.'

I fixed the issue just by concatenating(subdirectory to directory) and reassigning it to the directory.
using (var sftp = new SftpClient(host, 22, username, password))
{
sftp.Connect();
var directory = sftp.ListDirectory("/").ToList();
string FileName = "Dir1/abc.txt,file1.txt,file2.txt"
var fileNameList = FileName.Contains(',') ? FileName.Split(',') : String.IsNullOrEmpty(FileName) ? new string[0] : new string[1] { FileName };
HashSet<string> filenameHash = new HashSet<string>(fileNameList.Select(x => x));
directory.RemoveAll(x => !filenameHash.Contains(x.Name));
directory.RemoveAll(x => (!x.IsRegularFile));
string dir = "";
SftpFile fl = (SftpFile)Convert.ChangeType(dir, typeof(SftpFile));
foreach (var f in fileNameList)
{
if (f.Contains('/'))
{
string[] fl = f.Split("/");
var subdirectory = sftp.ListDirectory(f.Split('/')[0]).ToList();
directory = directory.Concat(subdirectory).ToList();
}
}

private void RecursivelyFilechecking(string Filepath, string _todaydate, string hostid, bool isHeader, string hostName, Int32 CustomerId)
{
try
{
if (_sftp.Exists(Filepath))
{
var files = _sftp.ListDirectory(Filepath);
bool flg = false;
string JobMailBody;
string toadd = string.Empty;
string fileName = string.Empty;
string fileDate = string.Empty;
Int32 filepathId = 0;
foreach (var file in files)
{
if (file.IsDirectory && !file.Name.Equals(".") && !file.Name.Equals(".."))
{
RecursivelyFilechecking(file.FullName, _todaydate, hostid, isHeader, hostName, CustomerId);
}
else if (!file.Name.Equals(".") && !file.Name.Equals(".."))
{
if (file.LastWriteTime.ToString("ddMMyyyy").Equals(_todaydate))
{
}
}
}
}
}
catch (Exception ex)
{
}
}

Related

Upload file in asp.net and angular 7 null

I upload image from angular to .net core but the file input I receive always null , with the postman , it's receive exactly. I don't know why ?
Can you help me how to solve it?
Thank you so much !
[HttpPost("upload-file")]
public async Task<IActionResult> UploadFile(IFormFile file)
{
try
{
//var file = Request.Form.Files[0];
var rnd = FileHelper.RandomNumber();
//var file = file;
var folder = "Folder";
var index = file.FileName.LastIndexOf('.');
var onlyName = file.FileName.Substring(0, index);
var fileName = onlyName + rnd;
var extension = Path.GetExtension(file.FileName);
var folderThumb = folder + "Thumbnail";
var fileNameThumb = fileName + "Thumbnail";
var t1 = Task.Run(() => FileHelper.SaveFile(folder, fileName, file));
await Task.WhenAll(t1);
var path = new MediaResponseModel()
{
Url = Url.Action("GetFile", "Media", new { folder = folder, fileName = string.Format("{0}{1}", fileName, extension) }, Request.Scheme),
UrlThumbnail = Url.Action("GetFile", "Media", new { folder = folderThumb, fileName = string.Format("{0}{1}", fileNameThumb, extension) }, Request.Scheme),
Title = onlyName
};
return Ok(path);
}
catch (System.Exception e)
{
throw e;
}
}
handleFileInput(files: FileList) {
const file = files.item(0);
this.fileToUpload = {};
this.fileToUpload.data = files.item(0);
this.fileToUpload.fileName = files.item(0).name;
}
onUpload() {
const formData = new FormData();
formData.append('file', this.fileToUpload.data, this.fileToUpload.name);
this.http.post('http://localhost:56000/api/media/upload-file', formData).subscribe(res => console.log(res));
}

Azure File Storage: Create nested directories

My code looks like this
CloudFileClient client = ...;
client.GetShareReference("fileStorageShare")
.GetRootDirectoryReference()
.GetDirectoryReference("one/two/three")
.Create();
This errors if directories one or two don't exist. Is there a way to create these nested directories with a single call?
It is impossible. The SDK does not support it this way, you should create them one by one.
A issue has already submitted here.
If you wanna create them one by one, you can use the following sample code:
static void NestedDirectoriesTest()
{
var cred = new StorageCredentials(accountName, accountKey);
var account = new CloudStorageAccount(cred, true);
var client = account.CreateCloudFileClient();
var share = client.GetShareReference("temp2");
share.CreateIfNotExists();
var cloudFileDirectory = share.GetRootDirectoryReference();
//Specify the nested folder
var nestedFolderStructure = "Folder/SubFolder";
var delimiter = new char[] { '/' };
var nestedFolderArray = nestedFolderStructure.Split(delimiter);
for (var i=0; i<nestedFolderArray.Length; i++)
{
cloudFileDirectory = cloudFileDirectory.GetDirectoryReference(nestedFolderArray[i]);
cloudFileDirectory.CreateIfNotExists();
Console.WriteLine(cloudFileDirectory.Name + " created...");
}
}
Following the advice of Ivan Yang, I adapted my code using Azure.Storage.Files.Shares (Version=12.2.3.0).
Here's my contribution:
readonly string storageConnectionString = "yourConnectionString";
readonly string shareName = "yourShareName";
public string StoreFile(string dirName,string fileName, Stream fileContent)
{
// Get a reference to a share and then create it
ShareClient share = new ShareClient(storageConnectionString, shareName);
share.CreateIfNotExists();
// Get a reference to a directory and create it
string[] arrayPath = dirName.Split('/');
string buildPath = string.Empty;
var tempoShare = share;
ShareDirectoryClient directory = null; // share.GetDirectoryClient(dirName);
// Here's goes the nested directories builder
for (int i=0; i < arrayPath.Length; i++)
{
buildPath += arrayPath[i];
directory = share.GetDirectoryClient(buildPath);
directory.CreateIfNotExists();
buildPath += '/';
}
// Get a reference to a file and upload it
ShareFileClient file = directory.GetFileClient(fileName);
using (Stream stream = fileContent)
{
file.Create(stream.Length);
file.UploadRange(new HttpRange(0, stream.Length), stream);
}
return directory.Path;
}
Here is a simplified version of Hagen's code:
public async Task<ShareFileClient> CreateFileClient(string connection, string shareName, string path)
{
var share = new ShareClient(connection, shareName);
await share.CreateIfNotExistsAsync();
var dir = share.GetRootDirectoryClient();
var pathChain = path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
int dirCount = pathChain.Length - 1;
for (int i = 0; i < dirCount; ++i)
{
dir = dir.GetSubdirectoryClient(pathChain[i]);
await dir.CreateIfNotExistsAsync();
}
return dir.GetFileClient(pathChain[dirCount]);
}

how do i get a full path of a folder from google drive api with c#

how do i get a full path of a folder with google drive api c#. Lets say i want a .net list filled with Folder class and Folder being a class with 2 properties. URL and folder name. Iam new to this so sorry if the question is bad/dumb. Any thing would help at this point.
There is a fantastic command line for working with google drive available on github.com/prasmussen/gdrive/
The logic exists in that codebase to walk the directory tree up from each file and construct the full path.
I've followed the .NET Quickstart instructions, then converted the relevant go-lang code from path.go into the C# equivalent below.
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
namespace DriveQuickstart
{
class Program
{
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/drive-dotnet-quickstart.json
static string[] Scopes = { DriveService.Scope.DriveReadonly };
static string ApplicationName = "Drive API .NET Quickstart";
static DriveService service;
static Dictionary<string, Google.Apis.Drive.v3.Data.File> files = new Dictionary<string, Google.Apis.Drive.v3.Data.File>();
static void Main(string[] args)
{
UserCredential credential;
using (var stream =
new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
{
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/drive-dotnet-quickstart.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Drive API service.
service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
FilesResource.ListRequest listRequest = service.Files.List();
listRequest.PageSize = 10;
listRequest.Fields = "nextPageToken, files(id, name, parents)";
// List files.
IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute()
.Files;
Console.WriteLine("Files:");
if (files != null && files.Count > 0)
{
foreach (var file in files)
{
var absPath = AbsPath(file);
Console.WriteLine("{0} ({1})", absPath, file.Id);
}
}
else
{
Console.WriteLine("No files found.");
}
Console.Read();
}
private static object AbsPath(Google.Apis.Drive.v3.Data.File file)
{
var name = file.Name;
if (file.Parents.Count() == 0)
{
return name;
}
var path = new List<string>();
while (true)
{
var parent = GetParent(file.Parents[0]);
// Stop when we find the root dir
if (parent.Parents == null || parent.Parents.Count() == 0)
{
break;
}
path.Insert(0, parent.Name);
file = parent;
}
path.Add(name);
return path.Aggregate((current, next) => Path.Combine(current, next));
}
private static Google.Apis.Drive.v3.Data.File GetParent(string id)
{
// Check cache
if (files.ContainsKey(id))
{
return files[id];
}
// Fetch file from drive
var request = service.Files.Get(id);
request.Fields = "name,parents";
var parent = request.Execute();
// Save in cache
files[id] = parent;
return parent;
}
}
}
Folder and Files both are considered as a File in Google Drive hence the following code will work for both the scenarios.
Create a function to return Full Path and Two other functions required in the same Task :
private IList<string> GetFullPath(Google.Apis.Drive.v3.Data.File file, IList<Google.Apis.Drive.v3.Data.File> files)
{
IList<string> Path = new List<string>();
if (file.Parents == null || file.Parents.Count == 0)
{
return Path;
}
Google.Apis.Drive.v3.Data.File Mainfile = file;
while (GetParentFromID(file.Parents[0], files) != null)
{
Path.Add(GetFolderNameFromID(GetParentFromID(file.Parents[0], files).Id, files));
file = GetParentFromID(file.Parents[0], files);
}
return Path;
}
private Google.Apis.Drive.v3.Data.File GetParentFromID(string FileID, IList<Google.Apis.Drive.v3.Data.File> files)
{
if (files != null && files.Count > 0)
{
foreach (var file in files)
{
if (file.Parents != null && file.Parents.Count > 0)
{
if (file.Id == FileID)
{
return file;
}
}
}
}
return null;
}
private string GetFolderNameFromID(string FolderID, IList<Google.Apis.Drive.v3.Data.File> files)
{
string FolderName = "";
if (files != null && files.Count > 0)
{
foreach (var file in files)
{
if (file.Id == FolderID)
{
FolderName = file.Name;
}
}
}
return FolderName;
}
Now you may call the function as :
string Path = "My Drive";
foreach (string Item in GetFullPath(file, files).Reverse())
{
Path += " / " + Item;
}
here, two parameters are passed -
1. file - it is the file whose path you are trying to find.
2. files - the list of files on your drive.

Paths from a directory tree array

I am using Directory.GetFiles to find files that will be copied. I need to find the paths of the files so I can use copy, but I have no idea how to find the path.
It iterates through the files fine, but I can't copy or move them because I need the file's source path.
This is what I have:
string[] files = Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories);
System.Console.WriteLine("Files Found");
// Display all the files.
foreach (string file in files)
{
string extension = Path.GetExtension(file);
string thenameofdoom = Path.GetFileNameWithoutExtension(file);
string filename = Path.GetFileName(file);
bool b = false;
string newlocation = (#"\\TEST12CVG\Public\Posts\Temporaryjunk\");
if (extension == ".pst" ||
extension == ".tec" ||
extension == ".pas" ||
extension == ".snc" ||
extension == ".cst")
{
b = true;
}
if (thenameofdoom == "Plasma" ||
thenameofdoom == "Oxygas" ||
thenameofdoom == "plasma" ||
thenameofdoom == "oxygas" ||
thenameofdoom == "Oxyfuel" ||
thenameofdoom == "oxyfuel")
{
b = false;
}
if (b == true)
{
File.Copy(file, newlocation + thenameofdoom);
System.Console.WriteLine("Success: " + filename);
b = false;
}
}
Path.GetFullPath works, but also consider using FileInfo as it comes with many file helper methods.
I would use a method similar to this (could use a lot more error handling (try catches...) but it's a good start
EDIT I noticed that you are filtering out the extensions, but requiring them, update to code allows for that
class BackupOptions
{
public IEnumerable<string> ExtensionsToAllow { get; set; }
public IEnumerable<string> ExtensionsToIgnore { get; set; }
public IEnumerable<string> NamesToIgnore { get; set; }
public bool CaseInsensitive { get; set; }
public BackupOptions()
{
ExtensionsToAllow = new string[] { };
ExtensionsToIgnore = new string[] { };
NamesToIgnore = new string[] { };
}
}
static void Backup(string sourcePath, string destinationPath, BackupOptions options = null)
{
if (options == null)
optionns = new BackupOptions();
string[] files = Directory.GetFiles(sourcePath, ".", SearchOption.AllDirectories);
StringComparison comp = options.CaseInsensitive ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture;
foreach (var file in files)
{
FileInfo info = new FileInfo(file);
if (options.ExtensionsToAllow.Count() > 0 &&
!options.ExtensionsToAllow.Any(allow => info.Extension.Equals(allow, comp)))
continue;
if (options.ExtensionsToIgnore.Any(ignore => info.Extension.Equals(ignore, comp)))
continue;
if (options.NamesToIgnore.Any(ignore => info.Name.Equals(ignore, comp)))
continue;
try
{
File.Copy(info.FullName, destinationPath + "\\" + info.Name);
}
catch (Exception ex)
{
// report/handle error
}
}
}
With a call like:
var options = new BackupOptions
{
ExtensionsToAllow = new string[] { ".pst", ".tec", ".pas", ".snc", ".cst" },
NamesToIgnore = new string[] { "Plasma", "Oxygas", "Oxyfuel" },
CaseInsensitive = true
};
Backup("D:\\temp", "D:\\backup", options);

How to recursively list all the files in a directory in C#?

How to recursively list all the files in a directory and child directories in C#?
Note that in .NET 4.0 there are (supposedly) iterator-based (rather than array-based) file functions built in:
foreach (string file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
{
Console.WriteLine(file);
}
At the moment I'd use something like below; the inbuilt recursive method breaks too easily if you don't have access to a single sub-dir...; the Queue<string> usage avoids too much call-stack recursion, and the iterator block avoids us having a huge array.
static void Main() {
foreach (string file in GetFiles(SOME_PATH)) {
Console.WriteLine(file);
}
}
static IEnumerable<string> GetFiles(string path) {
Queue<string> queue = new Queue<string>();
queue.Enqueue(path);
while (queue.Count > 0) {
path = queue.Dequeue();
try {
foreach (string subDir in Directory.GetDirectories(path)) {
queue.Enqueue(subDir);
}
}
catch(Exception ex) {
Console.Error.WriteLine(ex);
}
string[] files = null;
try {
files = Directory.GetFiles(path);
}
catch (Exception ex) {
Console.Error.WriteLine(ex);
}
if (files != null) {
for(int i = 0 ; i < files.Length ; i++) {
yield return files[i];
}
}
}
}
This article covers all you need. Except as opposed to searching the files and comparing names, just print out the names.
It can be modified like so:
static void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d))
{
Console.WriteLine(f);
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}
Added by barlop
GONeale mentions that the above doesn't list the files in the current directory and suggests putting the file listing part outside the part that gets directories. The following would do that. It also includes a Writeline line that you can uncomment, that helps to trace where you are in the recursion that may help to show the calls to help show how the recursion works.
DirSearch_ex3("c:\\aaa");
static void DirSearch_ex3(string sDir)
{
//Console.WriteLine("DirSearch..(" + sDir + ")");
try
{
Console.WriteLine(sDir);
foreach (string f in Directory.GetFiles(sDir))
{
Console.WriteLine(f);
}
foreach (string d in Directory.GetDirectories(sDir))
{
DirSearch_ex3(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}
Directory.GetFiles("C:\\", "*.*", SearchOption.AllDirectories)
Shortest record
string[] files = Directory.GetFiles(#"your_path", "*.jpg", SearchOption.AllDirectories);
In .NET 4.5, at least, there's this version that is much shorter and has the added bonus of evaluating any file criteria for inclusion in the list:
public static IEnumerable<string> GetAllFiles(string path,
Func<FileInfo, bool> checkFile = null)
{
string mask = Path.GetFileName(path);
if (string.IsNullOrEmpty(mask)) mask = "*.*";
path = Path.GetDirectoryName(path);
string[] files = Directory.GetFiles(path, mask, SearchOption.AllDirectories);
foreach (string file in files)
{
if (checkFile == null || checkFile(new FileInfo(file)))
yield return file;
}
}
Use like this:
var list = GetAllFiles(mask, (info) => Path.GetExtension(info.Name) == ".html").ToList();
IEnumerable<string> GetFilesFromDir(string dir) =>
Directory.EnumerateFiles(dir).Concat(
Directory.EnumerateDirectories(dir)
.SelectMany(subdir => GetFilesFromDir(subdir)));
This is how we can get files as FileInfo of its child directories,
var dir = new DirectoryInfo(rootPath);
FileInfo[] files = dir.GetFiles("*.*", SearchOption.AllDirectories);
In Framework 2.0 you can use (It list files of root folder, it's best the most popular answer):
static void DirSearch(string dir)
{
try
{
foreach (string f in Directory.GetFiles(dir))
Console.WriteLine(f);
foreach (string d in Directory.GetDirectories(dir))
{
Console.WriteLine(d);
DirSearch(d);
}
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Some excellent answers but these answers did not solve my issue.
As soon as a folder permission issue arises: "Permission Denied" the code fails. This is what I used to get around the "Permission Denied" issue:
private int counter = 0;
private string[] MyDirectories = Directory.GetDirectories("C:\\");
private void ScanButton_Click(object sender, EventArgs e)
{
Thread MonitorSpeech = new Thread(() => ScanFiles());
MonitorSpeech.Start();
}
private void ScanFiles()
{
string CurrentDirectory = string.Empty;
while (counter < MyDirectories.Length)
{
try
{
GetDirectories();
CurrentDirectory = MyDirectories[counter++];
}
catch
{
if (!this.IsDisposed)
{
listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add("Access Denied to : " + CurrentDirectory); });
}
}
}
}
private void GetDirectories()
{
foreach (string directory in MyDirectories)
{
GetFiles(directory);
}
}
private void GetFiles(string directory)
{
try
{
foreach (string file in Directory.GetFiles(directory, "*"))
{
listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add(file); });
}
}
catch
{
listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add("Access Denied to : " + directory); });
}
}
Hope this helps others.
A simple and clean solution
/// <summary>
/// Scans a folder and all of its subfolders recursively, and updates the List of files
/// </summary>
/// <param name="sFullPath">Full path of the folder</param>
/// <param name="files">The list, where the output is expected</param>
internal static void EnumerateFiles(string sFullPath, List<FileInfo> fileInfoList)
{
try
{
DirectoryInfo di = new DirectoryInfo(sFullPath);
FileInfo[] files = di.GetFiles();
foreach (FileInfo file in files)
fileInfoList.Add(file);
//Scan recursively
DirectoryInfo[] dirs = di.GetDirectories();
if (dirs == null || dirs.Length < 1)
return;
foreach (DirectoryInfo dir in dirs)
EnumerateFiles(dir.FullName, fileInfoList);
}
catch (Exception ex)
{
Logger.Write("Exception in Helper.EnumerateFiles", ex);
}
}
I prefer to use DirectoryInfo because I can get FileInfo's, not just strings.
string baseFolder = #"C:\temp";
DirectoryInfo di = new DirectoryInfo(baseFolder);
string searchPattern = "*.xml";
ICollection<FileInfo> matchingFileInfos = di.GetFiles(searchPattern, SearchOption.AllDirectories)
.Select(x => x)
.ToList();
I do this in case in the future I need future filtering..based on the properties of FileInfo.
string baseFolder = #"C:\temp";
DirectoryInfo di = new DirectoryInfo(baseFolder);
string searchPattern = "*.xml";
ICollection<FileInfo> matchingFileInfos = di.GetFiles(searchPattern, SearchOption.AllDirectories)
.Where(x => x.LastWriteTimeUtc < DateTimeOffset.Now)
.Select(x => x)
.ToList();
I can also resort back to strings if need be. (and still am future proofed for filters/where-clause stuff.
string baseFolder = #"C:\temp";
DirectoryInfo di = new DirectoryInfo(baseFolder);
string searchPattern = "*.xml";
ICollection<string> matchingFileNames = di.GetFiles(searchPattern, SearchOption.AllDirectories)
.Select(x => x.FullName)
.ToList();
Note that "." is a valid search pattern if you want to filer by extension.
private void GetFiles(DirectoryInfo dir, ref List<FileInfo> files)
{
try
{
files.AddRange(dir.GetFiles());
DirectoryInfo[] dirs = dir.GetDirectories();
foreach (var d in dirs)
{
GetFiles(d, ref files);
}
}
catch (Exception e)
{
}
}
This one helped me to get all files in a directory and sub directories, May be helpful for someone. [ Inspired from above answers ]
static void Main(string[] args)
{
try
{
var root = #"G:\logs";
DirectorySearch(root);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
public static void DirectorySearch(string root, bool isRootItrated = false)
{
if (!isRootItrated)
{
var rootDirectoryFiles = Directory.GetFiles(root);
foreach (var file in rootDirectoryFiles)
{
Console.WriteLine(file);
}
}
var subDirectories = Directory.GetDirectories(root);
if (subDirectories?.Any() == true)
{
foreach (var directory in subDirectories)
{
var files = Directory.GetFiles(directory);
foreach (var file in files)
{
Console.WriteLine(file);
}
DirectorySearch(directory, true);
}
}
}
To avoid the UnauthorizedAccessException, I use:
var files = GetFiles(#"C:\", "*.*", SearchOption.AllDirectories);
foreach (var file in files)
{
Console.WriteLine($"{file}");
}
public static IEnumerable<string> GetFiles(string path, string searchPattern, SearchOption searchOption)
{
var foldersToProcess = new List<string>()
{
path
};
while (foldersToProcess.Count > 0)
{
string folder = foldersToProcess[0];
foldersToProcess.RemoveAt(0);
if (searchOption.HasFlag(SearchOption.AllDirectories))
{
//get subfolders
try
{
var subfolders = Directory.GetDirectories(folder);
foldersToProcess.AddRange(subfolders);
}
catch (Exception ex)
{
//log if you're interested
}
}
//get files
var files = new List<string>();
try
{
files = Directory.GetFiles(folder, searchPattern, SearchOption.TopDirectoryOnly).ToList();
}
catch (Exception ex)
{
//log if you're interested
}
foreach (var file in files)
{
yield return file;
}
}
}
If you only need filenames and since I didn't really like most of the solutions here (feature-wise or readability-wise), how about this lazy one?
private void Foo()
{
var files = GetAllFiles("pathToADirectory");
foreach (string file in files)
{
// Use can use Path.GetFileName() or similar to extract just the filename if needed
// You can break early and it won't still browse your whole disk since it's a lazy one
}
}
/// <exception cref="T:System.IO.DirectoryNotFoundException">The specified path is invalid (for example, it is on an unmapped drive).</exception>
/// <exception cref="T:System.UnauthorizedAccessException">The caller does not have the required permission.</exception>
/// <exception cref="T:System.IO.IOException"><paramref name="path" /> is a file name.-or-A network error has occurred.</exception>
/// <exception cref="T:System.IO.PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters and file names must be less than 260 characters.</exception>
/// <exception cref="T:System.ArgumentNullException"><paramref name="path" /> is null.</exception>
/// <exception cref="T:System.ArgumentException"><paramref name="path" /> is a zero-length string, contains only white space, or contains one or more invalid characters as defined by <see cref="F:System.IO.Path.InvalidPathChars" />.</exception>
[NotNull]
public static IEnumerable<string> GetAllFiles([NotNull] string directory)
{
foreach (string file in Directory.GetFiles(directory))
{
yield return file; // includes the path
}
foreach (string subDir in Directory.GetDirectories(directory))
{
foreach (string subFile in GetAllFiles(subDir))
{
yield return subFile;
}
}
}
Some improved version with max lvl to go down in directory and option to exclude folders:
using System;
using System.IO;
class MainClass {
public static void Main (string[] args) {
var dir = #"C:\directory\to\print";
PrintDirectoryTree(dir, 2, new string[] {"folder3"});
}
public static void PrintDirectoryTree(string directory, int lvl, string[] excludedFolders = null, string lvlSeperator = "")
{
excludedFolders = excludedFolders ?? new string[0];
foreach (string f in Directory.GetFiles(directory))
{
Console.WriteLine(lvlSeperator+Path.GetFileName(f));
}
foreach (string d in Directory.GetDirectories(directory))
{
Console.WriteLine(lvlSeperator + "-" + Path.GetFileName(d));
if(lvl > 0 && Array.IndexOf(excludedFolders, Path.GetFileName(d)) < 0)
{
PrintDirectoryTree(d, lvl-1, excludedFolders, lvlSeperator+" ");
}
}
}
}
input directory:
-folder1
file1.txt
-folder2
file2.txt
-folder5
file6.txt
-folder3
file3.txt
-folder4
file4.txt
file5.txt
output of the function (content of folder5 is excluded due to lvl limit and content of folder3 is excluded because it is in excludedFolders array):
-folder1
file1.txt
-folder2
file2.txt
-folder5
-folder3
-folder4
file4.txt
file5.txt
Here's my angle on it, based on Hernaldo's, if you need to find files with names of a certain pattern, such as XML files that somewhere in their name contain a particular string:
// call this like so: GetXMLFiles("Platypus", "C:\\");
public static List<string> GetXMLFiles(string fileType, string dir)
{
string dirName = dir;
var fileNames = new List<String>();
try
{
foreach (string f in Directory.GetFiles(dirName))
{
if ((f.Contains(fileType)) && (f.Contains(".XML")))
{
fileNames.Add(f);
}
}
foreach (string d in Directory.GetDirectories(dirName))
{
GetXMLFiles(fileType, d);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return fileNames;
}
Listing files and folders to model, custom implementation.
This creates a full listing of all files and folders starting from your start directory.
public class DirOrFileModel
{
#region Private Members
private string _name;
private string _location;
private EntryType _entryType;
#endregion
#region Bindings
public string Name
{
get { return _name; }
set
{
if (value == _name) return;
_name = value;
}
}
public string Location
{
get { return _location; }
set
{
if (value == _location) return;
_location = value;
}
}
public EntryType EntryType
{
get { return _entryType; }
set
{
if (value == _entryType) return;
_entryType = value;
}
}
public ObservableCollection<DirOrFileModel> Entries { get; set; }
#endregion
#region Constructor
public DirOrFileModel()
{
Entries = new ObservableCollection<DirOrFileModel>();
}
#endregion
}
public enum EntryType
{
Directory = 0,
File = 1
}
Method:
static DirOrFileModel DirSearch(DirOrFileModel startDir)
{
var currentDir = startDir;
try
{
foreach (string d in Directory.GetDirectories(currentDir.Location))
{
var newDir = new DirOrFileModel
{
EntryType = EntryType.Directory,
Location = d,
Name = Path.GetFileName(d)
};
currentDir.Entries.Add(newDir);
DirSearch(newDir);
}
foreach (string f in Directory.GetFiles(currentDir.Location))
{
var newFile = new DirOrFileModel
{
EntryType = EntryType.File,
Location = f,
Name = Path.GetFileNameWithoutExtension(f)
};
currentDir.Entries.Add(newFile);
}
}
catch (Exception excpt)
{
Console.WriteLine(excpt.Message);
}
return startDir;
}
Usage:
var dir = new DirOrFileModel
{
Name = "C",
Location = #"C:\",
EntryType = EntryType.Directory
};
dir = DirSearch(dir);
Short and simple solution
string dir = #"D:\PATH";
DateTime from_date = DateTime.Now.Date;
DateTime to_date = DateTime.Now.Date.AddHours(23);
var files = Directory.EnumerateFiles(dir, "*.*",SearchOption.AllDirectories).Select(i=>new FileInfo(i))
.Where(file=>file.LastWriteTime >= from_date && file.LastWriteTime <= to_date);
foreach(var fl in files)
Console.WriteLine(fl.FullName);
var d = new DirectoryInfo(#"C:\logs");
var list = d.GetFiles("*.txt").Select(m => m.Name).ToList();
Here is a version of B. Clay Shannon's code not static for excel-files:
class ExcelSearcher
{
private List<string> _fileNames;
public ExcelSearcher(List<string> filenames)
{
_fileNames = filenames;
}
public List<string> GetExcelFiles(string dir, List<string> filenames = null)
{
string dirName = dir;
var dirNames = new List<string>();
if (filenames != null)
{
_fileNames.Concat(filenames);
}
try
{
foreach (string f in Directory.GetFiles(dirName))
{
if (f.ToLower().EndsWith(".xls") || f.ToLower().EndsWith(".xlsx"))
{
_fileNames.Add(f);
}
}
dirNames = Directory.GetDirectories(dirName).ToList();
foreach (string d in dirNames)
{
GetExcelFiles(d, _fileNames);
}
}
catch (Exception ex)
{
//Bam
}
return _fileNames;
}
A very simple solution, returns a list of files.
public static List<string> AllFilesInFolder(string folder)
{
var result = new List<string>();
foreach (string f in Directory.GetFiles(folder))
{
result.Add(f);
}
foreach (string d in Directory.GetDirectories(folder))
{
result.AddRange(AllFilesInFolder(d));
}
return result;
}
static void Main(string[] args)
{
string[] array1 = Directory.GetFiles(#"D:\");
string[] array2 = System.IO.Directory.GetDirectories(#"D:\");
Console.WriteLine("--- Files: ---");
foreach (string name in array1)
{
Console.WriteLine(name);
}
foreach (string name in array2)
{
Console.WriteLine(name);
}
Console.ReadLine();
}

Categories