Как получить объекты FileInfo из папки Orchard Media?

Я пытаюсь создать кастом ImageFilter это требует от меня временно записать образ на диск, потому что я использую стороннюю библиотеку, которая принимает только FileInfo объекты как параметры. Я надеялся, что смогу использовать IStorageProvider легко написать и получить файл, но я не могу найти способ конвертировать IStorageFile в FileInfo или получите полный путь к папке Media текущего арендатора, чтобы получить файл самостоятельно.

public class CustomFilter: IImageFilterProvider {

    public void ApplyFilter(FilterContext context)
    {
        if (context.Media.CanSeek)
        {
            context.Media.Seek(0, SeekOrigin.Begin);
        }

        // Save temporary image 
        var fileName = context.FilePath.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault();

        if (!string.IsNullOrEmpty(fileName))
        {
            var tempFilePath = string.Format("tmp/tmp_{0}", fileName);
            _storageProvider.TrySaveStream(tempFilePath, context.Media);

            IStorageFile temp = _storageProvider.GetFile(tempFilePath);
            FileInfo tempFile = ???

            // Do all kinds of things with the temporary file

            // Convert back to Stream and pass along
            context.Media = tempFile.OpenRead();
        }
    }    
}

FileSystemStorageProvider делает тонну тяжелой работы, чтобы построить пути к папке Media, поэтому обидно, что они не являются общедоступными. Я бы предпочел не копировать весь этот код инициализации. Существует ли простой способ прямого доступа к файлам в папке "Медиа"?

2 ответа

Решение

Я не использую мультитенантность, поэтому простите меня, если это неточно, но этот метод я использую для получения полного пути к хранилищу, а затем выбираю объекты FileInfo из этого:

_storagePath = HostingEnvironment.IsHosted
    ? HostingEnvironment.MapPath("~/Media/") ?? ""
    : Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Media");

files = Directory.GetFiles(_storagePath, "*", SearchOption.AllDirectories).AsEnumerable().Select(f => new FileInfo(f));

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

Это в значительной степени именно то, что использует FileSystemStorageProvider, но мне не нужны были другие вызовы, которые он делает, чтобы выяснить, каким должен быть _storagePath.

Короче говоря, да, вам, вероятно, придется заново реализовать любые частные функции FileSystemStorageProvider, необходимые для выполнения задачи. Но вам может не понадобиться все из них.

Я тоже боролся с подобной проблемой, и я могу сказать, что IStorageProvider материал в значительной степени ограничен.

Вы можете увидеть это при просмотре кода FileSystemStorageFile, Класс уже использует FileInfo возвращать данные, но сама структура недоступна, и на этом основан другой код. Поэтому вам придется в основном переопределить все с нуля (собственная реализация IStorageProvider). Самый простой вариант - просто позвонить

FileInfo fileInfo = new FileInfo(tempFilePath);

но это сломало бы настройки, где ни один поставщик хранилища на основе файловой системы не используется как AzureBlobStorageProvider,

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

Другие вопросы по тегам