Не удается получить доступ к файлу, так как он используется другим процессом


Мой веб-метод создает pdf-файл в папке% temp%, и это работает. Затем я хочу добавить некоторые пользовательские поля (мета) в этот файл, используя приведенный ниже код.

Класс PdfStamper генерирует IOException, независимо от того, использую ли я его метод .Close() или блок using просто заканчивается. Процесс, который все еще удерживает дескриптор файла, - это сам веб-сервер webdev (я отлаживаю в VS2010 SP1).

private string AddCustomMetaData(string guid, int companyID, string filePath)
{
    try
    {
        PdfReader reader = new PdfReader(filePath);

        using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
        {
            PdfStamper st = new PdfStamper(reader, fs);
            Dictionary<string, string> info = reader.Info;
            info.Add("Guid", guid);
            info.Add("CompanyID", companyID.ToString());

            st.MoreInfo = info;
            st.Close();
        }

        reader.Close();

        return guid;
    }
    catch (Exception e)
    {
        return e.Message;
    }
}

Независимо от того, что я пытаюсь, он продолжает бросать исключение в st.Close();, чтобы быть больше точно:

Процесс не может получить доступ к файлу 'C:Users[мой имя пользователя]AppDataLocalTemp53b96eaf-74a6-49d7-a715-6c2e866a63c3.в формате PDF' потому что он используется другим процессом.

Либо я упускаю что-то очевидное, либо есть проблема с классом PdfStamper, о которой я пока не знаю. Версии itextsharp используются 5.3.3.0 и 5.4.0.0, проблема та же.

Любое озарение было бы очень ценно.

EDIT: я в настоящее время "кодирование вокруг" проблемы, но я не нашел никакого решения.

4 6

4 ответа:

Ваша проблема заключается в том, что вы пишете в файл, одновременно читая из него. В отличие от некоторых типов файлов (JPG, PNG и т. д.), которые "загружают" все данные в память, iTextSharp считывает данные в виде потока. Вам нужно либо использовать два файла и поменять их местами в конце, либо вы можете заставить iTextSharp "загрузить" первый файл, привязав ваш PdfReader к массиву байтов файла.

PdfReader reader = new PdfReader(System.IO.File.ReadAllBytes(filePath));

Я предлагаю вам использовать FileShare enumerator при открытии файла, поэтому попробуйте открыть файл с помощью None sharing

   File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.None);

Попробуй .Dispose() ваш PDF-ридер (или то, что вы используете для его создания), когда вы сохраняете файл в первый раз

Попробуйте это решение, если вы считаете его возможным для вас - после того, как webmethod создает файл в папке Temp, вам нужно скопировать файл и вставить его в другое место или в то же место с другим именем и передать недавно скопированный путь к файлу вашему PDF reader.