Good day!
I'm trying to create a C # Forms app where user chooses directories with FolderDialog and paths are saved in list.txt file after read by textBox1.
In list.txt user can add and delete path.
code snippet:
private void Form1_Load(object sender, EventArgs e)
{
textBox1.Lines = System.IO.File.ReadAllLines(fileName);
}
string fileName = Environment.CurrentDirectory + #"/etc/list.txt";
private void LoadTextboxes()
{
string[] loadedLines = System.IO.File.ReadAllLines(Environment.CurrentDirectory + #"/etc/list.txt");
int index = 0;
int n = int.Parse(loadedLines[index]);
string[] lines = new string[n];
Array.Copy(loadedLines, index + 1, lines, 0, n);
textBox1.Lines = lines;
}
private void DeleteFilesFromDirectory(string directoryPath)
{
DirectoryInfo d = new DirectoryInfo(directoryPath);
foreach (FileInfo fi in d.GetFiles())
{
fi.Delete();
}
foreach (DirectoryInfo di in d.GetDirectories())
{
DeleteFilesFromDirectory(di.FullName);
di.Delete();
}
}
private void button1_Del(object sender, EventArgs e)
{
DeleteFilesFromDirectory(textBox1.Text);
}
list.txt format:
C:/downloads
F:/doc/scan
D:/etc
t is important to delete only the sub folders and files but root folders must remain.
So far I have been done with my weak knowledge of c# and and now I'm stuck for a long time.
DeleteFilesFromDirectory only deletes the first line of textBox1.
How to make DeleteFilesFromDirectory read and delete all lines from textBox1?
Check this I tested it.
//put all paths in array reading line by line
string[] paths = System.IO.File.ReadAllLines(#"path-to\list.txt");
//get line by line paths
foreach (string path in paths)
{
if (Directory.Exists(path))
{
//deletes all files and parent
//recursive:true, deletes subfolders and files
Directory.Delete(path, true);
//create parent folder
Directory.CreateDirectory(path);
}
}//end outer for
Related
Below is my code where I am successfully renaming only the files inside a a folder and also crawls inside every subfolders and renames the entire .png files.
I am trying to add a customization where if the file name already got #1 or #5 or any #(number) then i want the conversation to skip that file and go to next file
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog folderDlg = new FolderBrowserDialog();
//folderDlg.ShowDialog();
if (folderDlg.ShowDialog() != DialogResult.OK)
{
return;
}
// Has different framework dependend implementations
// in order to handle unauthorized access to subfolders
RenameAllPngFiles(folderDlg.SelectedPath);
}
private void RenameAllPngFiles(string directoryPath)
{
RenameCurrentPng(directoryPath);
foreach (var item in GetDirectoryInfos(directoryPath))
{
RenameCurrentPng(item.FullName);
}
}
private void RenameCurrentPng(string directoryPath)
{
int fileNameSuffixCounter = 1;
foreach (string originalFullFileName in Directory.EnumerateFiles(directoryPath, "*.png"))
{
// The new file name without path
var newFileName = $"{System.IO.Path.GetFileNameWithoutExtension(originalFullFileName)}#{fileNameSuffixCounter++}{System.IO.Path.GetExtension(originalFullFileName)}";
FileSystem.RenameFile(originalFullFileName, newFileName);
}
}
private DirectoryInfo[] GetDirectoryInfos(string directoryPath)
{
DirectoryInfo di = new DirectoryInfo(directoryPath);
DirectoryInfo[] directories = di.GetDirectories("*", System.IO.SearchOption.AllDirectories);
return directories;
}
Just use the String.Contains method to check for #.
private void RenameCurrentPng(string directoryPath)
{
int fileNameSuffixCounter = 1;
foreach (string originalFullFileName in Directory.EnumerateFiles(directoryPath, "*.png"))
{
string ShortFileName = System.IO.Path.GetFileNameWithoutExtension(originalFullFileName);
if (!ShortFileName.Contains("#"))
{
// The new file name without path
var newFileName = $"{ShortFileName}#{fileNameSuffixCounter++}{System.IO.Path.GetExtension(originalFullFileName)}";
FileSystem.RenameFile(originalFullFileName, newFileName);
}
}
}
I am new to programming, currently trying to get all the file sizes from the file array and display next to them. I found the solution which is FileInfo, but have no idea how it works and couldn't find any solution online. The file array retrieved and display successfully before I added the FileInfo line.
private void Button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog FBD = new FolderBrowserDialog();
if (FBD.ShowDialog()==DialogResult.OK)
{
listBox1.Items.Clear();
string[] files = Directory.GetFiles(FBD.SelectedPath);
string[] dirs = Directory.GetDirectories(FBD.SelectedPath);
foreach (string file in files)
{
long length = new FileInfo(FBD.SelectedPath).Length; //FileNotFoundException
listBox1.Items.Add(Path.GetFileName(file + length));
}
foreach (string dir in dirs)
{
listBox1.Items.Add(Path.GetFileName(dir));
}
}
}
I have a button which can open the folder dialog and user are able to select the directory, and a listbox to display all the file/directory from the selected path. Can I actually get all the files sizes along the path and display next to the files/ directory?
Not with Directory.GetFiles you can't - it returns an array of strings that are filepaths. You'd have to make a new FileInfo from each one and get its length.. It'd be better to call the method of DirectoryInfo that returns you an array of FileInfo to start with:
private void Button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog FBD = new FolderBrowserDialog();
if (FBD.ShowDialog()==DialogResult.OK)
{
listBox1.Items.Clear();
FileInfo[] files = new DirectoryInfo(FBD.SelectedPath).GetFiles();
string[] dirs = Directory.GetDirectories(FBD.SelectedPath);
foreach (FileInfo file in files)
{
listBox1.Items.Add(file.Name + "(" + file.Length + " bytes)");
}
foreach (string dir in dirs)
{
listBox1.Items.Add(Path.GetFileName(dir));
}
}
}
I'm not really sure what you mean by "Can I actually get all the files sizes along the path and display next to the .. directory"
Directories don't have a file size; did you mean that you want the sum total of all the files' sizes inside the directory? For all subdirectories in the hierarchy or the top directory only? Perhaps something like this:
private void Button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog FBD = new FolderBrowserDialog();
if (FBD.ShowDialog()==DialogResult.OK)
{
listBox1.Items.Clear();
FileInfo[] files = new DirectoryInfo(FBD.SelectedPath).GetFiles();
DirectoryInfo[] dirs = new DirectoryInfo(FBD.SelectedPath).GetDirectories();
foreach (FileInfo file in files)
{
listBox1.Items.Add(file.Name + "(" + file.Length + " bytes)");
}
foreach (DirectoryInfo dir in dirs)
{
listBox1.Items.Add(dir.Name + "(" + dir.GetFiles().Sum(f => f.Length) + " bytes)");
}
}
}
For Sum to work you'll have to have imported System.Linq
Incidentally, I present the following as a commentary on why your code didn't work:
private void Button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog FBD = new FolderBrowserDialog();
if (FBD.ShowDialog()==DialogResult.OK)
{
listBox1.Items.Clear();
string[] files = Directory.GetFiles(FBD.SelectedPath);
string[] dirs = Directory.GetDirectories(FBD.SelectedPath);
foreach (string file in files) //ok, so file is the filepath
{
//it doesn't work because you put "FBD.SelectedPath" in instead of "file"
// FBD.SelectedPath is a directory, not a file, hence the FileNotFoundException
//But the real problem is probably a cut n paste error here
long length = new FileInfo(FBD.SelectedPath).Length;
//it would work out but it's a weird way to do it, adding the length on before you strip the filename out
//Path doesnt do anything complex, it just drops all the text before the
//last occurrence of /, but doing Path.GetFilename(file) + length would be better
listBox1.Items.Add(Path.GetFileName(file + length));
}
foreach (string dir in dirs)
{
//need to be careful here: "C:\temp\" is a path of a directory but calling GetFilename on it would return "", not temp
listBox1.Items.Add(Path.GetFileName(dir));
}
}
}
You almost had it right, try the following:
private void Button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog folderBrowser = new FolderBrowserDialog();
if (folderBrowser.ShowDialog() == DialogResult.OK)
{
listBox1.Items.Clear();
string[] files = Directory.GetFiles(folderBrowser.SelectedPath);
foreach (string file in files)
{
var fileInfo = new FileInfo(file);
listBox1.Items.Add($"{Path.GetFileName(file)} {fileInfo.Length} bytes.");
}
}
}
Hey guys so I'm working on a small program which sorta speeds up your pc, but I have a problem I get an exception if I try to delete files, I believe cause they are in use. Though it deletes some, but not much. My question is how to delete files in use, and how to delete sub folders inside the folder
//this is my directory:
DirectoryInfo tempPath = new DirectoryInfo(#"C:\Users\" + Environment.UserName + #"\AppData\Local\Temp");
private void button8_Click(object sender, EventArgs e)
{
if (checkBox5.Checked)
{
//loop through these files
foreach (FileInfo file in tempPath.GetFiles())
{
//delete files in content
file.Delete();
}
}
}
You must delete Folder recursivly with set FileAttributes normal.
private static void DeleteAllFolderRecursive(DirectoryInfo yourBaseDir)
{
baseDir.Attributes = FileAttributes.Normal;
foreach (var childDir in baseDir.GetDirectories())
DeleteFolderRecursive(childDir);
foreach (var file in baseDir.GetFiles())
file.IsReadOnly = false;
baseDir.Delete(true);
}
And you call this :
DirectoryInfo tempPath = new DirectoryInfo(#"C:\Users\" + Environment.UserName + #"\AppData\Local\Temp");
DeleteAllFolderRecursive(tempPath);
I am currently working on my own MP3 player and want to add drag & drop functionality to be able to drag & drop your music either a file at a time or a whole directory at a time. I have the View of my ListView set to details, and am using the following code:
void Playlist_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
}
void Playlist_DragDrop(object sender, DragEventArgs e)
{
Playlist.Items.Clear();
string[] songs = (string[])e.Data.GetData(DataFormats.FileDrop, false);
Parallel.ForEach(songs, s =>
{
if (File.Exists(s))
{
if (string.Compare(Path.GetExtension(s), ".mp3", true) == 0)
{
MessageBox.Show(s);
AddFileToListview(s);
}
}
else if (Directory.Exists(s))
{
DirectoryInfo di = new DirectoryInfo(s);
FileInfo[] files = di.GetFiles("*.mp3");
foreach (FileInfo file in files)
{
AddFileToListview(file.FullName);
MessageBox.Show(file.FullName);
}
}
});
}
private void AddFileToListview(string fullFilePath)
{
if (!File.Exists(fullFilePath))
return;
string song = Path.GetFileName(fullFilePath);
string directory = Path.GetDirectoryName(fullFilePath);
if (directory.EndsWith(Convert.ToString(Path.DirectorySeparatorChar)))
directory = directory.Substring(0, directory.Length - 1); //hack off the trailing \
ListViewItem itm = Playlist.Items.Add(song);
itm.SubItems.Add(directory); //second column = path
}
I have the MessageBox in there to make sure my code is being hit and tit always shows me the right data but nothing shows in the ListView. Any ideas what I'm doing wrong?
#ClearLogic: You were right I forgot to define columns in the ListView, thanks. Now I have another problem, I can drag multiple directories into the ListView with no problems, but when I try to add multiple single MP3's I get a cross-thread exception on the line
ListViewItem itm = Playlist.Items.Add(song);
Thanks to #ClearLogic for all their help in solving this issue, I thought I'd share my code in case someone else is having some issues as well.
private void Playlist_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
}
private void Playlist_DragDrop(object sender, DragEventArgs e)
{
//get the file names
string[] songs = (string[])e.Data.GetData(DataFormats.FileDrop, false);
//we're using a Parallel.ForEach loop because if a directory is selected it can contain n number of items, this is to help prevent a bottleneck.
Parallel.ForEach(songs, song =>
{
//make sure the file exists
if (File.Exists(song))
{
//if it's an mp3 file then call AddFileToListview
if (string.Compare(Path.GetExtension(song), ".mp3", true) == 0)
{
AddFileToListview(song);
}
}
//A HA! It's a directory not a single file
else if (Directory.Exists(song))
{
//get the directory information
DirectoryInfo di = new DirectoryInfo(song);
//get all the mp3 files (will add WMA in the future)
FileInfo[] files = di.GetFiles("*.mp3");
//here we use a parallel loop to loop through every mp3 in the
//directory provided
Parallel.ForEach(files, file =>
{
AddFileToListview(file.FullName);
});
}
});
}
private void AddFileToListview(string fullFilePath)
{
double nanoseconds;
string totalTime = string.Empty;
//First things first, does the file even exist, if not then exit
if (!File.Exists(fullFilePath))
return;
//get the song name
string song = Path.GetFileName(fullFilePath);
//get the directory
string directory = Path.GetDirectoryName(fullFilePath);
//hack off the trailing \
if (directory.EndsWith(Convert.ToString(Path.DirectorySeparatorChar)))
directory = directory.Substring(0, directory.Length - 1);
//now we use the WindowsAPICodePack.Shell to start calculating the songs time
ShellFile shell = ShellFile.FromFilePath(fullFilePath);
//get the length is nanoseconds
double.TryParse(shell.Properties.System.Media.Duration.Value.ToString(), out nanoseconds);
//first make sure we have a value greater than zero
if (nanoseconds > 0)
{
// double milliseconds = nanoseconds * 0.000001;
TimeSpan time = TimeSpan.FromSeconds(Utilities.ConvertToMilliseconds(nanoseconds) / 1000);
totalTime = time.ToString(#"m\:ss");
}
//build oour song data
ListViewItem item = new ListViewItem();
item.Text = song;
item.SubItems.Add(totalTime);
//now my first run at this gave me a cross-thread exception when trying to add multiple single mp3's
//but I could add all the whole directories I wanted, o that is why we are now using BeginINvoke to access the ListView
if (Playlist.InvokeRequired)
Playlist.BeginInvoke(new MethodInvoker(() => Playlist.Items.Add(item)));
else
Playlist.Items.Add(item);
}
This code uses the WindowsAPICodePack to calculate the time of each song.
I need your help.
The thing is that my code works, it reads all the files in a folder which are 96 text files and saves the path of each file.
I then take each file and change the line number 32 in the text file which is
"Treatment";"1"; nr = 1,2,3,4,5,...,96.
My program will takes this string and replaces it with a different one, I change the first file for example to "Treatment";"100"; then the last file should be "Treatment";"196";
So to solve this i change the whole line with a new one. But when i write the number to the string first file is right when i start from 1, but files 2-10 are. 12,23,34,45,56,67,78,89, then it starts 2,3,4,5,6,7 from the 11-th file.
Why is this? My code is below.
I tried saving the integer as a string because I though i was somehow accesing a ASCII table. But that works the same, so my code is below any ideas?
private void button1_Click(object sender, EventArgs e)
{
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
int start = 1;
string strengur = "\";";
string myString = start.ToString();
string[] filePaths = Directory.GetFiles(folderBrowserDialog1.SelectedPath);
//foreach (var file in Directory.EnumerateFiles(folderBrowserDialog1.SelectedPath))
for(int i = 0; i < 96 ; i++){
var lines = File.ReadAllLines(filePaths[i]);
lines[31] = "\"Treatment!!\";\"" +myString +strengur;
File.WriteAllLines(filePaths[i], lines);
start += 1;
myString = start.ToString();
}
}
}
Best Regards
Sæþór Ólafur Pétursson
Display all these files in windows explorer, sort by name, and then you will see why.
To solve it, you can set your start based on each file's line31's current number, and add by 100. E.g.:
private void button1_Click(object sender, EventArgs e)
{
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
string strengur = "\";";
string[] filePaths = Directory.GetFiles(folderBrowserDialog1.SelectedPath);
foreach(var file in filePaths)
{
var lines = File.ReadAllLines(file);
int currentstart = int.Parse(lines[31].Split(';')[1].Trim('\"'));
lines[31] = "\"Treatment!!\";\"" + (currentstart+100).ToString() + strengur;
File.WriteAllLines(file, lines);
}
}
}
Edit based on your comment:
private void button1_Click(object sender, EventArgs e)
{
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
int start = 100; //set this to your user's input
string strengur = "\";";
string[] filePaths = Directory.GetFiles(folderBrowserDialog1.SelectedPath);
foreach(var file in filePaths)
{
var lines = File.ReadAllLines(file);
int currentstart = int.Parse(lines[31].Split(';')[1].Trim('\"'));
lines[31] = "\"Treatment!!\";\"" + (currentstart+start-1).ToString() + strengur;
File.WriteAllLines(file, lines);
}
}
}