I have many .cshtml pages available in view folder of my MVC project. In my layout page there is search option available, so when someone search by any word, then I want to search that word in all .cshtml pages and return view name.
how can i achieve this in MVC?
A possible way to do this:
string path = Server.MapPath("~/Views"); //path to start searching.
if (Directory.Exists(path))
{
ProcessDirectory(path);
}
//Loop through each file and directory of provided path.
public void ProcessDirectory(string targetDirectory)
{
// Process the list of files found in the directory.
string[] fileEntries = Directory.GetFiles(targetDirectory);
foreach (string fileName in fileEntries)
{
string found = ProcessFile(fileName);
}
//Recursive loop through subdirectories of this directory.
string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
foreach (string subdirectory in subdirectoryEntries)
{
ProcessDirectory(subdirectory);
}
}
//Get contents of file and search specified text.
public string ProcessFile(string filepath)
{
string content = string.Empty;
string strWordSearched = "test";
using (var stream = new StreamReader(filepath))
{
content = stream.ReadToEnd();
int index = content.IndexOf(strWordSearched);
if (index > -1)
{
return Path.GetFileName(filepath);
}
}
}
Related
goal: we are not talking about files, but about folders. if the desired folder, which is specified in the array of strings, is available on the desktop, then we need to get subdirectories and paths to this folder, if the desired folder is not on the desktop, then the search for this folder has already been performed in appdata, and then the same thing, if the folder is present, then we get subdirectories and paths to this folder.
string[] directory = new string [] {#"folder1/", #"folder3/", }
foreach (string sPath in directory)
{
string Path;
if (sPath.Contains("folder1"))
{
Path = Desktop + sPath;
}
else
{
Path = Appdata + sPath;
}
there is an if (sPath.Contains("folder1"))
I intended the string Path to first take the Path = "Desktop + sPath" logic to return the names of the subdirectories of the folder1 folder
if (Directory.Exists(Path)) foreach (string folder in Directory.GetDirectories(Path))
{
Console.WriteLine(folder);
this code does not work for me = (if you delete a folder from the desktop, which, for example, was present, then the search from another place that is specified in the code is not carried out( how to fix the situation?
string Path;
if (sPath.Contains("folder1"))
{
Path = Desktop + sPath;
}
else
{
Path = Appdata + sPath;
}
full code
string [] directory = new string [] {#"folder1/", #"folder3/", }
foreach (string sPath in directory)
{
string sFullPath;
if (sPath.Contains("folder1"))
{
sFullPath = Desktop + sPath;
}
else
{
sFullPath = Appdata + sPath;
}
if (Directory.Exists(sFullPath)) foreach (string folder in Directory.GetDirectories(sFullPath))
{
Console.WriteLine(folder);
}
}
First of all we should come to terms. To be "available on the desktop" is to be a subfolder of
// Have a look at
// Environment.SpecialFolder.CommonDesktopDirectory
// Environment.SpecialFolder.DesktopDirectory
// as well
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
then we can manipulate with directory array:
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string[] directory = new string [] {#"folder1/", #"folder3/", };
foreach (string sPath in directory) {
if (Directory.Exists(Path.Combine(desktop, sPath))) {
// available on the desktop
}
else if (Directory.Exists(Path.Combine(appData, sPath))) {
// available on the AppData
}
else {
// not exists
}
}
I have the below throwing an exception: System.ArgumentException: 'Empty file name is not legal.
Parameter name: sourceFileName'
public bool ArchiveFile()
{
int fileCount = Directory.GetFiles(#"\\company\Archive\IN\InvoiceTest\Inbox\").Length;
DirectoryInfo diFileCheck = new DirectoryInfo(#"\\company\Archive\IN\InvoiceTest\Inbox\");
foreach (var fi in diFileCheck.GetFiles())
{
string strSourceFile = Path.GetFileName(#"\\company\Archive\\IN\InvoiceTest\Inbox\");
string strDestination =Path.Combine(#"\\company\ArchiveIN\InvoiceTest\Archive\", strSourceFile);
File.Move(strSourceFile, strDestination);
}
if (fileCount==0)
{
string strMessage = "No file found in directory: \n\n";
MessageBox.Show(strMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
else
{
return true;
}
}
Your problem is here:
foreach (var fi in diFileCheck.GetFiles())
{
string strSourceFile = Path.GetFileName(#"\\company\Archive\\IN\InvoiceTest\Inbox\");
string strDestination = Path.Combine(#"\\company\ArchiveIN\InvoiceTest\Archive\", strSourceFile);
File.Move(strSourceFile, strDestination);
}
Your fi is a FileInfo object, but you are not using it. Instead of using Path.GetFileName, use fi.Name.
See FileInfo
This reads all files from a source directory, and moves them to a target directory:
var filePaths = Directory.GetFiles("Source"); // get file paths from folder 'Source'
foreach (var filePath in filePaths)
{
var fileName = Path.GetFileName(filePath); // get only the name of the file
var targetPath = Path.Combine("Target", fileName); // create path to target directory 'Target' (including file name)
File.Move(filePath, targetPath); // move file from source path to target path
}
I have created something that grabs all file names that have the extension .lua with them. This will then list them in a CheckListBox. Everything goes well there but I want to know which one of the CheckListBox's are ticked/checked and then open them in notepad.exe.
To dynamically add the files Code (works perfectly, and adds the files i want)
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string path = appData + "\\Lua";
string[] fileArray = Directory.GetFiles(path, "*.lua");
for (int i = 0; i < fileArray.Length; i++)
{
string Name = Path.GetFileName(fileArray[i]);
string PathToLua = fileArray[i];
ScriptsBoxBox.Items.AddRange(Name.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries));
Console.WriteLine(fileArray[i]);
}
Then when i check the items i want to open in notepad i use `
System.Diagnostics.Process.Start("notepad.exe", ScriptsBoxBox.CheckedItems.ToString());
Or
System.Diagnostics.Process.Start("notepad.exe", ScriptsBoxBox.CheckedItems);
Neither works and im pretty sure it's on my end. So my problem is that i cannot open the file that is ticked/checked in checklistbox and want to resolve this problem. However when I do
System.Diagnostics.Process.Start("notepad.exe", PathToLua);
It opens the files with .lua extension ticked or not which makes sense.
I don't think there are any arguments that you can pass to notepad to open a list of specific files. However, you can use a loop to open each file.
foreach (var file in ScriptsBoxBox.CheckedItems)
{
System.Diagnostics.Process.Start("notepad.exe", file);
}
I don't know WinForms as well as WPF but here goes
You need an object that contains your values
public class LuaFile
{
public string FileName { get; set; }
public string FilePath { get; set; }
public LuaFile(string name, string path)
{
FileName = name;
FilePath = path;
}
public override string ToString()
{
return FileName;
}
}
Replace your for loop with
foreach (var file in files)
{
ScriptsBoxBox.Items.Add(new LuaFile(Path.GetFileName(file), file));
}
And to run the checked files
foreach (var file in ScriptsBoxBox.CheckedItems)
{
System.Diagnostics.Process.Start("notepad.exe", ((LuaFile)file).FilePath);
}
Thanks everyone that helped but I solved it on my own (pretty easy when you read :P)
For anyone in the future that wants to do this here is how i accomplished it.
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string path = appData + "\\Lua";
string[] fileArray = Directory.GetFiles(path, "*.lua");
for (int i = 0; i < fileArray.Length; i++)
{
string Name = Path.GetFileName(fileArray[i]);
string PathToLua = fileArray[i];
//ScriptsBoxBox.Items.AddRange(Name.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries));
// Console.WriteLine();
Console.WriteLine(ScriptsBoxBox.CheckedItems.Contains(Name));
var pathname = ScriptsBoxBox.CheckedItems.Contains(Name);
if (ScriptsBoxBox.CheckedItems.Contains(Name))
{
System.Diagnostics.Process.Start("notepad.exe", fileArray[ScriptsBoxBox.CheckedItems.IndexOf(Name)]); // I supposed this would get the correct name index, and it did! fileArray by default seems to get the path of the file.
}
I have been using the following lines to search a folder structure for specific filetypes and just copy those filetypes and maintain their original folder structure. It works very well.
Is there any modification I can make to my method to only copy the directories that contain the filtered filetype?
*edit: I can let the user select a only certain set of files, (example *.dwg or *.pdf), using text box named txtFilter.
private void button1_Click(object sender, EventArgs e)
{
string sourceFolder = txtSource.Text;
string destinationFolder = txtDestination.Text;
CopyFolderContents(sourceFolder, destinationFolder);
}
// Copies the contents of a folder, including subfolders to an other folder, overwriting existing files
public void CopyFolderContents(string sourceFolder, string destinationFolder)
{
string filter = txtFilter.Text;
if (Directory.Exists(sourceFolder))
{
// Copy folder structure
foreach (string sourceSubFolder in Directory.GetDirectories(sourceFolder, "*", SearchOption.AllDirectories))
{
Directory.CreateDirectory(sourceSubFolder.Replace(sourceFolder, destinationFolder));
}
// Copy files
foreach (string sourceFile in Directory.GetFiles(sourceFolder, filter, SearchOption.AllDirectories))
{
string destinationFile = sourceFile.Replace(sourceFolder, destinationFolder);
File.Copy(sourceFile, destinationFile, true);
}
}
}
Something like this in your main loop?
if (Directory.EnumerateFiles(sourceSubFolder, "*.pdf").Any())
Directory.CreateDirectory(sourceSubFolder.Replace(sourceFolder, destinationFolder));
or for multiple file types:
if (Directory.EnumerateFiles(sourceSubFolder).Where(x => x.ToLower.EndsWith(".pdf") || x.ToLower.EndsWith(".dwg")).Any())
Directory.CreateDirectory(sourceSubFolder.Replace(sourceFolder, destinationFolder));
You can simply concatenate both operations into one loop and complete the algorithm in O(n).
foreach(string sourceFile in Directory.GetFiles(sourceFolder, filter, SearchOption.AllDirectories))
{
Directory.CreateDirectory(Path.GetDirectoryName(sourceFile.Replace(sourceFolder,destinationFolder)));
File.Copy(sourceFile,sourceFile.Replace(sourceFolder,destinationFolder),true);
}
You can get the distinct directories from the files you find, then iterate through them and create the directories before copying the files.
if (Directory.Exists(sourceFolder))
{
var files = Directory.GetFiles(sourceFolder, filter, SearchOption.AllDirectories);
foreach(string directory in files.Select(f => Path.GetDirectoryName(f)).Distinct())
{
string destinationDirectory = directory.Replace(sourceFolder, destinationFolder);
if (!Directory.Exists(destinationDirectory))
{
Directory.CreateDirectory(destinationDirectory);
}
}
foreach (string sourceFile in files)
{
string destinationFile = sourceFile.Replace(sourceFolder, destinationFolder);
File.Copy(sourceFile, destinationFile, true);
}
}
I'm trying to search for files of extension .dcm, by entering either the filename or the content of the file. I am able to search in a directory, but when i try searching in a drive, I get an error that says missing directory or an assemble reference.
string startFolder = #"C:\";
// Take a snapshot of the file system.
System.IO.DriveInfo dir = new System.IO.DriveInfo(startFolder);
// This method assumes that the application has discovery permissions
// for all folders under the specified path.
IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.*", System.IO.
SearchOption.
AllDirectories);
Try to search in drive like in folder it works:
string startFolder = #"c:\";
DirectoryInfo directoryInfo = new DirectoryInfo(startFolder);
IEnumerable<System.IO.FileInfo> fileList = directoryInfo.GetFiles("*.*", System.IO.SearchOption.AllDirectories);
Use this recursive function to avoid exceptions:
public static IEnumerable<string> GetFiles(string path, string pattern)
{
IEnumerable<string> result;
try
{
result = Directory.GetFiles(path, pattern);
}
catch (UnauthorizedAccessException)
{
result = new string[0];
}
IEnumerable<string> subDirectories;
try
{
subDirectories = Directory.EnumerateDirectories(path);
}
catch (UnauthorizedAccessException)
{
subDirectories = new string[0];
}
foreach (string subDirectory in subDirectories)
{
IEnumerable<string> subFiles = GetFiles(subDirectory, pattern);
result = result.Concat(subFiles); //This is LINQ concatenation
}
return result;
}
static void Main(string[] args)
{
string startFolder = #"c:\";
foreach (string fileName in GetFiles(startFolder, "*.chm"))
{
Console.WriteLine(fileName);
}
You can filter out immediatelly all the files with *.dcm extension
string startFolder = #"c:\";
DirectoryInfo directoryInfo = new DirectoryInfo(startFolder);
IEnumerable<System.IO.FileInfo> fileList = directoryInfo.GetFiles("*.dcm", System.IO.SearchOption.AllDirectories);
After that use foreach loop to find either a file with the desired name or open the file for reading and search for the value inside the file.
Are *.dcm text-based files or binary files? If they are text-based files you could use regulare expression to figure out whether the search string exists or not.
EDIT: Here is the sample recursive function that does the job. It is a console application so adapt it for your needs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
namespace FileSearcher
{
class Program
{
static string searchValue = "Windows";
static List<FileInfo> files = new List<FileInfo>();
static void Main(string[] args)
{
string startFolder = #"C:\";
DirectoryInfo diParent = new DirectoryInfo(startFolder);
FindSearchValue(diParent);
foreach (var file in files)
{
Console.WriteLine("{0}", file.FullName);
}
Console.WriteLine("Press any key to continue...");
Console.ReadLine();
}
/// <summary>
/// Recursive function that searches for a file that matches the criteria.
/// If the file is not found, the current file is opened and it's contents is
/// scanned for search value.
/// </summary>
/// <param name="diParent">Current parent folder being searched.</param>
private static void FindSearchValue(DirectoryInfo diParent)
{
FileInfo[] foundFiles = diParent.GetFiles("*.doc");
foreach (var file in foundFiles)
{
Console.WriteLine(file.FullName);
if (file.FullName.Contains(searchValue)) // There is a search string in a file name
{
files.Add(file);
}
else
{
string fileContents = File.ReadAllText(file.FullName);
if (fileContents.Contains(searchValue)) // Here you can use Regex.IsMatch(fileContents, searchValue)
{
files.Add(file);
}
}
}
foreach (var diChild in diParent.GetDirectories())
{
try
{
FindSearchValue(diChild);
}
catch (Exception exc)
{
Console.WriteLine("ERROR: {0}", exc.Message);
}
}
}
}
}
This function uses try-catch block to intercept exceptions that might occur. For example, file not found or access denied. Hope this helps!