Search code examples
c#amazon-s3aws-sdk-net

Using memory stream instead of filestream for AWS C# S3 SDK not writing full file to S3


I have some code that is meant to create a file on AWS S3 bucket. When I use a file stream it works fine and all the data is present. When I use a memory stream, some of the xml data in the file is missing. Here is the code im running:

internal void WriteDataContractToFile(object data, string filename)
    {
        string path = @"C:\Jenova\restfulengine\RESTfulEngine\App_Data\requests\" + filename;
        try
        {
            using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite))
            {
                using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8))
                {
                    DataContractSerializer dcs = new DataContractSerializer(data.GetType());
                    writer.WriteStartDocument();
                    dcs.WriteObject(writer, data);
                }
            }
            var uploadRequest = new TransferUtilityUploadRequest();
            uploadRequest.FilePath = path;
            uploadRequest.Key = filename;
            uploadRequest.BucketName = bucketName;
            transferUtility.Upload(uploadRequest);

            //METHOD WITH MEMORY STREAM THAT DOESNT WORK

            using (MemoryStream stream = new MemoryStream())
            {
                using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8))
                {
                    DataContractSerializer dcs = new DataContractSerializer(data.GetType());
                    writer.WriteStartDocument();
                    dcs.WriteObject(writer, data);
                    var uploadRequest1 = new TransferUtilityUploadRequest();
                    uploadRequest1.InputStream = stream;
                    uploadRequest1.Key = filename;
                    uploadRequest1.BucketName = bucketName;
                    transferUtility.Upload(uploadRequest);
                }
            }
        }
        
    }

When I use the first method with the file stream all data is present in the file I create in S3. When I use the memory stream, I am missing the end of the file:

Missing closing tag

And is missing the end of the file:

enter image description here

This is what it is supposed to look like:

What its supposed to be

Does anyone see anything I am doing wrong? It doesnt make sense to me why the memory stream is truncating the data. Even when I write that memory stream to a file locally for testing the data is not complete so I am kind of at a loss, any suggestions are appreciated!


Solution

  • You're uploading before the stream is fully written. Probably the last buffer is written when you dispose the writer.

    So:

    using (MemoryStream stream = new MemoryStream())
    {
        using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8))
        {
            DataContractSerializer dcs = new DataContractSerializer(data.GetType());
            writer.WriteStartDocument();
            dcs.WriteObject(writer, data);
        }
    
        var uploadRequest1 = new TransferUtilityUploadRequest();
        uploadRequest1.InputStream = stream;
        uploadRequest1.Key = filename;
        uploadRequest1.BucketName = bucketName;
        transferUtility.Upload(uploadRequest);
    }
    

    Use XmlDictionaryWriter.CreateTextWriter(Stream, Encoding, Boolean) with false for the last parameter to let it keep the stream open.