How To Save Attachments object to RackSpace Cloud using C#? - c#

I Have one 'System.Net.Mail.Attachment[] attachment' object , This object contains PDF,Xls,Doc or jpg file.
I want to save this attachment object to cloud server.
string sSavePath = "EmailAttachment/" + intSomeid + "/";
string strErrorMsg = string.Empty;
if ((attachments != null))
{
MemoryStream memoryStream = new MemoryStream();
StreamWriter memoryWriter = new StreamWriter(memoryStream);
memoryWriter.Write(attachments[0]);
memoryStream.Position = 0;
CloudFileSystem.SaveFileToCloudSystem(memoryStream, ref strErrorMsg, sSavePath, ConfigHelper.PrivateContainer, attachments[intI].Name);
memoryWriter.Dispose();
memoryStream.Dispose();
}
I have used the above code to save the file.
The File is saved to cloud but having 0 Byte data (Corrupted) File.
I have searched many places for that.
But not able to find error in the code.
Please suggest some solution in this case ?

Looks like you are making it yourself more difficult then needed. The Attachment instance has an ContentStream property which you don't need to feed through a MemoryStream at all.
string sSavePath = "EmailAttachment/" + intSomeid + "/";
string strErrorMsg = string.Empty;
if ((attachments != null))
{
CloudFileSystem.SaveFileToCloudSystem(
attachments[intI].ContentStream,
ref strErrorMsg,
sSavePath,
ConfigHelper.PrivateContainer,
attachments[intI].Name);
}
If you are doing this:
MemoryStream memoryStream = new MemoryStream();
StreamWriter memoryWriter = new StreamWriter(memoryStream);
memoryWriter.Write(attachments[0]);
You are probably writing the string representation of Attachment (ToString() gets called) and that is not the content of your file.

After so much r&d ,I have come up with the following answer
Memory stream of attachment object didn't work for me.
So I have approached temp path where the attachement was saved and do the following magical code :
string FileName = ((System.IO.FileStream (attachments[intI].ContentStream)).Name;
MemoryStream ms = new MemoryStream();
using (FileStream file = new FileStream(FileName, FileMode.Open, FileAccess.Read))
{
byte[] bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
ms.Write(bytes, 0, (int)file.Length);
}
ms.Position = 0;
CloudFileSystem.SaveFileToCloudSystem(ms, ref strErrorMsg, sSavePath, ConfigHelper.PrivateContainer, attachments[intI].Name);
ms.Dispose();
I hope my question and answer helps you for your project

Related

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

I have some code that is meant to retrieve a file from an S3 bucket and deserialize the file. When I use a file stream I get all the data no problem, but when I use a memory stream it seems like I am not getting all of the data:
It doesnt get the full XML:
Where it should look like:
Here is the code I am using:
internal object ReadDataContractFromFile(string filename, Type type)
{
GetObjectRequest getObjRequest = new GetObjectRequest();
MemoryStream memoryStream = new MemoryStream();
getObjRequest.BucketName = bucketName;
getObjRequest.Key = filename;
string path = #"C:\{PATH_TO_FILE}\requests\" + filename;
FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite);
using (GetObjectResponse getObjRespone = s3Client.GetObject(getObjRequest))
using (Stream responseStream = getObjRespone.ResponseStream)
{
responseStream.CopyTo(fileStream);
//memoryStream.Seek(0, 0);
XmlReaderSettings rs = new XmlReaderSettings
{
ConformanceLevel = ConformanceLevel.Fragment,
};
XmlReader r = XmlReader.Create(fileStream, rs);
return new DataContractSerializer(type).ReadObject(r);
}
}
If I use memoryStream in place of the fileStream variable, I get the incomplete XML I showed above. I tried to seek to the beginning of the stream incase the position was wrong but that didnt fix it. Any idea what Im doing wrong?

C# Spire Document.SaveToStream not working

I have the following code but it is just creating a 0kb empty file.
using (var stream1 = new MemoryStream())
{
MemoryStream txtStream = new MemoryStream();
Document document = new Document();
fileInformation.Stream.CopyTo(stream1);
document.LoadFromStream(stream1, FileFormat.Auto);
document.SaveToStream(txtStream, FileFormat.Txt);
StreamReader reader = new StreamReader(txtStream);
string text = reader.ReadToEnd();
System.IO.File.WriteAllText(fileName + ".txt", text);
}
I know the data is successfully loaded into document because if do document.SaveToTxt("test.txt", Encoding.UTF8);
instead of the SaveToStream line it exports the file properly.
What am I doing wrong?
When copying a stream, you need to take care to reset the position to 0 if copying. As seen in the answer here, you can do something like this to your streams:
stream1.Position = 0;
txtStream.Position = 0;

Alternative way of using System.IO.File.OpenWrite() in Using(Stream fileStream = System.IO.File.OpenWrite("D:\sample.svg"))

using (Stream fileStream = System.IO.File.OpenWrite("D:\sample.svg"))
{
byte[] buffer = new byte[8 * 1024];
int len;
while ((len = SvgStream.Read(buffer, 0, buffer.Length)) > 0)
{
fileStream.Write(buffer, 0, len);
}
}
I have this code for converting a PPT to SVG. SvgStream contains the PPT Slides. I don't want to store the converted SVG file on a physical path like D:\sample.svg. Is it possible to store it on an object that is not a physical path?
Is it possible to store it on an object that is not a physical path?
Sure. Create a MemoryStream instead of a FileStream if you want to stream into memory rather than the file system.
And while I'm here: you might want to use the CopyTo method rather than this tedious business of buffering it over one page at a time.
I saved it to a string:
SvgStream = new MemoryStream();
sld.WriteAsSvg(SvgStream);
SvgStream.Position = 0;
string[] svgArray = new string[MAX];
//instead of using(var fileStream = File.IO.......
//I came up with this:
var sr = new StreamReader(SvgStream);
svgArray[i] = sr.ReadToEnd();

