2011-01-20 2 views
3

У меня есть программа, которая должна загружать файлы из каталога, как только они будут записаны. Я получил FileSystemWatcher, чтобы уведомить меня об изменениях в каталоге. Вместо того, чтобы проверять событие на то, что изменилось, я просто перечисляю файлы и начинаю обрабатывать все, что я нашел.Чтение файла сразу после его написания Я получаю все нули (.net)

Чтобы предотвратить попытку прочитать файл, который до сих пор записываемый У меня есть код, как:

try { 
    fs = fi.Open(FileMode.Open, FileAccess.ReadWrite, 
        FileShare.None); 
    message = new byte[fs.Length]; 
    int br = fs.Read(message, 0, (int)fi.Length); 
} 
catch (Exception e) { 
    // I'll get it next time around 
    return; 
} 
finally { 
    if (fs != null) 
     fs.Close(); 
} 

Проблема заключается в том, что для некоторых файлов, около 1 в 200, программе чтения всех нулей. Длина файла верна, но содержание кажется равным нулю. Когда я проверяю последний файл, я нахожу, что он содержит фактические правильные данные. Я думал, что способ открытия файла будет препятствовать преждевременному доступу к файлу.

Я тестирую это путем копирования файлов в каталог с помощью команды DOS «копировать InFile_0 * dropdir» (около 100 файлов на выполнение). Возможно, эта команда выполняет копию в два этапа: 1) выделить место и 2) и моя программа иногда прыгает в середине двух.

Какие-либо идеи относительно того, как это сделать, чтобы быть надежным?

Обновление: У меня нет контроля над программой написания - это может быть что угодно. Похоже, я должен защищать код.

+1

Совет. Добавьте регистрацию для исключения. Не умолкайте. – Amy

+0

Вы работаете с программой, которая не помещает никаких блокировок в файл. Например, для программ на языке C, fopen() позволяет любой программе читать и писать, пока файл открыт.Не так много способов победить за «ожиданием». –

ответ

2

Вы попадаете в состояние гонки. Здесь будет только хуже (с сетевыми файловыми системами и т. Д.), Если вы не решите его окончательно.

Попробуйте написать программу, пишущую файлы, используя имя «whatever.tmp», затем закройте ее, а затем переименуйте. При чтении игнорируйте файлы .tmp.

Или сохраните файл нулевой длины с именем «sentinel» или некоторые из них в каталоге. Получить программу, записывающую файлы, чтобы переписать файл часового ПОСЛЕ каждой успешной записи другого файла. Затем не пытайтесь читать файлы, чья дата/время изменения> = дата/время изменения файла дозорного.

Или, если у вас нет контроля над писателем файлов, проверьте дату/время изменения каждого файла на текущую системную дату/время. Пусть файлы ставят соответствующую сумму (несколько секунд, если они маленькие, дольше, если они больше), прежде чем пытаться их прочитать.

Удачи. Это печально известная боль в шее.

1

Ну, я не согласен с предыдущим сообщением от @Ollie Jones.

Вы уже установили эксклюзивный доступ к файлу, поэтому проблем с расы нет.

Думаю, вам следует более внимательно изучить поведение писателя. И попытайтесь уменьшить помехи на доступ к файлам с только читать, делиться любой доступ:

fi.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 

Это может не ваше чтение, но уменьшит ошибку записи. Чтобы решить, когда читать безопасно, вы можете проверить время файла или размер файла или что-то еще. Если впоследствии будет записано много файлов, вы можете начать читать первый файл после создания второго файла.

+0

Я действительно открыл его FileAccess.Read и имел ту же проблему с нулевыми файлами. Открытие .ReadWrite было попыткой исправить это - я думал, что запрос на доступ к записи может задержать мой доступ к файлу, пока все авторы не будут с ним действительно выполнены. – TomU

+0

Я не вижу, как FileShare.ReadWrite решит проблему. Это более разрешительно, чем. Никто, и я не нуждаемся в меньшем разрешении. Кроме того, документы говорят «последующее открытие» - процесс, который приходит после меня. Я последовал за писателем, поэтому я хочу, чтобы писатель открылся с. Но у меня нет контроля над этим. Конечно, я мог бы неправильно интерпретировать документацию, или документация может быть неправильной. – TomU

Смежные вопросы