Это «вилка» из ответа @ Lother (который, я считаю, следует считать правильным ответом).
Для такого файла:
$ cat file.txt
1: october rust
2: november rain
3: december snow
вилка из решения Лоутера отлично работает:
#!/usr/bin/python3.4
with open("file.txt","r+") as f:
new_f = f.readlines()
f.seek(0)
for line in new_f:
if "snow" not in line:
f.write(line)
f.truncate()
Усовершенствования:
with open
, которые отбрасывают использование f.close()
if/else
для оценки того, нет ли строки в текущей строке System.IO.DirectoryInfo di = new DirectoryInfo("YourPath");
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in di.GetDirectories())
{
dir.Delete(true);
}
Если в вашем каталоге может быть много файлов, EnumerateFiles ()
более эффективен, чем GetFiles ()
, потому что при использовании EnumerateFiles ( )
вы можете начать его перечисление до того, как будет возвращена вся коллекция, в отличие от GetFiles ()
, где вам нужно загрузить всю коллекцию в память, прежде чем начинать ее перечисление. См. Эту цитату здесь :
Поэтому, когда вы работаете с большим количеством файлов и каталогов, EnumerateFiles () может быть более эффективным.
То же самое относится к EnumerateDirectories ()
и GetDirectories ()
. Таким образом, код будет выглядеть следующим образом:
foreach (FileInfo file in di.EnumerateFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in di.EnumerateDirectories())
{
dir.Delete(true);
}
В этом вопросе нет причин использовать GetFiles ()
и GetDirectories ()
.
using System.IO;
string[] filePaths = Directory.GetFiles(@"c:\MyDir\");
foreach (string filePath in filePaths)
File.Delete(filePath);
System.IO.Directory.Delete(installPath, true);
System.IO.Directory.CreateDirectory(installPath);
Самый простой способ:
Directory.Delete(path,true);
Directory.CreateDirectory(path);
Имейте в виду, что это может уничтожить некоторые разрешения для папки.
Каждый метод, который я пробовал, в какой-то момент заканчивался ошибкой System.IO. Следующий метод работает наверняка, даже если папка пуста или нет, доступна только для чтения или нет и т. Д.
ProcessStartInfo Info = new ProcessStartInfo();
Info.Arguments = "/C rd /s /q \"C:\\MyFolder"";
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = "cmd.exe";
Process.Start(Info);
new System.IO.DirectoryInfo(@"C:\Temp").Delete(true);
//Or
System.IO.Directory.Delete(@"C:\Temp", true);
Да, это правильный способ сделать это. Если вы хотите дать себе «Очистить» (или, как я бы предпочел называть это, «Пустую» функцию), вы можете создать метод расширения.
public static void Empty(this System.IO.DirectoryInfo directory)
{
foreach(System.IO.FileInfo file in directory.GetFiles()) file.Delete();
foreach(System.IO.DirectoryInfo subDirectory in directory.GetDirectories()) subDirectory.Delete(true);
}
Это позволит вам сделать что-то вроде. .
System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(@"C:\...");
directory.Empty();
Следующий код рекурсивно очищает папку:
private void clearFolder(string FolderName)
{
DirectoryInfo dir = new DirectoryInfo(FolderName);
foreach(FileInfo fi in dir.GetFiles())
{
fi.Delete();
}
foreach (DirectoryInfo di in dir.GetDirectories())
{
clearFolder(di.FullName);
di.Delete();
}
}
private void ClearFolder(string FolderName)
{
DirectoryInfo dir = new DirectoryInfo(FolderName);
foreach(FileInfo fi in dir.GetFiles())
{
try
{
fi.Delete();
}
catch(Exception) { } // Ignore all exceptions
}
foreach(DirectoryInfo di in dir.GetDirectories())
{
ClearFolder(di.FullName);
try
{
di.Delete();
}
catch(Exception) { } // Ignore all exceptions
}
}
Если вы знаете, что нет подпапок, проще всего будет что-то вроде этого:
Directory.GetFiles(folderName).ForEach(File.Delete)
Мы также можем проявить любовь к LINQ :
using System.IO;
using System.Linq;
…
var directory = Directory.GetParent(TestContext.TestDir);
directory.EnumerateFiles()
.ToList().ForEach(f => f.Delete());
directory.EnumerateDirectories()
.ToList().ForEach(d => d.Delete(true));
Обратите внимание, что мое решение здесь неэффективно, потому что я использую Get * (). ToList (). ForEach (... )
, который дважды генерирует один и тот же IEnumerable
. Я использую метод расширения, чтобы избежать этой проблемы:
using System.IO;
using System.Linq;
…
var directory = Directory.GetParent(TestContext.TestDir);
directory.EnumerateFiles()
.ForEachInEnumerable(f => f.Delete());
directory.EnumerateDirectories()
.ForEachInEnumerable(d => d.Delete(true));
Это метод расширения:
/// <summary>
/// Extensions for <see cref="System.Collections.Generic.IEnumerable"/>.
/// </summary>
public static class IEnumerableOfTExtensions
{
/// <summary>
/// Performs the <see cref="System.Action"/>
/// on each item in the enumerable object.
/// </summary>
/// <typeparam name="TEnumerable">The type of the enumerable.</typeparam>
/// <param name="enumerable">The enumerable.</param>
/// <param name="action">The action.</param>
/// <remarks>
/// “I am philosophically opposed to providing such a method, for two reasons.
/// …The first reason is that doing so violates the functional programming principles
/// that all the other sequence operators are based upon. Clearly the sole purpose of a call
/// to this method is to cause side effects.”
/// —Eric Lippert, “foreach” vs “ForEach” [http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx]
/// </remarks>
public static void ForEachInEnumerable<TEnumerable>(this IEnumerable<TEnumerable> enumerable, Action<TEnumerable> action)
{
foreach (var item in enumerable)
{
action(item);
}
}
}