.NET Framework
Класс System.IO.File
Поиск…
Синтаксис
- источник строки;
- назначение строки;
параметры
параметр | подробности |
---|---|
source | Файл, который нужно переместить в другое место. |
destination | Каталог, в который вы хотите переместить source (эта переменная также должна содержать имя (и расширение файла) файла. |
Удалить файл
Чтобы удалить файл (если у вас есть необходимые разрешения), просто:
File.Delete(path);
Однако многие вещи могут пойти не так:
- У вас нет необходимых разрешений (вызывается
UnauthorizedAccessException
). - Файл может быть использован кем-то другим (вызывается
IOException
). - Файл не может быть удален из-за ошибки низкого уровня или носитель доступен только для чтения (
IOException
). - Файл больше не существует (вызывается
IOException
).
Обратите внимание, что последняя точка (файл не существует) обычно обходит фрагмент кода следующим образом:
if (File.Exists(path))
File.Delete(path);
Однако это не атомная операция, и файл может быть File.Exists()
кем-то другим между вызовом File.Exists()
и перед File.Delete()
. Правильный подход к обработке операций ввода-вывода требует обработки исключений (при условии, что при выполнении операции может быть предпринят альтернативный курс действий):
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
}
}
Обратите внимание, что эти ошибки ввода-вывода иногда являются временными (например, файл используется), и если задействовано сетевое подключение, оно может автоматически восстанавливаться без каких-либо действий с нашей стороны. Затем обычно повторяется операция ввода-вывода несколько раз с небольшой задержкой между каждой попыткой:
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
Примечание: в среде Windows файл не будет действительно удален при вызове этой функции, если кто-то еще откроет файл с помощью FileShare.Delete
тогда файл можно удалить, но это будет эффективно, только когда владелец закроет файл.
Снимайте ненужные строки из текстового файла
Изменить текстовый файл непросто, потому что его содержимое нужно перемещать. Для небольших файлов самым простым способом является чтение его содержимого в памяти, а затем запись измененного текста.
В этом примере мы читаем все строки из файла и удаляем все пустые строки, а затем возвращаем исходный путь:
File.WriteAllLines(path,
File.ReadAllLines(path).Where(x => !String.IsNullOrWhiteSpace(x)));
Если файл слишком велик, чтобы загрузить его в память, и путь вывода отличается от пути ввода:
File.WriteAllLines(outputPath,
File.ReadLines(inputPath).Where(x => !String.IsNullOrWhiteSpace(x)));
Преобразование кодировки текстовых файлов
Текст сохраняется в кодировке (см. Также раздел «Строки» ), и иногда вам может понадобиться изменить его кодировку, этот пример предполагает (для простоты), что файл не слишком велик, и его можно полностью прочитать в памяти:
public static void ConvertEncoding(string path, Encoding from, Encoding to)
{
File.WriteAllText(path, File.ReadAllText(path, from), to);
}
При выполнении преобразований не забывайте, что файл может содержать спецификацию (знак байтового заказа), чтобы лучше понять, как он управляется, ссылаясь на Encoding.UTF8.GetString не принимает во внимание преамбулу / спецификацию .
«Коснитесь» большого количества файлов (чтобы обновить последнее время записи)
Этот пример обновляет последнее время записи огромного количества файлов (используя System.IO.Directory.EnumerateFiles
вместо System.IO.Directory.GetFiles()
). При желании вы можете указать шаблон поиска (по умолчанию это "*.*"
И, в конечном итоге, искать через дерево каталогов (не только указанный каталог):
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);
}
}
Перечислить файлы старше указанной суммы
Этот фрагмент является вспомогательной функцией для перечисления всех файлов старше указанного возраста, это полезно - например, когда вам приходится удалять старые файлы журналов или старые кешированные данные.
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);
}
Используется следующим образом:
var oldFiles = EnumerateAllFilesOlderThan(TimeSpan.FromDays(7), @"c:\log", "*.log");
Мало что нужно отметить:
- Поиск выполняется с использованием
Directory.EnumerateFiles()
вместоDirectory.GetFiles()
. Перечисление живое, тогда вам не нужно ждать, пока все записи в файловой системе не будут извлечены. - Мы проверяем последнее время записи, но вы можете использовать время создания или время последнего доступа (например, для удаления неиспользуемых кешированных файлов, обратите внимание, что время доступа может быть отключено).
- Гранулярность не является однородной для всех этих свойств (время записи, время доступа, время создания), проверьте MSDN, чтобы узнать подробности об этом.
Перемещение файла из одного места в другое
File.Move
Чтобы переместить файл из одного места в другое, одна простая строка кода может это сделать: File.Move(@"C:\TemporaryFile.txt", @"C:\TemporaryFiles\TemporaryFile.txt");
Тем не менее, есть много вещей, которые могут пойти не так с этой простой операцией. Например, что, если у пользователя, запускающего вашу программу, нет Диска с меткой «C»? Что делать, если они это сделали, но решили переименовать его в «B» или «M»?
Что делать, если исходный файл (файл, в который вы хотите переместить) был перемещен без вашего ведома - или что, если он просто не существует.
Это можно обойти, предварительно проверив, существует ли исходный файл:
string source = @"C:\TemporaryFile.txt", destination = @"C:\TemporaryFiles\TemporaryFile.txt";
if(File.Exists("C:\TemporaryFile.txt"))
{
File.Move(source, destination);
}
Это гарантирует, что в этот момент файл действительно существует и может быть перемещен в другое место. Бывают случаи, когда простого вызова File.Exists
будет недостаточно. Если это не так, проверьте еще раз, передайте пользователю, что операция завершилась неудачно - или обработайте исключение.
Исключение FileNotFoundException
- это не единственное исключение, с которым вы, вероятно, столкнетесь.
Ниже приведены возможные исключения:
Тип исключения | Описание |
---|---|
IOException | Файл уже существует или исходный файл не найден. |
ArgumentNullException | Значение параметров Source и / или Destination равно null. |
ArgumentException | Значение параметров Source и / или Destination пусто или содержит недопустимые символы. |
UnauthorizedAccessException | У вас нет необходимых разрешений для выполнения этого действия. |
PathTooLongException | Исходный, целевой или заданный путь (ы) превышают максимальную длину. В Windows длина пути должна быть меньше 248 символов, а имена файлов должны быть менее 260 символов. |
DirectoryNotFoundException | Указанный каталог не найден. |
NotSupportedException | Пути источника или назначения или имена файлов находятся в недопустимом формате. |