#c# #foreach
Вопрос:
У меня есть цикл foreach, который добавляет данные из 1 файла (источника) в другой (пункт назначения). Как только файл будет добавлен со всеми данными, я хочу переместить исходный исходный файл. При отладке я получаю сообщение об ошибке «Исключение: «System.IO.IOException» в System.IO.FileSystem.dll»
Я предполагаю, что это связано с тем, что файл заблокирован. Как я могу избавиться от этого, чтобы я мог переместить файл.
var stringwrite = new[] { prefix, prefix2 };
foreach (string line in File.ReadLines(currentFile))
{
var lastOne = line.Split(';').Last();
if (!stringwrite.Any(stringwrite => lastOne.Contains(stringwrite)))
continue;
//write lines found to new file
File.AppendAllText(todestination, line Environment.NewLine);
}
//move original file to new directory
try
{
File.Move(currentFile, completeddestination);
break;
}
catch (Exception ex)
{
MessageBox.Show("Issue Moving File");
}
Комментарии:
1. Скорее всего, он уже закрыт, так как
ReadLines()
файл закрывается автоматически, поэтому должна быть другая причина, проверьте, есть ли у вас разрешения на перемещение файла. Возможно, это «только для чтения», или приложение должно работать с повышенными разрешениями или sth2. Проверил все разрешения, и они верны. Бросая мне, как вы говорите, ReadLines() автоматически закрывает файл.
3. @PeterSmith что вы имеете в виду под «закрытием файла»?
4. @cragjungle каковы детали исключения? Один этот тип мало что говорит…
5. В частности, «Файл уже существует». Я проверил, что это не так
Ответ №1:
Поскольку вы читаете исходный файл до конца и записываете его в пункт назначения в зависимости от условий, было бы разумно сохранить как входные, так и выходные потоки открытыми до окончания операций чтения/записи. Обратите внимание, что File.ReadLines
откроется исходный файл, прочтите его содержимое, а затем закройте его. Кроме того, File.AppendAllText
откроется файл назначения, добавит содержимое, а затем закроет файл. Такой подход неэффективен. Я думаю, что ваша задача может быть правильно реализована с помощью файловых потоков. Пожалуйста, найдите пример ниже:
static void Main()
{
var sourcePath = "C:\PathToSource";
var destinationPath = "C:\PathToDestination";
var completedDestinationPath = "C:\PathToCompletedDestination";
var prefixes = new[] { "some-prefix", "some-other-prefix" };
foreach (var source in EnumerateDataFiles(sourcePath))
{
// This assumes that files in source and destination and completed
// dectination directories have the same file name but different paths.
// If you use another convention for your data, please adjust it here
var destination = GetDestinationFilePath(source, destinationPath);
var completedDestination = GetDestinationFilePath(source, completedDestinationPath);
try
{
AppendData(
source,
destination,
line =>
{
var lastEntry = line.Split(';').Last();
return prefixes.Any(prefix => lastEntry.Contains(prefix));
});
File.Move(source, completedDestination);
}
catch (Exception ex)
{
Console.WriteLine($"Issue Moving File: {ex.Message}");
}
}
}
static IEnumerable<string> EnumerateDataFiles(string path)
{
// Change *.dat to the extension (e.g., *.txt) you use for your data files,
// or to *.* to include all files from the directory
return Directory.EnumerateFiles(path, "*.dat", SearchOption.AllDirectories);
}
static string GetDestinationFilePath(string sourceFileName, string destinationPath)
{
// This will return a file path to the file with the same name as the source
// but located in the destination directory
return Path.Combine(destinationPath, Path.GetFileName(sourceFileName));
}
static void AppendData(string source, string destination, Func<string, bool> linePredicate)
{
using (var inputStream = new FileStream(source, FileMode.Open, FileAccess.Read))
using (var inputReader = new StreamReader(inputStream))
using (var outputStream = new FileStream(destination, FileMode.OpenOrCreate, FileAccess.Write))
using (var outputWriter = new StreamWriter(outputStream))
{
while (inputReader.ReadLine() is string inputLine)
{
if (!linePredicate(inputLine))
continue;
outputWriter.WriteLine(inputLine);
}
}
}
В приведенном примере я предположил, что у вас одно и то же имя файла, но разные пути к исходному, целевому и завершенному пути к целевому файлу. Если вы используете другой механизм именования, пожалуйста, следуйте комментариям, чтобы соответствующим образом его настроить.
Комментарии:
1. Хотя ваши замечания о производительности, конечно, верны, они, вероятно, не имеют ничего общего с возникшим исключением.
2. Конечно, дело не в исходном коде. Но с помощью кода, который я предоставил, проблема, скорее всего, должна быть решена