using GetObject, the memory stream returned is null while GetObjectSaveToFile returns proper file

StackOverflow https://stackoverflow.com/questions/18066260

Question

Rackspace .NET cloudifles API, the GetObjectSaveToFile method gets the file and save it properly in the specified location, but when using GetObject method, if i save the memorystream returned, the file is filled with bunch of nulls.

var cloudFilesProvider = new CloudFilesProvider(cloudIdentity);
cloudFilesProvider.GetObjectSaveToFile(inIntStoreID.ToString(), @"C:\EnetData\Development\Sanbox\OpenStack\OpenStackConsole\testImages\", inStrFileName);

works fine. but when i try

System.IO.Stream outputStream = new System.IO.MemoryStream();
cloudFilesProvider.GetObject(inIntStoreID.ToString(), inStrFileName, outputStream);
FileStream file = new FileStream(strSrcFilePath, FileMode.Create, System.IO.FileAccess.Write);
byte[] bytes = new byte[outputStream.Length];
outputStream.Read(bytes, 0, (int)outputStream.Length);
file.Write(bytes, 0, bytes.Length);
file.Close();
outputStream.Close();

i get a file with bunch of nulls in it.

Was it helpful?

Solution

I think the secret to your problem lies in the return value of outputStream.Read - which is likely returning 0.

I would try the following code instead:

using (System.IO.Stream outputStream = new System.IO.MemoryStream())
{
    cloudFilesProvider.GetObject(inIntStoreID.ToString(), inStrFileName, outputStream);

    byte[] bytes = new byte[outputStream.Length];
    outputStream.Seek(0, SeekOrigin.Begin);

    int length = outputStream.Read(bytes, 0, bytes.Length);
    if (length < bytes.Length)
        Array.Resize(ref bytes, length);

    File.WriteAllBytes(strSrcFilePath, bytes);
}

OTHER TIPS

I can confirm that using the IO.SeekOrigin.Begin does work. So I can define a class which has a byte array:-

 public class RackspaceStream
 {
    private  byte[] _bytes;

    public byte[] Bytes 
    {
        get { return _bytes; }
        set { _bytes = value; }
    }
    // other properties as needed
}

and use code very similar to the post above to assign the bytes from the output stream to it.

    public RackspaceStream DownloadFileToByteStream(string containerName, string cloudObjectName)
    {
        RackspaceStream rsStream = new RackspaceStream();
        try
        {
            CloudFilesProvider cfp = GetCloudFilesProvider();

            using (System.IO.Stream outputStream = new System.IO.MemoryStream())
            {
                cfp.GetObject(containerName, cloudObjectName, outputStream);

                byte[] bytes = new byte[outputStream.Length];
                outputStream.Seek (0, System.IO.SeekOrigin.Begin);

                int length = outputStream.Read(bytes, 0, bytes.Length);
                if (length < bytes.Length)
                    Array.Resize(ref bytes, length);

                rsStream.Bytes = bytes; // assign the byte array to some other object which is declared as a byte array 

            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);

        }
        return rsStream;
    } // DownloadFileSaveToDisk

then the returned object can be used elsewhere.....

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top