Как сгенерировать содержимое “файла” по запросу для каждой операции чтения в Linux?

Вопрос или проблема

У меня есть CSV-файл, который содержит список записей с известными значениями, такими как:

2024-11-01,78.5
2024-11-04,80.0
2024-11-06,78.0

Существует сервис, куда я хотел бы загрузить эту информацию, но он ожидает значение для каждой даты, поэтому мне нужно интерполировать, чтобы оценить отсутствующие записи:

2024-11-01,78.5
2024-11-02,79.0
2024-11-03,79.5
2024-11-04,80.0
2024-11-05,79.0
2024-11-06,78.0

Мне придется регулярно загружать это каждый раз после добавления новых данных. Есть ли способ создать фиктивный файл в моей файловой системе, который я могу выбрать в диалоговом окне загрузки браузера и который генерирует свежий интерполированный контент из исходного файла каждый раз, когда к нему обращаются? На данный момент единственным, казалось бы, подходящим решением, которое я нашел, было написание пользовательского драйвера FUSE, который обслуживает динамический контент, но это выглядит как избыточное решение для такой простой задачи. В качестве обходного пути я рассматривал возможность экспериментов с inotify, чтобы заменять содержимое файла каждый раз, когда исходник записывается, но это потребует обеспечения того, чтобы этот фоновый сервис работал все время. Есть ли более простой метод, который я упускаю, например, специального рода символическая ссылка или FIFO, который может запускать процесс при каждом чтении и перенаправлять его вывод?

П.С. Не стесняйтесь перенести это на StackOverflow, если это будет более уместно!

Ответ или решение

Чтобы создать "виртуальный" файл в Linux для генерации содержимого по запросу, вам подойдут несколько подходов. Ниже я подробно рассмотрю возможные варианты, включая их преимущества и недостатки, чтобы вы могли выбрать наиболее подходящий для вашей задачи.

1. Использование FUSE (Filesystem in Userspace)

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

Преимущества:

  • Полная гибкость: вы можете реализовать любую логику для генерации данных.
  • Легкость в интеграции с системными вызовами.

Недостатки:

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

Простой пример кода:

from fuse import FUSE, Operations
import pandas as pd
from datetime import datetime, timedelta
import os

class DynamicCSV(Operations):
    def __init__(self):
        self.base_file = 'data.csv'

    def read(self, path, size, offset):
        if path != '/dynamic.csv':
            return -errno.ENOENT

        # Чтение и обработка CSV
        df = pd.read_csv(self.base_file, header=None, parse_dates=[0])
        df.set_index(0, inplace=True)

        # Интерполяция данных
        date_range = pd.date_range(start=df.index.min(), end=df.index.max())
        df = df.reindex(date_range).interpolate()

        generated_contents = df.to_csv(header=False)

        return generated_contents.encode('utf-8')[offset:offset + size]

def main():
    fuse = FUSE(DynamicCSV(), '/path/to/mountpoint', foreground=True)

if __name__ == '__main__':
    main()

2. Использование FIFO (именованных каналов)

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

Преимущества:

  • Простой в реализации и настройке.
  • Не требует постоянной работы службы.

Недостатки:

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

Пример:

mkfifo /tmp/dynamic.csv

Затем вы можете реализовать процесс, который будет записывать данные в этот FIFO:

while true; do
    python generate_data.py > /tmp/dynamic.csv
done

На вашем веб-интерфейсе вы сможете выбрать /tmp/dynamic.csv как файл для загрузки.

3. Использование inotify

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

Заключение

В зависимости от ваших потребностей и уровня удобства в программировании, вы можете выбрать одно из предложенных решений. Для максимальной гибкости и возможностей рекомендуется рассмотреть FUSE, хотя и FIFO может быть хорошим вариантом в более простых случаях.

Оцените материал
Добавить комментарий

Капча загружается...