Basically I am trying to make a program that empties or even deletes a certain file, the thing is, this file is about 3 or 4 or so folders past the macromedia folder, and it can be it different named folders for anyone, so that is why the string[] files is done like that, it just checks for basically "FlashGame.sol" in EVERY folder after the macromedia folder.
I commented where I need help, I basically need to empty the contents of the file, or just flat out delete it.
private void button1_Click(object sender, EventArgs e)
{
string path = textBox1.Text + "/AppData/Roaming/Macromedia"; //the person using the program has to type in the beginning of the directory, C:/Users/Mike for example
bool Exists = Directory.Exists(path);
try
{
if (Exists)
{
string[] files = Directory.GetFiles(path, "*FlashGame.sol", SearchOption.AllDirectories);
string[] array = files;
for (int i = 0; i < array.Length; i++)
{
string info;
string text = array[i];
using (StreamReader streamReader = new StreamReader(text))
{
info = streamReader.ReadToEnd();
//erase the contents of the file here or even delete it
}
}
}
}
catch
{
MessageBox.Show("The given directory was not found", "Error", MessageBoxButtons.OK);
}
}
You can clear a file this way:
System.IO.File.WriteAllText(#"file.path",string.Empty);
So you should probably change your Code to:
string[] files = Directory.GetFiles(path, "*FlashGame.sol", SearchOption.AllDirectories);
foreach (var file in files)
{
System.IO.File.WriteAllText(file, string.Empty);
}
Also take a look at Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), which gives the appdata directory of the current user.
Also never catching a Exception without handling it correctly. You already know, if the directory exists via your Exists Variable.
string path = Environment.ExpandEnvironmentVariables(#"%AppData%\Macromedia\"); // Example C:\Users\Mike\AppData\Roaming\Macromedia\
if (Directory.Exists(path)) {
string[] files = Directory.EnumerateFiles(path, "*FlashGame.sol", SearchOption.AllDirectories);
foreach (string file in files) {
try {
File.Delete(file);
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
}
Related
I want to get the full path of the file named wampmanager.conf on disk D. I coded the following for this:
private static string Scan(string path, string file)
{
try
{
foreach (var dir in Directory.EnumerateDirectories(path))
{
foreach (var fl in Directory.EnumerateFiles(dir, file))
{
if (!string.IsNullOrEmpty(fl))
{
return fl;
}
}
}
}
catch (Exception)
{
// ignored
}
return null;
}
var wmc = Scan(#"D:\", "wampmanager.conf");
MessageBox.Show(wmc);
It always returns null even though the wampmanager.conf file exists on the disk D. I guess it goes to a directory like d:\recovery\ that I don't have access to, then it crashes into a catch and returns null. But when I don't use try catch I always get access authorization error. How can I deal with this problem?
For each directory you must use SearchOption.AllDirectories to Includes the current directory and all its subdirectories in a search operation. Try this function:
private static string Scan(string path, string file)
{
foreach (var dir in Directory.EnumerateDirectories(path))
try
{
string[] files = Directory.GetFiles(dir, file, SearchOption.AllDirectories);
if (files.Length > 0)
{
return files[0];
}
}
catch (Exception e)
{
string s = e.Message;
}
return "not found!";
}
I am making an app in C# where I am searching if the file exists in the text file or not. If it does not exist then, it would add it in the text file and then append it in a List. But, for some reason the list only takes one file and ends at that point. So, can someone help me with what is the problem in this foreach loop?
static void CheckNewFile()
{
string path_f = #"File_Address_where_Text_file_exists";
var new_file = new List<string>();
if (!File.Exists(path_f)) # Checking if the text file exists or not and then creating it
{
var myFile = File.Create(path_f);
myFile.Close();
}
DirectoryInfo hdDirectoryInWhichToSearch = new DirectoryInfo(#"File_Address_in_which_Files_need_to_be_searched");
FileInfo[] filesInDir = hdDirectoryInWhichToSearch.GetFiles("AC" + "*" + "*.*" + "AC"); # Format of the file to be searched
foreach (FileInfo foundFile in filesInDir) # foreach for the files in the directory
{
string fullName = foundFile.FullName;
int flag = 0;
var lines = File.ReadLines(path_f);
foreach (var line in lines) # Reading line by line and checking if the file exists in the text file before
{
if (String.Equals(line, fullName))
{
flag += 1;
break;
}
}
if (flag < 1)
{
if (new FileInfo(path_f).Length == 0) # File Address is appended in the File
{
//TextWriter tw = new StreamWriter(path_f);
//tw.WriteLine(fullName);
//tw.Close();
}
else
{
//using (var tw = new StreamWriter(path_f, true))
//{
// tw.WriteLine(fullName);
//}
}
new_file.Add(fullName.ToString()); # Adding File Address to the list
flag = 0;
break;
}
}
}
Remove the last break. It is causing the program flow to leave the enclosing foreach loop with the file names.
As the other poster mentioned, you're breaking out of your loop early in the if block.
However, there isn't really a need for the flag (or loop or if block) at all. Your method could be simplified greatly by using a little System.Linq and just using Directory to find the new files by comparing their paths to the contents of the input file.
For example:
static List<string> CheckForNewFiles(string filePath, string searchDir,
string searchPattern)
{
// Create file if it doesn't exist
if (!File.Exists(filePath)) using (File.Create(filePath)) ;
// Get list of files that match search pattern which aren't contained in our file
var newFiles = Directory
.GetFiles(searchDir, searchPattern)
.Where(match => !File.ReadLines(filePath).Contains(match))
.ToList();
// Add the new file paths to our file
File.AppendAllLines(filePath, newFiles);
// Return the list of new files (?)
return newFiles;
}
In use it migth look something like:
public static void Main()
{
Console.WriteLine("Checking for new files...");
var newFiles = CheckForNewFiles(#"c:\temp\paths.txt", #"c:\temp\temp", "*.png");
Console.WriteLine($"{newFiles.Count} files found since last search.");
if (newFiles.Any())
{
Console.WriteLine(" -> " + string.Join(Environment.NewLine + " -> ", newFiles));
}
Console.ReadLine();
}
I have a source and destination path with the same folder and file names (source has some extra files). my question is when I have cut source locations files and folders and to paste the destination location
how to copied initially the extra files(destination not having files)?
how to through the error after paste the extra files "the folder and files already exist do you want to replace it" message?
after getting the response how can I move and delete the source files?
somebody can help me guys I am stuck with this logic nearly 2 days.
Note: am the beginner of the C# server side code.
thanks, advance. Hi All, thank you for your reply, I have written the same structure with #RezaNoei mentioned my code was
private void DirectoryCopy(string sourceDirName, string destDirName, bool replace, string action)
{
try
{
// Gets the subdirectories for the specified directory.
var dir = new DirectoryInfo(sourceDirName);
var dirs = dir.GetDirectories();
// If the destination directory doesn't exist, creates it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
// Gets the files in the directory and copy them to the new location.
var files = dir.GetFiles();
foreach (var file in files)
{
var oldPath = Path.Combine(sourceDirName, file.Name);
var temppath = Path.Combine(destDirName, file.Name);
var fileExist = File.Exists(temppath);
if (!fileExist)
{
if (action != "paste")
{
file.CopyTo(temppath, true);
}
else
{
File.Move(oldPath, temppath);
}
}
else if (fileExist && replace)
{
File.Delete(temppath);
if (action != "paste")
{
file.CopyTo(temppath, true);
}
else
{
File.Move(oldPath, temppath);
}
}
}
if (action == "paste")
{
DeleteDirectory(sourceDirName);
}
}
catch (Exception e)
{
throw e;
}
}
Use this Function:
Note: If you are developing a web-application and you want to alert this through Html, it doesn't help you. Please read the Next Section "For Web-Application"
Note2: this function doesn't check for inner folders. so if you have a nested path, we should write a recursive function.
public void Copy(string Source, string Destination)
{
string[] SourceFiles = System.IO.Directory.GetFiles(Source);
for (int i = 0; i < SourceFiles.Length; i++)
{
string DestinationFilePath = System.IO.Path.Combine(Destination, System.IO.Path.GetFileName(SourceFiles[i]));
if (System.IO.File.Exists(DestinationFilePath))
{
var DialogResult = MessageBox.Show($"File `{System.IO.Path.GetFileName(SourceFiles[i])}` Exists in the Destination. Are you want to overwrite this file ?", "File Exist !", MessageBoxButtons.YesNo);
if (DialogResult == DialogResult.Yes)
System.IO.File.Copy(SourceFiles[i], DestinationFilePath, true);
}
else
{
System.IO.File.Copy(SourceFiles[i], DestinationFilePath);
}
}
}
For Web-Application:
You actually need to interact with User. And it make our work more complicated than before.
You will Work with Session and you must keep track of this Operation. I don't know which technology are you using but you must but added these ones to Session:
1-1 **Destination Folder**
1-2 **List of Duplicated SourceFiles**
So:
Next Step is to copy non-duplicated files and Added Duplication on Session:
public void Copy(string Source, string Destination)
{
/// Set Session ....
Session["Destination"] = Destination;
List<string> DuplicatedFiles = new List<string>();
string[] SourceFiles = System.IO.Directory.GetFiles(Source);
for (int i = 0; i < SourceFiles.Length; i++)
{
string DestinationFilePath = System.IO.Path.Combine(Destination, System.IO.Path.GetFileName(SourceFiles[i]));
if (System.IO.File.Exists(DestinationFilePath))
{
// Add into Duplication List
DuplicatedFiles.Add(SourceFiles[i]);
}
else
{
System.IO.File.Copy(SourceFiles[i], DestinationFilePath);
}
}
/// Set Session .....
Session["DouplicatedFiles"] = DuplicatedFiles;
}
above code is psudo and the goal is Clear.
Next Step is to show the result of copying or duplications:
I don'n know how do you want to implement such a view for duplication errors and it will not the part of the answer. anyway you may want to let the user to choose the action on each files separately or whole of them at the same time.
depend on your preferences you will have an ActionMethod (In MVC) or something else in WebForm that will do these things:
(If user doesn't want replace the files, it's easy to forget the action)
public void CopyDuplications(bool Overwrite)
{
if (!Overwrite)
return "OK";
else
{
string Destination = Session["Destination"] as string;
var DuplicatedFiles = Session["DouplicatedFiles"] as List<string>();
for (int i = 0; i< DuplicatedFiles.Count; i++)
{
string DestinationFilePath = System.IO.Path.Combine(Destination, System.IO.Path.GetFileName(DuplicatedFiles[i]));
System.IO.File.Copy(DuplicatedFiles[i], DestinationFilePath, true);
}
}
}
I have 10 txt files in Debug\Tests\Text\ (10 txt files). I need to write a program to open all 10 files and updated every single file. I'm not sure how to do it. Now, I'm actually reading the folder and getting the file name and storing the file name in an array. Below is my code:
private void getFilesName()
{
string[] fileArray = Directory.GetFiles(#"Tests\Text");
//looping through the folder and get the fileNames
for (int i = 0; i<fileArray.Length; i++)
{
MessageBox.Show(fileArray[i]); // I'm doing this is to double check i manage to get the file name.
}
}
After doing this, it do read all the text file name, but the challenge now is for me to access the filename and updating every file in it. I have also created another method just for updating the values in the txt files, below is the code:
private bool modifySQLFile()
{
string destFileName = #"Tests\Text\" // I need the fileName?
string[] fileTexts = File.ReadAllLines(destFileName);
int counter = 0;
//Processing the File
foreach(string line in fileTexts)
{
//only read those non-comments line
if(line.StartsWith("--") == false)
{
//Start to replace instances of Access ID
if(line.Contains(Variable) == true)
{
fileTexts[counter] = fileTexts[counter].Replace(Variable, textBox2.Text);
}
}
counter++;
}
//check if file exists in the backup folder
if(File.Exists("Tests\\Text\\file name "+ textBox1.Text +".sql") == true)
{
MessageBox.Show("This file already exist in the backup folder");
return false;
}
else
{
//update the file
File.WriteAllLines(destFileName, fileTexts);
File.Move(destFileName, "Tests\\Text\\file name"+ textBox1.Text +".sql");
MessageBox.Show("Completed");
return true;
}
}
Your problem seems to be passing the filename variable from the loop to the method.
In order to do what you want, add a parameter to the method:
private bool ModifySQLFile(string filename)
{
string[] fileTexts = File.ReadAllLines(filename);
// ...
}
Then call the method with this parameter:
for (int i = 0; i<fileArray.Length; i++)
{
ModifySQLFile(fileArray[i]);
}
But in general you really don't want to treat a formal language as plaintext like you do. It's very easy to break the SQL like that. What if the user wanted to replace the text "insert", or replaces something with "foo'bar"?
First, implement one (file) modification:
private bool modifySQLFile(String file) {
// given source file, let´s elaborate target file name
String targetFile = Path.Combine(
Path.GetDirectoryName(file),
String.Format("{0}{1}.sql",
Path.GetFileNameWithoutExtension(file),
textBox1.Text));
// In case you want a back up
//TODO: given source file name, elaborate back up file name
//String backUpFile = Path.Combine(...);
// Check (validate) before processing: do not override existing files
if (File.Exists(targetFile))
return false;
//TODO: what if back up file exists? Should we override it? skip?
// if line doesn't start with SQL commentary --
// and contains a variable, substitute the variable with its value
var target = File
.ReadLines(file)
.Select(line => (!line.StartsWith("--") && line.Contains(Variable))
? line.Replace(Variable, textBox2.Text)
: line);
// write modified above lines into file
File.WriteAllLines(targetFile, target);
// In case you want a back up
// Move file to backup
//File.Move(file, backUpFile);
return true;
}
Then call it in the loop:
// enumerate all the text files in the directory
var files = Directory
.EnumerateFiles("#"Tests\Text", "*.txt");
//TODO: you may want filter out some files with .Where
//.Where(file => ...);
// update all the files found above
foreach (var file in files) {
if (!modifySQLFile(file))
MessageBox.Show(String.Format("{0} already exist in the backup folder", file));
}
Please, do not do:
Use Magic values: what is #"Tests\Text\" within your modifySQLFile
Mix UI MessageBox.Show(...) and logic: modifySQLFile returns true or false and it's caller who can display message box.
Materialize when it's not required (Directory.GetFiles, File.ReadAllLines)
If you would like to edit the files in parallel. With threads you can parallelize work.
for (int i = 0; i < fileArray.Length; i++)
new Thread(UpdateFileThread).Start(fileArray[i]);
private void UpdateFileThread(object path)
{
string filePath = (string)path;
//ToDo: Edit file
}
In your case you would create 10 Threads. That solution works, but is a bad pattern if you have to deal with more than 10 files.
Below i have posted the real time code ,which i have used project
protected void btnSqlfinder_Click(object sender, EventArgs e)
{
//Defining the path of directory where all files saved
string filepath = # "D:\TPMS\App_Code\";
//get the all file names inside the directory
string[] files = Directory.GetFiles(filepath);
//loop through the files to search file one by one
for (int i = 0; i < files.Length; i++)
{
string sourcefilename = files[i];
StreamReader sr = File.OpenText(sourcefilename);
string sourceline = "";
int lineno = 0;
while ((sourceline = sr.ReadLine()) != null)
{
lineno++;
//defining the Keyword for search
if (sourceline.Contains("from"))
{
//append the result to multiline text box
TxtResult.Text += sourcefilename + lineno.ToString() + sourceline + System.Environment.NewLine;
}
if (sourceline.Contains("into"))
{
TxtResult.Text += sourcefilename + lineno.ToString() + sourceline + System.Environment.NewLine;
}
if (sourceline.Contains("set"))
{
TxtResult.Text += sourcefilename + lineno.ToString() + sourceline + System.Environment.NewLine;
}
if (sourceline.Contains("delete"))
{
TxtResult.Text += sourcefilename + lineno.ToString() + sourceline + System.Environment.NewLine;
}
}
}
}
This code will fetch the multiple files in the given directory,and show the lines as per the keyword in a separate text.
But you can easily change as per your requirement,Kindly let me know your thoughts.
Thanks
I'm making a button that reads a file path then deletes the files within the folder. It's currently deleting the entire directory. Here's my code:
public void deleteFiles(string Server)
{
string output = "\\\\" + Server + "\\F\\Output";
string input = "\\\\" + Server + "\\F\\Input";
string exceptions = "\\\\" + Server + "\\F\\Exceptions";
new System.IO.DirectoryInfo(input).Delete(true);
new System.IO.DirectoryInfo(output).Delete(true);
new System.IO.DirectoryInfo(exceptions).Delete(true);
}
Would just deleting the directory and recreating it work? Or do you want to preserve permissions?
You are calling Delete method on DirectoryInfo, you should call it on FileInfo's instead:
var files = new DirectoryInfo(input).GetFiles()
.Concat(new DirectoryInfo(output).GetFiles())
.Concat(new DirectoryInfo(exceptions).GetFiles());
foreach(var file in files)
file.Delete();
Another way:
var files = Directory.GetFiles(input)
.Concat(Directory.GetFiles(output))
.Concat(Directory.GetFiles(exceptions));
foreach(var file in files)
File.Delete(file);
DirectoryInfo.Delete and Directory.Delete delete empty directories, if you want to delete files you could try this method:
public void DeleteFiles(string path, bool recursive, string searchPattern = null)
{
var entries = searchPattern == null ? Directory.EnumerateFileSystemEntries(path) : Directory.EnumerateFileSystemEntries(path, searchPattern);
foreach(string entry in entries)
{
try
{
FileAttributes attr = File.GetAttributes(entry);
//detect whether its a directory or file
bool isDir = (attr & FileAttributes.Directory) == FileAttributes.Directory;
if(!isDir)
File.Delete(entry);
else if(recursive)
DeleteFiles(entry, true, searchPattern);
}
catch
{
//ignore
}
}
}