.NET Framework
System.IO.File klass
Sök…
Syntax
- strängkälla;
- strängdestination;
parametrar
Parameter | detaljer |
---|---|
source | Filen som ska flyttas till en annan plats. |
destination | Katalogen som du vill flytta source till (denna variabel bör också innehålla filnamnet (och filändelsen)). |
Radera en fil
Att ta bort en fil (om du har behörigheter) är så enkelt som:
File.Delete(path);
Men många saker kan gå fel:
- Du har inte nödvändiga behörigheter (
UnauthorizedAccessException
kastas). - Filen kan användas av någon annan (
IOException
kastas). - Filen kan inte raderas på grund av fel på låg nivå eller media är skrivskyddat (
IOException
kastas). - Filen finns inte längre (
IOException
kastas).
Observera att sista punkt (fil finns inte) vanligtvis kringgås med ett kodavsnitt som detta:
if (File.Exists(path))
File.Delete(path);
Men det är inte en atomoperation och filen kan raderas av någon annan mellan samtalet till File.Exists()
och före File.Delete()
. Rätt tillvägagångssätt för att hantera I / O-drift kräver undantagshantering (förutsatt att en alternativ åtgärd kan vidtas när operationen misslyckas):
if (File.Exists(path))
{
try
{
File.Delete(path);
}
catch (IOException exception)
{
if (!File.Exists(path))
return; // Someone else deleted this file
// Something went wrong...
}
catch (UnauthorizedAccessException exception)
{
// I do not have required permissions
}
}
Observera att detta I / O-fel ibland är övergående (till exempel fil som används) och om en nätverksanslutning är inblandad kan det automatiskt återhämta sig utan några åtgärder från vår sida. Det är då vanligt att försöka igen en I / O-operation några gånger med en liten fördröjning mellan varje försök:
public static void Delete(string path)
{
if (!File.Exists(path))
return;
for (int i=1; ; ++i)
{
try
{
File.Delete(path);
return;
}
catch (IOException e)
{
if (!File.Exists(path))
return;
if (i == NumberOfAttempts)
throw;
Thread.Sleep(DelayBetweenEachAttempt);
}
// You may handle UnauthorizedAccessException but this issue
// will probably won't be fixed in few seconds...
}
}
private const int NumberOfAttempts = 3;
private const int DelayBetweenEachAttempt = 1000; // ms
Obs: i Windows-miljöfilen raderas inte riktigt när du kallar den här funktionen, om någon annan öppnar filen med FileShare.Delete
kan filen raderas men den kommer faktiskt bara att ske när ägaren stänger filen.
Remsa oönskade rader från en textfil
Att ändra en textfil är inte lätt eftersom dess innehåll måste flyttas runt. För små filer är den enklaste metoden att läsa innehållet i minnet och sedan skriva tillbaka modifierad text.
I det här exemplet läser vi alla rader från en fil och släpper alla tomma rader och sedan skriver vi tillbaka till den ursprungliga sökvägen:
File.WriteAllLines(path,
File.ReadAllLines(path).Where(x => !String.IsNullOrWhiteSpace(x)));
Om filen är för stor för att ladda den i minnet och utmatningsvägen skiljer sig från inmatningsvägen:
File.WriteAllLines(outputPath,
File.ReadLines(inputPath).Where(x => !String.IsNullOrWhiteSpace(x)));
Konvertera textfilkodning
Text sparas kodad (se även Strängar ämne) då ibland kan du behöva ändra dess kodning, detta exempel antar (för enkelhetens skull) att filen inte är för stor och den kan läsas helt i minnet:
public static void ConvertEncoding(string path, Encoding from, Encoding to)
{
File.WriteAllText(path, File.ReadAllText(path, from), to);
}
När du utför konverteringar, glöm inte att filen kan innehålla BOM (Byte Order Mark), för att bättre förstå hur den hanteras hänvisar du till Encoding.UTF8.GetString tar inte hänsyn till Preamble / BOM .
"Tryck" på en stor mängd filer (för att uppdatera senaste skrivtiden)
Detta exempel uppdaterar den senaste skrivtiden för ett stort antal filer (med System.IO.Directory.EnumerateFiles
istället för System.IO.Directory.GetFiles()
). Valfritt kan du ange ett sökmönster (standard är "*.*"
Och så småningom söka igenom ett katalogträd (inte bara den angivna katalogen):
public static void Touch(string path,
string searchPattern = "*.*",
SearchOptions options = SearchOptions.None)
{
var now = DateTime.Now;
foreach (var filePath in Directory.EnumerateFiles(path, searchPattern, options))
{
File.SetLastWriteTime(filePath, now);
}
}
Räkna upp filer som är äldre än ett angivet belopp
Detta utdrag är en hjälpfunktion för att räkna upp alla filer som är äldre än en viss ålder, det är användbart - till exempel - när du måste ta bort gamla loggfiler eller gamla cachade data.
static IEnumerable<string> EnumerateAllFilesOlderThan(
TimeSpan maximumAge,
string path,
string searchPattern = "*.*",
SearchOption options = SearchOption.TopDirectoryOnly)
{
DateTime oldestWriteTime = DateTime.Now - maximumAge;
return Directory.EnumerateFiles(path, searchPattern, options)
.Where(x => Directory.GetLastWriteTime(x) < oldestWriteTime);
}
Används så här:
var oldFiles = EnumerateAllFilesOlderThan(TimeSpan.FromDays(7), @"c:\log", "*.log");
Få saker att notera:
- Sökning utförs med
Directory.EnumerateFiles()
istället förDirectory.GetFiles()
. Uppräkningen är i live, då behöver du inte vänta tills alla filsystemposter har hämtats. - Vi letar efter senaste skrivtid men du kan använda skapelsetid eller senaste åtkomsttid (till exempel för att ta bort oanvända cachade filer, observera att åtkomsttiden kan vara inaktiverad).
- Granulariteten är inte enhetlig för alla dessa egenskaper (skrivtid, åtkomsttid, skapelsestid), kolla MSDN för mer information om detta.
Flytta en fil från en plats till en annan
File.Move
För att flytta en fil från en plats till en annan kan en enkel kodrad uppnå detta: File.Move(@"C:\TemporaryFile.txt", @"C:\TemporaryFiles\TemporaryFile.txt");
Det finns dock många saker som kan gå fel med den här enkla åtgärden. Till exempel, vad händer om användaren som kör ditt program inte har en enhet som är märkt "C"? Tänk om de gjorde det - men de bestämde sig för att byta namn på det till 'B' eller 'M'?
Vad händer om källfilen (filen som du vill flytta i) har flyttats utan att du vet - eller om det helt enkelt inte finns.
Detta kan kringgås genom att först kontrollera om källfilen finns:
string source = @"C:\TemporaryFile.txt", destination = @"C:\TemporaryFiles\TemporaryFile.txt";
if(File.Exists("C:\TemporaryFile.txt"))
{
File.Move(source, destination);
}
Detta kommer att säkerställa att filen just nu existerar och kan flyttas till en annan plats. Det kan finnas tillfällen då ett enkelt samtal till File.Exists
inte räcker. Om det inte är det, kontrollera igen, meddela användaren att åtgärden misslyckades - eller hantera undantaget.
En FileNotFoundException
är inte det enda undantag du troligtvis kommer att stöta på.
Se nedan för möjliga undantag:
Undantagstyp | Beskrivning |
---|---|
IOException | Filen finns redan eller källfilen kunde inte hittas. |
ArgumentNullException | Värdet på käll- och / eller destinationparametrarna är noll. |
ArgumentException | Värdet på käll- och / eller destinationparametrarna är tomma eller innehåller ogiltiga tecken. |
UnauthorizedAccessException | Du har inte de behörigheter som krävs för att utföra denna åtgärd. |
PathTooLongException | Källan, destinationen eller de angivna banorna överskrider den maximala längden. I Windows måste en sökvägs längd vara mindre än 248 tecken, medan filnamnen måste vara mindre än 260 tecken. |
DirectoryNotFoundException | Den angivna katalogen kunde inte hittas. |
NotSupportedException | Käll- eller destinationsvägarna eller filnamnen är i ogiltigt format. |