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

1.3k views Asked by At

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.

2

There are 2 answers

0
Sam Harwell On BEST ANSWER

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);
}
0
Robert Weir On

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.....