DotNetZip Saving to Stream

I am using DotNetZip to add a file from a MemoryStream to a zip file and then to save that zip as a MemoryStream so that I can email it as an attachment. The code below does not err but the MemoryStream must not be done right because it is unreadable. When I save the zip to my hard drive everything works perfect, just not when I try to save it to a stream.
using (ZipFile zip = new ZipFile())
{
var memStream = new MemoryStream();
var streamWriter = new StreamWriter(memStream);
streamWriter.WriteLine(stringContent);
streamWriter.Flush();
memStream.Seek(0, SeekOrigin.Begin);
ZipEntry e = zip.AddEntry("test.txt", memStream);
e.Password = "123456!";
e.Encryption = EncryptionAlgorithm.WinZipAes256;
var ms = new MemoryStream();
ms.Seek(0, SeekOrigin.Begin);
zip.Save(ms);
//ms is what I want to use to send as an attachment in an email
}
Ok, I figured out my problem, pretty stupid actually. Thanks for everyone's help!
ZipEntry e = zip.AddEntry("test.txt", memStream);
e.Password = "123456!";
e.Encryption = EncryptionAlgorithm.WinZipAes256;
//zip.Save("C:\\Test\\Test.zip");
//Stream outStream;
var ms = new MemoryStream();
zip.Save(ms);
//--Needed to add the following 2 lines to make it work----
ms.Seek(0, SeekOrigin.Begin);
ms.Flush();
I've copied your code, and then saved your final memory steam to disk as data.txt. It was completely unreadable to me, but then I realized that it wasn't a text file, it was a zip file, so i saved it as data.zip and it worked as expected
the method I used to save ms to disk is the following(immediately after your zip.Save(ms); line)
ms.Position = 0;
byte[] data = ms.ToArray();
File.WriteAllBytes("data.zip", data);
So, I believe that your memory stream is what It is supposed to be, which is compressed text. It won't be readable until you decompress it.

Create new FileStream out of a byte array

I am attempting to create a new FileStream object from a byte array. I'm sure that made no sense at all so I will try to explain in further detail below.
Tasks I am completing:
1) Reading the source file which was previously compressed
2) Decompressing the data using GZipStream
3) copying the decompressed data into a byte array.
What I would like to change:
1) I would like to be able to use File.ReadAllBytes to read the decompressed data.
2) I would then like to create a new filestream object usingg this byte array.
In short, I want to do this entire operating using byte arrays. One of the parameters for GZipStream is a stream of some sort, so I figured I was stuck using a filestream. But, if some method exists where I can create a new instance of a FileStream from a byte array - then I should be fine.
Here is what I have so far:
FolderBrowserDialog fbd = new FolderBrowserDialog(); // Shows a browser dialog
fbd.ShowDialog();
// Path to directory of files to compress and decompress.
string dirpath = fbd.SelectedPath;
DirectoryInfo di = new DirectoryInfo(dirpath);
foreach (FileInfo fi in di.GetFiles())
{
zip.Program.Decompress(fi);
}
// Get the stream of the source file.
using (FileStream inFile = fi.OpenRead())
{
//Create the decompressed file.
string outfile = #"C:\Decompressed.exe";
{
using (GZipStream Decompress = new GZipStream(inFile,
CompressionMode.Decompress))
{
byte[] b = new byte[blen.Length];
Decompress.Read(b,0,b.Length);
File.WriteAllBytes(outfile, b);
}
}
}
Thanks for any help!
Regards,
Evan
It sounds like you need to use a MemoryStream.
Since you don't know how many bytes you'll be reading from the GZipStream, you can't really allocate an array for it. You need to read it all into a byte array and then use a MemoryStream to decompress.
const int BufferSize = 65536;
byte[] compressedBytes = File.ReadAllBytes("compressedFilename");
// create memory stream
using (var mstrm = new MemoryStream(compressedBytes))
{
using(var inStream = new GzipStream(mstrm, CompressionMode.Decompress))
{
using (var outStream = File.Create("outputfilename"))
{
var buffer = new byte[BufferSize];
int bytesRead;
while ((bytesRead = inStream.Read(buffer, 0, BufferSize)) != 0)
{
outStream.Write(buffer, 0, bytesRead);
}
}
}
}
Here is what I ended up doing. I realize that I did not give sufficient information in my question - and I apologize for that - but I do know the size of the file I need to decompress as I am using it earlier in my program. This buffer is referred to as "blen".
string fi = #"C:\Path To Compressed File";
// Get the stream of the source file.
// using (FileStream inFile = fi.OpenRead())
using (MemoryStream infile1 = new MemoryStream(File.ReadAllBytes(fi)))
{
//Create the decompressed file.
string outfile = #"C:\Decompressed.exe";
{
using (GZipStream Decompress = new GZipStream(infile1,
CompressionMode.Decompress))
{
byte[] b = new byte[blen.Length];
Decompress.Read(b,0,b.Length);
File.WriteAllBytes(outfile, b);
}
}
}

Categories

Resources