I have a list of text files that I want to be able to open in a console application.
The output I want is something like:
List1.txt
List2.txt
List3.txt
etc
Once I get this output I want a way of being able to call one of those files and have it open via Console.ReadLine();
What I'm doing at the moment is
string[] FileNames = Directory.GetFiles(#"Itemized\", ".txt");
Console.WriteLine(String.Join(Environment.NewLine,FileNames));
This allows me to get as far as getting list that looks like:
Itemized\List1.txt
Itemized\List2.txt
Itemized\List3.txt
If I know the number of files in the folder I can hard code it but the problem I have is that any number of files could be present.
So what im looking for at the moment is a way to append a scaling numeric value to each file and remove the folder-name from the front of it.
I've tried using a for loop to get it to work but can't seem to get my head around it.
Try something like this
var fileNames = Directory.GetFiles(#"Itemized\", "*.txt").Select(Path.GetFileName).ToArray();
Console.WriteLine(string.Join(Environment.NewLine, fileNames));
Here is something clean and simple:
static void Main(string[] args)
{
string dirFolderPath = string.Format("{0}/{1}", Directory.GetCurrentDirectory(), "Itemized");
DirectoryInfo dir = new DirectoryInfo(dirFolderPath);
if(!dir.Exists)
{
dir.Create();
}
FileInfo[] files = dir.GetFiles("*.txt");
for(int i = 0; i < files.Length; i++)
{
string line = string.Format("\n{0}-{1}", i, files[i].Name);
Console.WriteLine(line);
}
Console.ReadLine();
}
Related
I am trying to avoid empty files in my Program and the way i am doing it doesnt work.
I got a machschine that create logs, at Weekend is nobody here and but the maschine create a file with only 5,6 lines, the right one should have 20k lines.
I know there is FileInfo.Length but i dont know how to use it with this what a have right now.
public List<SystemLogFileData> ProcessSystemLogFiles(List<string> systemLogsFilePaths)
{
List<SystemLogFileData> systemLogFilesData = new List<SystemLogFileData>();
foreach (var filePath in systemLogsFilePaths)
{
string[] lines = System.IO.File.ReadAllLines(filePath);
var systemLogFileData = ProcessSystemLogFile(lines.ToList());
if (File.ReadAllText(systemLogFileData).Length > 100)
{
systemLogFilesData.Add(systemLogFileData);
}
}
return systemLogFilesData;
}
I solved it and it works well. Not in my main Program but in Autobackup.
insted of ignoring the the not important file i don't copy them and i reached my goal.
Thakns for the help!
//path of file
string pathToOriginalFile = #"C:\Users\Desktop\c#\Logging\Systemlog.bk66";
//duplicate file path
string PathForDuplicateFile = #"C:\\\Desktop\c#\Systemlog";
//rename fileName if Exists
FixFileName(ref PathForDuplicateFile, ".bk");
if (File.ReadAllText(pathToOriginalFile).Length > 2000)
{
File.Copy(pathToOriginalFile, PathForDuplicateFile);
}
else
{
}
//provide source and destination file paths
I have a unity project that i need to rename basically all my files in it to contain a - as a way of easily identifying what assetbundle i need to load it from.
I would need to insert a - at the end of the identifier so for example, testtest.png would become test-test.png and so on.
I currently have this (just want to get the identifier from the file name itself for now) however, the first string in temp is always empty with the second one containing the rest of the file name
foreach (string file in Directory.GetFiles(Directory.GetCurrentDirectory()))
{
string name = file.Split('\\').Last();
if (name.StartsWith(args[0]))
{
string[] temp = name.Split(new[]{args[0]},StringSplitOptions.None);
foreach (string s in temp)
{
Console.WriteLine(s);
}
}
}
D:\renamething\bin\Debug>renamething.exe test
.pdb
I tried Regex for it as well however it produced the same result, empty string in the first one, rest of it in the second.
I don't think that would work, especially the args[0]
Try this:
foreach (string file in Directory.GetFiles(Directory.GetCurrentDirectory()))
{
var fileInfo = new FileInfo(file); //Get FileInfo
if (!fileInfo.Name.StartsWith(args[0], StringComparison.OrdinalIgnoreCase)) //If File doesn't start with the specified arguments, don't process
{
continue;
}
//Consider file -> C:/TestFolder/test.png
var directory = fileInfo.DirectoryName;//Gives C:\TestFolder\
var extension = fileInfo.Extension; //gives ".png"
var fileName = Path.GetFileNameWithoutExtension(fileInfo.Name); //Gives "test"
var modifiedFileName = $"{fileName}-test{extension}"; //Gives "test-test.png
var modifiedFullPath = $"{directory}/{modifiedFileName}";// C:\TestFolder\test-test.png
fileInfo.MoveTo(modifiedFullPath);
}
With the code from #Zee (and #Dai from having a second look over), here is what i ended up in the odd chance that anyone else in the future comes here and needs it
public static void Main(string[] args){
foreach(string file in Directory.GetFiles(Directory.GetCurrentDirectory())){
FileInfo fileInfo=new FileInfo(file);
if(fileInfo.Name.StartsWith(args[0])&&fileInfo.Name.EndsWith(".png"){
string[]temp=Regex.Split(fileInfo.Name, #"(?<!^)(?=[A-Z])");
temp[0]+="-";
File.Move(fileInfo.FullName,String.Concat(temp));
}
}
}
I try to get the Full Path of a File. ie. calc
Input: calc
Expected output: C:\WINDOWS\system32\calc.exe
I could find out how to do it with PowerShell:
(Get-Command calc).Source
Or with CommandLine:
where.exe calc
But unfortunately I can not get it done with C#.
The documentation for Get-Command says:
Get-Command * gets all types of commands, including all of the non-PowerShell files in the Path environment variable ($env:Path), which it lists in the Application command type.
So we will need to get the Path environment variable and iterate over the directories it lists, looking for files with extensions that indicate the file is a program, for example "*.com" and "*.exe".
The problem with the Path environment variable is that it can become polluted with non-existent directories, so we will have to check for those.
The case of the filename and extension don't matter, so case-insensitive comparisons need to be made.
static void ShowPath(string progName)
{
var extensions = new List<string> { ".com", ".exe" };
string envPath = Environment.GetEnvironmentVariable("Path");
var dirs = envPath.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string d in dirs.Where(f => Directory.Exists(f)))
{
foreach (var f in (Directory.EnumerateFiles(d).
Where(thisFile => extensions.Any(h => Path.GetExtension(thisFile).Equals(h, StringComparison.InvariantCultureIgnoreCase)))))
{
if (Path.GetFileNameWithoutExtension(f).Equals(progName, StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine(f);
return;
}
}
}
Console.WriteLine("Not found.");
}
static void Main(string[] args)
{
ShowPath("calc");
Console.ReadLine();
}
Output:
C:\WINDOWS\system32\calc.exe
There is always the possibility that the current user does not have permission to list the files from somewhere in the path, so checks should be added for that. Also, you might want to use StringComparison.CurrentCultureIgnoreCase for the comparison.
You can get the Pathenvironment variable, split it with ; as delimiter and loop over that result. Then, check if the file path + #"\" + name + ".exe" exists.
var findMe = "calc";
var pathes = Environment.GetEnvironmentVariable("Path").Split(';');
foreach (var path in pathes)
{
var testMe = $#"{path}\{findMe}.exe";
if (File.Exists(testMe))
{
Console.WriteLine(testMe);
}
}
This outputs :
C:\WINDOWS\system32\calc.exe
I do not know about any way of doing that exact thing from C# either. However the paths are usually well known and can be retreived via the SpecialFolders Enumeration:
using System;
using System.Diagnostics;
using System.IO;
namespace RunAsAdmin
{
class Program
{
static void Main(string[] args)
{
/*Note: Running a batch file (.bat) or similar script file as admin
Requires starting the interpreter as admin and handing it the file as Parameter
See documentation of Interpreting Programm for details */
//Just getting the Absolute Path for Notepad
string windir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
string FullPath = Path.Combine(windir, #"system32\notepad.exe");
//The real work part
//This is the programm to run
ProcessStartInfo startInfo = new ProcessStartInfo(FullPath);
//This tells it should run Elevated
startInfo.Verb = "runas";
//And that gives the order
//From here on it should be 100% identical to the Run Dialog (Windows+R), except for the part with the Elevation
System.Diagnostics.Process.Start(startInfo);
}
}
}
I did not just use System (37) back then, as I wrote it when x32/x86 Systems were still a thing. You would need to check how it resolves nowadays.
Note that most of those paths are duplicated in the PATH System Variable, so you could look it up: https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/
Path Variables in turn go back to the old DOS days. Basically if you gave the Commandline a command/filename it would try the build-in commands, then Executables in the current working Directory (.bat, .com, .exe), and then go look over the path directories to again look for executeables. And only if all that failed, would it complain.
I finally tried to combine all three answers and came up with this:
I post it here in case someone has the same problem.
public static string[] GetPathOf(string cmd)
{
var list = new List<string>();
list.AddRange(Environment.GetEnvironmentVariable("path", EnvironmentVariableTarget.Machine).Split(';'));
list.AddRange(Environment.GetEnvironmentVariable("path", EnvironmentVariableTarget.Process).Split(';'));
list.AddRange(Environment.GetEnvironmentVariable("path", EnvironmentVariableTarget.User).Split(';'));
list = list.Distinct().Where(e=>Directory.Exists(e)).SelectMany(e=> new DirectoryInfo(e).GetFiles()).Where(e=>Regex.IsMatch(e.Name,"(?i)^"+cmd+"\\.(?:exe|cmd|com)")).Select(e=>e.FullName).ToList();
return list.ToArray();
}
I would like to create a simple copy console application (I know copy already exists in DOS). Exactly like the DOS copy command I would like to be able to execute my copy application with two simple arguments:
copy C:\Users\Admin\Samples\*.pdf C:\
Input path and search pattern
Ouput path
In my code I use this
static void Main(string[] args)
{
string input;
string output;
var options = new Options();
ICommandLineParser parser = new CommandLineParser();
if (parser.ParseArguments(args, options))
{
input = options.Argument[0];
output = options.Argument[1];
// Get file list
String directory = Path.GetDirectoryName(input);
String[] files = Directory.GetFiles(directory, /* ??? */);
// To be continued...
}
else
{
System.Console.WriteLine("Erreur");
System.Console.ReadKey();
}
}
How can I easely retrieve my search pattern? Is beter way to do this?
Try this:
string extension = System.IO.Path.GetExtension(input);
string inputDirectory = System.IO.Path.GetDirectoryName(input);
I think this is what you wanted.
To get the path, or the file, of the input parameter, you can use the following:
Path.GetFileName(input);
I am having a problem .
My Problem is to read all the subdirectories in a given destination which contain Master file .
I can read subdirectories but i am creating a project which only read given directory which should contain Master file in the directory .
In the given directory a file called Master file should be there.
I want to write the code like if the given directory doesnot contain any Master file in it it should Jump to another Directory.
My source Directory is #"C:\test.
In #"C:\test" there are many folders and subfolders .
the test directory contains "C:\test\test1\test2\test3 . In this path test3 folder contains Master file test1 and test2 doesn't .
I want to write this code something like this,
MLMReader Reader = new MLMReader();
Reader.OpenDirectory(#"C:\test");
if (!File.Exists(test + "\\Master"))
{
//i want to loop the "C"\\" and if test1 does not contain
// Master File then jump to another directory test2, if
//test2 directory contain Master File then the work should
// continue after finishing go to test3
}
Is there any way to do .
Any suggestions for my problem.
I haven't tested, but I'm pretty sure the following will work:
string[] paths = Directory.GetFiles(dirPath, "MasterFile", SearchOption.AllDirectories);
Then you can just foreach over the resulting array, if you want to go through all MasterFiles. Or if you just care about the first result, then it's just paths[0] -- of course, means it does a lil bit extra work finding all matching paths. And you probably don't need a check for an empty array as an index out of bounds would indicate there's no MasterFile (unless you want to catch that and then rethrow as file not found exception or whatever).
Linq-to-FileSystem allows you to perform structured queries on your file system. See the following example:
var dir = new DirectoryInfo(#"C:\test");
// find all subdirectories of test that contains a file / folder called 'Master'
var dirs = dir.Elements()
.Where(d => d.Elements().Any(i => i.Name == "Master"))
this is my code where I program with directorys, hope it will help you.
using System;
using System.IO;
static void Print(string path, int? rec, int? tree, bool color, int? level = 0)
{
if ((rec != null && level > rec) || path == null) return;
if (rec == null) rec = 0;
string[] dir;
string[] fil;
try
{
dir = Directory.GetDirectories(path);
fil = Directory.GetFiles(path);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
return;
}
foreach (string s in dir)
{
WriteSpace(level,tree);
Console.WriteLine(s);
Print(s, rec, tree, color, level + 1);
}
if (color)
{
ConsoleColor def = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Blue;
foreach (string s in fil) // vypis file
{
WriteSpace(level, tree);
Console.WriteLine(s);
}
Console.ForegroundColor = def;
}
else
{
foreach (string s in fil)
{
WriteSpace(level, tree);
Console.WriteLine(s);
}
}
}
private static void WriteSpace(int? level, int? tree)
{
for (int i = 0; i < level*tree; i++)
Console.Write(" ");
}
}
Here's a Recursive Example on how you can traverse a directory structure and look for a certain file, once it is found you can call the corresponding method.
static void Main()
{
TraverseDirectory(#"D:\TestDirectory");
}
static void DoSomethingWithMaster(string path)
{
Console.WriteLine("Found master at {0}", path);
}
static void TraverseDirectory(string directory)
{
var currentDirectory = new DirectoryInfo(directory);
foreach(var dir in currentDirectory.GetDirectories())
{
var currentPath = dir.FullName;
TraverseDirectory(currentPath);
var pathToMasterFile = Path.Combine(currentPath, "Master");
if (File.Exists(pathToMasterFile))
DoSomethingWithMaster(pathToMasterFile);
}
}
I have the following Folder Structure:
D:\TestDirectory\1
D:\TestDirectory\2
D:\TestDirectory\3
D:\TestDirectory\4
D:\TestDirectory\4\Master
D:\TestDirectory\5
And when running the above it prints: Found master at D:\TestDirectory\4
All you need for this is:
using System;
using System.IO;
You can also move TraverseDirectory(currentPath); to the end of the foreach-loop, where you put it depends on when you want to detect the file, do you want to go deep and then climb your way back and check for the Master-file on the way up, or do you want to check for the master file before you enter the next directory?
According to your question, you might want to swap them in my answer and if I understand you correctly, you might not even want to go to the next directory after finding one master-file?
foreach(var dir in currentDirectory.GetDirectories())
{
var currentPath = dir.FullName;
var pathToMasterFile = Path.Combine(currentPath, "Master");
if (File.Exists(pathToMasterFile))
DoSomethingWithMaster(pathToMasterFile);
TraverseDirectory(currentPath);
}
In this example, it does exactly what you are saying in your commented code inside your if. It will first check TestDirectory\1 for a Master file and then go further down the line. If you don't care about any other Master-files in one sub-directory once it is found, you can just nest TraverseDirectory(pathToMasterFile) inside an else-block.
Edit
You might want to use EnumerateDirectories, see MSDN for details.