Как мне распечатать содержимое файлов в каталоге, но игнорировать файлы, которые открываются в режиме записи? - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть программа, которая периодически проверяет наличие новых файлов в каталоге, а затем печатает содержимое файлов.Однако есть другая процедура, которая создает файл, записывает содержимое в него и затем сохраняет файл.

Как игнорировать файлы, которые открываются в режиме WRITE в каталоге?

Пример кода:

for {
 fileList, err := ioutil.ReadDir("/uploadFiles")
  if err != nil {
     log.Fatal(err)
     continue
  }

 for _, f := range fileList {
      log.Println("File : ", f.Name())
      go printContents(f.Name())
 }

 time.Sleep(time.Second * 5)
}

В процедуре printContents я хочу игнорировать файлы, которые открыты в режиме WRITE.

1 Ответ

0 голосов
/ 11 декабря 2018

Это не так, как это делается.

Вне моей головы, я могу подумать о следующих вариантах:

  • Если обе программы работают в одной программеЕсть небольшая проблема: сделать так, чтобы программа-производитель регистрировала имена файлов, которые она завершила , внося изменения в некоторый реестр, и заставляла "потребительскую" процедуру считывать (и удалять) из этого реестра.

    В простейшем случае это может быть буферизованный канал.

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

  • Если процедуры работают в разных процессах на одной и той же машине, но вы управляете обеими программами, сделайте так, чтобы процесс производителя передавал одни и те же данные процессу потребителя через любую подходящуюсвоего рода IPC.

    Какой метод сделать IPC лучше, зависит от того, как процессы запускаются, взаимодействуют и т. д.

    Существует множество вариантов выбора.ion.

  • Если вы управляете обоими процессами, но не хотите связываться с IPC между ними (тоже есть причины), то заставьте производителя следовать рекомендациям по написанию файла(подробнее об этом чуть позже), и заставьте потребителя использовать любое средство мониторинга файловой системы, чтобы сообщить, какие файлы создаются («появляются») после того, как они были созданы производителем.Вы можете начать с github.com/fsnotify/fsnotify.

    Чтобы правильно записать файл, производитель должен записать свои данные во временный файл, то есть файл, расположенный в том же каталоге, но имеющийимя файла, которое хорошо понимается, чтобы указать, что файл еще не закончен, например, «.foobar.data.part» или «foobar.data.276gd14054.tmp» - это нормально для записи «foobar.data».(Существуют и другие подходы, но этот достаточно хорош для начала.)

    Как только файл готов, производитель должен переименовать файл из его временного имени в его "правильное", окончательное имя.Эта операция является атомарной во всех разумных ОС / файловых системах и делает файл атомарно "возникающим в существовании" из PoV потребителя.Например, inotify в Linux генерирует событие типа «перемещено в» для такого появления .

    Если вам не хочется делать правильные вещи самостоятельно, github.com/dchest/safefile - это хороший кроссплатформенный старт.

    Как вы можете видеть, с этим подходом вы знаете, что файл сделан только из того факта, что он был обнаружен.

  • Если вы не контролируете производителя, вам, возможно, придется прибегнуть к угадыванию.

    Самое простое, опять же, следить за файловой системой на предмет событий, но на этот раз для "файла обновлен"события, а не события "файл создан".Для каждого файла, сообщенного как обновленный, вы должны были помнить временную метку этого события, и по прошествии определенного количества времени вы можете объявить , что файл создан производителем.

    IMO thisПодход - худший из всех, но если у вас нет лучших вариантов, это по крайней мере что-то.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...