SharePoint ItemAdded и SPFile.OpenBinary (), нулевые байты - PullRequest
1 голос
/ 30 июня 2011

У меня есть получатель событий, связанный с библиотекой изображений SharePoint 2010.Когда изображение загружено, я хочу открыть его для обработки.Файлы, загруженные через веб-интерфейс, работают нормально, но файлы, скопированные с помощью проводника Windows, возвращают ноль байтов.Упрощенный код ниже.

public override void ItemAdded(SPItemEventProperties properties)
{
    SPListItem item = properties.ListItem;
    SPFile file = item.File;
    byte[] buffer = file.OpenBinary(); //buffer has zero bytes for files copied in Windows Explorer!
}

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

public override void ItemAdded(SPItemEventProperties properties)
{
    SPListItem item = properties.ListItem;
    SPFile file = item.File;
    System.Threading.Thread.Sleep(2000);
    byte[] buffer = file.OpenBinary(); //buffer now populated correctly
}

Но я думал, что ItemAdded вызывался только после того, как все было сделано, включая загрузку файла.Я также обнаружил, что file.CanOpenFile (true) всегда возвращает true независимо от того, работает или нет OpenBinary.

Как я могу убедиться, что файл готов открыться, прежде чем я вызову OpenBinary ()?Мне не нравится решение Thread.Sleep, потому что я уверен, что большие файлы или более загруженный сервер потребуют большего времени ожидания.Требуемое время не может быть предсказано, и я не хочу зацикливаться и повторять попытки навсегда.

Обновление: я первоначально думал, что ошибка открытия была вызвана большими файлами.Вопрос был обновлен, чтобы отразить точку зрения исследователя как причину.Я также обнаружил, что копия Windows Explorer также вызывает ItemUpdated (дважды), и я могу открыть файл здесь.Немного грязно иметь 3 триггера, 2 звонка, чтобы сделать 1 вещь, так что я все еще открыт для предложений.

Ответы [ 2 ]

2 голосов
/ 23 мая 2014

Я только что столкнулся с этой проблемой сегодня в SharePoint 2013. Я воспользовался перечисленными здесь предложениями и улучшил их.

Хорошо, когда поток спит 2 секунды, но что происходит, когда у вас большойфайл?Вы столкнетесь с той же проблемой.

Мой код исправлен следующим образом:

     //Check if the SPContext is null since Explorer View isn't within the context
     if (SPContext.Current == null)
        {
          //If the initial file length is 0, pause the thread for 2 seconds
          if (properties.ListItem.File.Length == 0)
             {

               System.Threading.Thread.Sleep(2000);

               //Since our item exists, run the GetItemById to instantiate a new  and updated SPListItem object 
               var spFile = properties.List.GetItemById(properties.ListItemId);

               //SharePoint places an Exclusive lock on the file while the data is being loaded into the file
               while (spFile.File.LockType != SPFile.SPLockType.None)
                     {
                       System.Threading.Thread.Sleep(2000);
                       spFile = properties.List.GetItemById(properties.ListItemId);

                       //We need to check if the file exists, otherwise it will loop forever if someone decides to cancel the upload
                       if (!spFile.File.Exists)
                        return;
                     }

                //If someone thought it was a good idea to actually load a 0 byte file, don't do anything else
                if (spFile.File.Length == 0)
                       return;

              }

        }
0 голосов
/ 28 марта 2013

Я сталкиваюсь с одной и той же проблемой в SP2010 и SP2013. Любая идея, как решить эту проблему?

Каким-то образом это связано с большими файлами. Маленькие файлы работают без проблем, большие файлы (400 КБ) не всегда будут работать.

У меня есть только одна подсказка. Если вы скопируете и вставите файл через проводник Windows (WebDAV) в библиотеку, EventHandle (ItemAdded) сработает, как только файл будет создан. Но это не значит, что файл уже заполнен данными. Я видел это однажды, мой отладчик достиг моей точки останова, даже когда windows все еще был занят процессом копирования.

Было бы здорово узнать, когда процесс копирования завершится. Я думал, что смогу сделать это, просто сделав spfile.openBinary (), и если он пуст, просто подождите 2 секунды и делайте это снова, пока он не получит что-то больше 0 байт. Но это не работает! Это работает только в том случае, если вы ждете, ДО того как вы вызовете openBinary () в первый раз, все остальные случаи вызова openBinary () приводят к тому же результату.

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