Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

As far as I am aware, you will get an error if you try to load large file sizes using the function IMemoryBlobStream.LoadFromFile().

Has anyone found some workaround code to load a file into a IMemoryBlobStream?

What I am trying to do is just insert a PDF document file into a BLOB in an Oracle database, but I am not, and do not want to use Oracle API's. I am just using ArcOjects for this one.

My code looks like:

public void LoadReport(string fileName)
{
    try
    {
        if (File.Exists(fileName))
        {
            IMemoryBlobStream2 memoryBlobStream = new MemoryBlobStreamClass();
            memoryBlobStream.LoadFromFile(fileName);

            report = memoryBlobStream;
        }
    }
    catch (Exception ex) {
                throw ex;
    }
}

UPDATE

This is the code I have put to finally get the file in the database, now just need to check reading out the file from the BLOB - hopefully it should work.

fs = new System.IO.FileStream(fileName, FileMode.Open, FileAccess.Read);

byte[] bytes = new byte[fs.Length];

int chunkSize = 2 << 17;

int pos = 0;

for (pos = 0; pos < (fs.Length - chunkSize); pos += chunkSize)
{
    fs.Read(bytes, pos, chunkSize);
}
long modResult = (fs.Length % chunkSize);
fs.Read(bytes, pos,Convert.ToInt32(modResult));

IMemoryBlobStream2 memoryBlobStream = new MemoryBlobStreamClass();
memoryBlobStream.ImportFromMemory(ref bytes[0], (uint)bytes.Length);

fs.Close();
share|improve this question
add comment

1 Answer

up vote 4 down vote accepted

First, load the file into a regular .NET Stream (e.g. a FileStream), then convert it to IMemoryBlobStream as follows:

byte[] bytes = new byte[stream.Length]; // stream is a .NET Stream instance
stream.Read(bytes, 0, bytes.Length);

IMemoryBlobStream memoryBlobStream = new MemoryBlobStreamClass();
memoryBlobStream.ImportFromMemory(ref bytes[0], (uint)bytes.Length);

In your specific scenario you can take a handy shortcut of reading the bytes in a simpler way, by calling File.ReadAllBytes(). It opens, reads and closes a FileStream behind the scenes for you.

Any other instance of a .NET Stream will do the trick, of course.

In any case, this approach is more memory-intensive than IMemoryBlobStream.LoadFromFile() as the data will need to reside in the memory twice before the GC collects the bytes reference.

share|improve this answer
    
This looks great - and a very good explanation. I tried this and it looked like it was working - but when reading into the byte array - it threw an exception "Insufficient system resources exist to complete the requested service." –  Vidar Dec 8 '11 at 16:06
    
How large is the binary data? –  Petr Krebs Dec 8 '11 at 16:29
    
Well the PDF is about 200mb - but some of the filess are only 23mb. It seems that any files less that 23mb have worked but the larger ones fail. –  Vidar Dec 8 '11 at 16:49
    
Hmm.. don't think I can help you with this one. I've never had problems with this approach. In your case it probably fails for the same reason IMemoryBlobStream.LoadFromFile() does in the first place. This could occur when a continous block of the requested memory is not available due to memory fragmentation. –  Petr Krebs Dec 8 '11 at 16:57
    
Unfortunately, ESRI forces us to use an intermediate in-memory blob representation without a means to use chunked transfer instead... –  Petr Krebs Dec 8 '11 at 17:00
show 7 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.