I have an event receiver tied to a SharePoint 2010 picture library. When a picture is uploaded, I want to open it for processing. Files uploaded with the web interface work fine, but files copied via Windows Explorer view return zero bytes. Simplified code below.
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!
}
If I insert a delay before opening, it works.
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
}
But I though that ItemAdded was only called after everything was done, including file upload.
I also found that file.CanOpenFile(true) always returns true, whether or not OpenBinary works.
How can I make sure the file is ready to open before I call OpenBinary()?
I don't like the Thread.Sleep solution, because I'm sure larger files or a busier server would require more wait. The time required can't be predicted, and I don't want to loop and try again forever.
Update: I originally thought the failure to open was caused by larger files. Question has been updated to reflect the explorer view as the cause. I also find that Windows Explorer copy also triggers ItemUpdated (twice), and I am able to open the file here. A little messy to have 3 triggers, 2 calls to do 1 thing, so I am still open to suggestions.
Best Answer
I just encountered this issue today on SharePoint 2013. I've taken the suggestions listed here and improved upon them.
It's fine making the thread sleep for 2 seconds, but what happens when you have a large file? You're going to run into the same issue.
My code fix is as follows: