Downloading mail attachments damaging files - c#

i'm using C# to download the attachments on a mail message but all the files I download is damaged (specially PDF files), the code I;m using only download one attachment at the time (because are being moved based on criteria)
The code I'm using:
byte[] allBytes = new byte[item.ContentStream.Length];
int bytesRead = item.ContentStream.Read(allBytes, 0, (int)item.ContentStream.Length);
string destinationFile = #Destination;
BinaryWriter writer = new BinaryWriter(new FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None));
writer.Write(allBytes);
writer.Close();

BinaryWriter is only meant to write primitive data to a file. It's not meant for stream operations. You can copy data from one stream to another with Stream.CopyTo eg:
using(var targetStream=new FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
{
item.ContentStream.CopyTo(targetStream);
}

Don't use BinaryWriter. You already have the binary content, just write that to disk.
File.WriteAllBytes(destinationFile, allBytes)

Related

How to decompress with GZipStream in C#?

My problem is that I can't find a solution to decompress a file. Compressing a file works without error messages, but I don't know if that's right.
Here is my code for compressing a file:
using (StreamReader sr = new StreamReader(File.Open(srcFile, FileMode.Open), true))
using (GZipStream zip = new GZipStream(File.Open(destFile, FileMode.OpenOrCreate), CompressionMode.Compress, false))
using (StreamWriter sw = new StreamWriter(zip, Encoding.UTF8)) {
while (!sr.EndOfStream) {
sw.Write((char)sr.Read());
}
}
Then I tried to decompress the compressed file with following code:
using (GZipStream zip = new GZipStream(File.Open(srcFile, FileMode.Open), CompressionMode.Decompress, false))
using (StreamReader sr = new StreamReader(zip, true))
using (StreamWriter sw = new StreamWriter(File.Open(destFile, FileMode.OpenOrCreate), Encoding.UTF8)) {
while (!sr.EndOfStream) {
sw.Write((char)sr.Read());
}
}
The content of the decompressed file wasn't like the content of the source file and I don't know where I've made my mistakes.
Thanks in advance for your help.
I'm sorry for my bad English, but English isn't my strength. :/
Using StreamReader/Writer is not indicated. It will certainly destroy the file content if the file is not a text file. And the decompressed file will always have a BOM, it might be missing in the original file.
There's just no reason to use these classes, GZipStream doesn't care. Use FileStream instead, the only way to be sure that the decompressed bytes are an exact match with the bytes in the original file.

One program writes to file while other program reads same file c#

1) I have created a program that has opened a twitter stream and writes everything to a file.
FileStream fs = new FileStream(#"\Database\twitterstream.txt", FileMode.Create);
TextWriter tmp = Console.Out;
StreamWriter sw = new StreamWriter(fs);
Console.SetOut(sw);
2) I have another program that I want to read said text file.
using (StreamReader sr = File.OpenText("C:\\Database\\twitterstream.txt"))
{
input = sr.ReadLine();
}
Because I want it to be in real time I am trying to have one program write, while at the same time the other program reads, however obviously it is throwing
"The process cannot access the file
'C:\Database\twitterstream.txt' because it is being used by another
process" back at me.
Is what I am trying to do possible? If so, how do I go about doing it?
Add a couple parameters to you FileStream constructor:
FileStream fs = new FileStream(
#"\Database\twitterstream.txt",
FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
See FileStream on MSDN

unable to save dynamically created MemoryStream with rebex sftp

I'm using StreamWriter to generate a dynamic file and holding it in a MemoryStream. Everything appears to be alright until I go to save the file using rebex sftp.
The example they give on their site works fine:
// upload a text using a MemoryStream
string message = "Hello from Rebex FTP for .NET!";
byte[] data = System.Text.Encoding.Default.GetBytes(message);
System.IO.MemoryStream ms = new System.IO.MemoryStream(data);
client.PutFile(ms, "message.txt");
However the code below does not:
using (var stream = new MemoryStream())
{
using (var writer = new StreamWriter(stream))
{
writer.AutoFlush = true;
writer.Write("test");
}
client.PutFile(stream, "test.txt");
}
The file "test.txt" is saved, however it is empty. Do I need to do more than just enable AutoFlush for this to work?
After writing to the MemoryStream, the stream is positioned at the end. The PutFile method reads from the current position to the end. That's exactly 0 bytes.
You need to position the stream at the beginning before passing it to PutFile:
...
}
stream.Seek(0, SeekOrigin.Begin);
client.PutFile(stream, "test.txt");
You may also need to prevent the StreamWriter from disposing the MemoryStream:
var writer = new StreamWriter(stream);
writer.Write("test");
writer.Flush();
stream.Seek(0, SeekOrigin.Begin);
client.PutFile(stream, "test.txt");

create file and save to it using memorystream

How can i create a file and write to it using the memory stream?
I need to use the memorystream to prevent other threads from trying to access the file.
The data i'm trying to save to a file is html.
How can this be done?
(Presuming you mean how to copy a file's content to a memory stream)
If you are using framework 4:
var memoryStream = new MemoryStream();
using var fileStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
fileStream.CopyTo(memoryStream);
Here are code to create file
byte[] data = System.Text.Encoding.ASCII.GetBytes("This is a sample string");
System.IO.MemoryStream ms = new System.IO.MemoryStream();
ms.Write(data, 0, data.Length);
ms.Close();

What's the least invasive way to read a locked file in C# (perhaps in unsafe mode)?

I need to read a Windows file that may be locked, but I don't want to create any kind lock that will prevent other processes from writing to the file.
In addition, even if the file is locked for exclusive use, I'd like to see what's inside.
Although this isn't my exact use case, consider how to read a SQL/Exchange log or database file while it's in use and mounted. I don't want to cause corruption but I still want to see the insides of the file and read it.
You can do it without copying the file, see this article:
The trick is to use FileShare.ReadWrite (from the article):
private void LoadFile()
{
try
{
using(FileStream fileStream = new FileStream(
"logs/myapp.log",
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
using(StreamReader streamReader = new StreamReader(fileStream))
{
this.textBoxLogs.Text = streamReader.ReadToEnd();
}
}
}
catch(Exception ex)
{
MessageBox.Show("Error loading log file: " + ex.Message);
}
}
The accepted answer is not correct. If the file is really locked, you cannot just change the file share. This would work if the lock has been set with this fileshare option too but it does not mean that it is the case. In fact, you can test #CaffGeek solution pretty easily by opening the file without the FileShare.ReadWrite and than trying to open it with this flag to ReadWrite. You will get that the file is using by another process.
Code:
string content;
var filePath = "e:\\test.txt";
//Lock Exclusively the file
var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);
//CaffGeek solution
using (FileStream fileStream = new FileStream(
filePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
using (StreamReader streamReader = new StreamReader(fileStream))
{
content = streamReader.ReadToEnd();
}
}
As you can see, it crashes. This result is the same with any FileStream method like the File.Open. It will crash what ever you put for FileShare during the open stage.
//OPEN FOR WRITE with exclusive
var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);
//OPEN FOR READ with file share that allow read and write
var x = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); //Crash
Copying the file is not also an option. You can try it your self by opening the file exclusively and try to copy the file on Windows Explorer or by code:
var filePath = "e:\\test.txt";
var filePathCopy = "e:\\test.txt.bck";
//Lock the file
var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);
File.Copy(filePath, filePathCopy);
var x = File.Open(filePathCopy, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using (var reader = new StreamReader(x))
{
content = reader.ReadToEnd();
}
r.Close();
File.Delete(filePathCopy);
This code crash when you hit the File.Copy line. The exception is the same as before : file is being using by another process.
You need to kill the process that has the lock of the file if you want to read it OR if you have the source code of the file that is locking the file to change this one to use FileShare.ReadWrite instead of just FileShare.Write.
You can probably create a copy and read that, even if the file is locked.
Or maybe a StreamReader on a FileStream depending on how SQL opened the file?
new FileStream("c:\myfile.ext", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

Categories