Stream to string - c#

How do I append Stream output to a string instead of a file in this code?
HttpWebResponse res = (HttpWebResponse)httpRequest.GetResponse();
using (Stream output = File.OpenWrite(#"c:\temp\tmp.html"))
using (Stream input = res.GetResponseStream())
{
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
input.Close();
output.Close();
}

You can use StreamReader:
HttpWebResponse res = (HttpWebResponse)httpRequest.GetResponse();
using (Stream input = res.GetResponseStream())
using (var streamReader = new StreamReader(input))
{
string result = streamReader.ReadToEnd();
}
Note this would read the entire string into memory.

Use encoding to get a string and then use StringReader to read buffer.
HttpWebResponse res = (HttpWebResponse)httpRequest.GetResponse();
using (Stream output = File.OpenWrite(#"c:\temp\tmp.html"))
using (Stream input = res.GetResponseStream())
{
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
input.Close();
output.Close();
string sBuffer = Encoding.UTF8.GetString(buffer);
StringReader reader = new StringReader(sBuffer);
​

Related

Zip file is getting corrupted after downloading from server in C#

request = MakeConnection(uri, WebRequestMethods.Ftp.DownloadFile, username, password);
response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
//This part of the code is used to write the read content from the server
using (StreamReader responseReader = new StreamReader(responseStream))
{
using (var destinationStream = new FileStream(toFilenameToWrite, FileMode.Create))
{
byte[] fileContents = Encoding.UTF8.GetBytes(responseReader.ReadToEnd());
destinationStream.Write(fileContents, 0, fileContents.Length);
}
}
//This part of the code is used to write the read content from the server
using (var destinationStream = new FileStream(toFilenameToWrite, FileMode.Create))
{
long length = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[2048];
readCount = responseStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
destinationStream.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
}
}
The former ones writes the content to the file but when I try to open the file it says it is corrupted. But the later one does the job perfectly when downloading zip files. Is there any specific reason why the former code doesn't work for zip files as it works perfectly for text files?
byte[] fileContents = Encoding.UTF8.GetBytes(responseReader.ReadToEnd());
You try to interpret a binary PDF file as an UTF-8 text. That just cannot work.
For a correct code, see Upload and download a binary file to/from FTP server in C#/.NET.
Use BinaryWriter and pass it FileStream.
//This part of the code is used to write the read content from the server
using (var destinationStream = new BinaryWriter(new FileStream(toFilenameToWrite, FileMode.Create)))
{
long length = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[2048];
readCount = responseStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
destinationStream.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
}
}
here is my solution that worked for me
C#
public IActionResult GetZip([FromBody] List<DocumentAndSourceDto> documents)
{
List<Document> listOfDocuments = new List<Document>();
foreach (DocumentAndSourceDto doc in documents)
listOfDocuments.Add(_documentService.GetDocumentWithServerPath(doc.Id));
using (var ms = new MemoryStream())
{
using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
{
foreach (var attachment in listOfDocuments)
{
var entry = zipArchive.CreateEntry(attachment.FileName);
using (var fileStream = new FileStream(attachment.FilePath, FileMode.Open))
using (var entryStream = entry.Open())
{
fileStream.CopyTo(entryStream);
}
}
}
ms.Position = 0;
return File(ms.ToArray(), "application/zip");
}
throw new ErrorException("Can't zip files");
}
don't miss the ms.Position = 0; here

Changing FileStream Write encoding type

This is my code :
public static string DownloadFile(string FtpUrl, string FileNameToDownload,
string userName, string password, string tempDirPath)
{
string ResponseDescription = "";
string PureFileName = new FileInfo(FileNameToDownload).Name;
string DownloadedFilePath = tempDirPath + "/" + PureFileName;
string downloadUrl = String.Format("{0}/{1}", FtpUrl, FileNameToDownload);
FtpWebRequest req = (FtpWebRequest)FtpWebRequest.Create(downloadUrl);
req.Method = WebRequestMethods.Ftp.DownloadFile;
req.Credentials = new NetworkCredential(userName, password);
req.UseBinary = true;
req.Proxy = null;
try
{
FtpWebResponse response = (FtpWebResponse)req.GetResponse();
Stream stream = response.GetResponseStream();
byte[] buffer = new byte[2048];
FileStream fs = new FileStream(DownloadedFilePath, FileMode.Create);
int ReadCount = stream.Read(buffer, 0, buffer.Length);
while (ReadCount > 0)
{
fs.Write(buffer, 0, ReadCount);
ReadCount = stream.Read(buffer, 0, buffer.Length);
}
ResponseDescription = response.StatusDescription;
fs.Close();
stream.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return ResponseDescription;
}
}
This code Downloads a file from a ftp server and write it to a specific path in server.
but the encoding of the saved file is not UTF-8.
I want to change the encoding type of the file to UTF-8.
Do I must use StreamReader ?
How Can I modify that code?
In theory, the below should work, but it depends or whether the responsestream can work together with the streamreader.
Writing with a different encoding is easy, you can simply use a streamwriter (based on textwriter) instead of a filestream. However, you can't write the bytes directly, since you have to write the properly formatted text. For that, the bytes have to be converted to text (Char buffer) with the proper original encoding.
char[] buffer = new char[2048]; //or 1024 if you want to keep the same block size
using (var reader = new StreamReader(stream, Encoding.Unicode)) // <= Or whatever encoding the orignal is
{
using (var tw = new StreamWriter(DownloadedFilePath, false, Encoding.UTF8)) //streamwriter instead of filestream
{
while (true)
{
int ReadCount = reader.Read(buffer, 0, buffer.Length);
if (ReadCount == 0) break;
tw.Write(buffer, 0, ReadCount);
}
ResponseDescription = response.StatusDescription;
stream.Close();
tw.Close();
}
}
If the streamreader gives problems, you can also download the bytes first, and use a streamreader on the already downloaded bytes.
You can wrap it in StreaWriter:
try
{
FtpWebResponse response = (FtpWebResponse)req.GetResponse();
Stream stream = response.GetResponseStream();
byte[] buffer = new byte[2048];
var sw = new StreamWriter( new FileStream(DownloadedFilePath, FileMode.Create),
Encoding.UTF8);
int ReadCount = stream.Read(buffer, 0, buffer.Length);
while (ReadCount > 0)
{
sw.Write(buffer, 0, ReadCount);
ReadCount = stream.Read(buffer, 0, buffer.Length);
}
ResponseDescription = response.StatusDescription;
sw.Close();
stream.Close();
}
I hope it will help
You have a look here :https://stackoverflow.com/ answer

httpwebrespose does not receive pdf file?

A web application that receive and send a pdf file with signature. I send pdf file in httpwebrequest to the application. But not receive that pdf file with httpwebresponse ?
My code
byte[] pdfFile = File.ReadAllBytes("c:\\sample.pdf");
WebRequest request = WebRequest.Create("URL");
request.Credentials = new NetworkCredential("Username", "Password");
request.Proxy.Credentials = new NetworkCredential("Username", "Password");
request.Method = "POST";
request.ContentLength = pdfFile.Length;
request.ContentType = "application/pdf";
Stream stream = request.GetRequestStream();
stream.Write(pdfFile, 0, pdfFile.Length);
stream.Close();
WebResponse resp = request.GetResponse();
var buffer = new byte[4096];
MemoryStream memoryStream = new MemoryStream();
Stream responseStream =resp.GetResponseStream();
{
int count;
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write
(buffer, 0, responseStream.Read(buffer, 0, buffer.Length));
} while (count != 0);
}
resp.Close();
byte[] memoryBuffer = memoryStream.ToArray();
System.IO.File.WriteAllBytes(#"c:\sample1.txt", memoryBuffer);
int s = memoryBuffer.Length;
BinaryWriter binaryWriter =
new BinaryWriter(File.Open(#"c:\sample2.txt", FileMode.Create));
binaryWriter.Write(memoryBuffer);
binaryWriter.Close();
//Read Fully is :
public static byte[] ReadFully(Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
One problem you have is in your reading:
int count;
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, responseStream.Read(buffer, 0, buffer.Length));
} while (count != 0);
You're reading the buffer twice each time through the loop. The bytes you read the first time are lost because you overwrite them. Your code should be:
int count;
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, count);
} while (count != 0);
Also: I don't understand why you're writing the PDF to the request stream. Are you trying to send the PDF to a server and have it send the same file back?
What, exactly, are you trying to do here?

PhoneGap Build API Error when Posting .ZIP file Greater than 127kb

I wrote the C# application below to update an existing application via the PhoneGap Build API. I noticed it works when my .ZIP file is 127kb or less. As soon as it hits 128kb, I get a 500 HTTP response. Sorry, the API does not return any details on the error, only the 500 response code. Any help with this issue will be greatly appreciated. Please note the placeholders for authentication token, appId and .zip file location. Thanks.
using System;
using System.IO;
using System.Net;
namespace PhoneGapBuildQuestion
{
class Program
{
static void Main(string[] args)
{
string token = "<add your token here>";
string appId = "<add your appId here>";
string zipFile = "<add full path to the application .zip file here>";
var info = new FileInfo(zipFile);
var request = (HttpWebRequest)WebRequest.Create(string.Format("https://build.phonegap.com/api/v1/apps/{0}?auth_token={1}", appId, token));
request.ContentType = "application/zip";
request.Headers["Content-disposition"] = string.Format("attachment; filename=\"{0}\"", info.Name);
request.Method = "PUT";
var reqStream = request.GetRequestStream();
var file = new FileStream(zipFile, FileMode.Open);
var bytes = new byte[32768];
int len = 0;
while((len = file.Read(bytes, 0, bytes.Length)) > 0)
reqStream.Write(bytes, 0, len);
reqStream.Close();
var response = new StreamReader(request.GetResponse().GetResponseStream());
string responseText = response.ReadToEnd();
Console.WriteLine(responseText);
Console.ReadLine();
}
}
}
I figured it out. I used fiddler to capture the request from my app and cURL, compared the two and adjusted accordingly. Here is the code I ended up with:
using System;
using System.IO;
using System.Net;
namespace PhoneGapBuildQuestion
{
class Program
{
static void Main(string[] args)
{
string appId = "[your appId here]";
string fileName = "[absolute path to .zip file here]";
string token = "[authentication token here]";
string boundry = "----------------------------7b053ae48e94";
var encoding = new System.Text.ASCIIEncoding();
var fileInfo = new FileInfo(fileName);
var ms = new MemoryStream();
long totalBytes = 0;
string txt = string.Format("--{0}{2}Content-Disposition: form-data; name=\"file\"; filename=\"{1}\"{2}Content-Type: application/octet-stream{2}{2}", boundry, fileInfo.Name, Environment.NewLine);
int bytesRead = 0;
var buffer = new byte[32768];
bytesRead = encoding.GetBytes(txt, 0, txt.Length, buffer, 0);
totalBytes += bytesRead;
ms.Write(buffer, 0, bytesRead);
// read/write file contents to the stream
var fs = new FileStream(fileName, FileMode.Open);
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, bytesRead);
totalBytes += bytesRead;
}
txt = Environment.NewLine + "--" + boundry + "--" + Environment.NewLine;
bytesRead = encoding.GetBytes(txt, 0, txt.Length, buffer, 0);
totalBytes += bytesRead;
ms.Write(buffer, 0, bytesRead);
ms.Position = 0;
var request = (HttpWebRequest)WebRequest.Create(string.Format("https://build.phonegap.com/api/v1/apps/{0}?auth_token={1}", appId, token));
request.ContentLength = totalBytes;
request.Method = "PUT";
request.ContentType = "multipart/form-data; boundary=" + boundry;
var requestStream = request.GetRequestStream();
while ((bytesRead = ms.Read(buffer, 0, buffer.Length)) > 0)
requestStream.Write(buffer, 0, bytesRead);
requestStream.Close();
Console.WriteLine(new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd());
Console.ReadLine();
}
}
}

Download to file and save to byte array

I am trying to download a file to my computer and in the same time save it to Byte Array:
try
{
var req = (HttpWebRequest)HttpWebRequest.Create(url);
var fileStream = new FileStream(filePath,
FileMode.Create, FileAccess.Write, FileShare.Write);
using (var resp = req.GetResponse())
{
using (var stream = resp.GetResponseStream())
{
byte[] buffer = new byte[0x10000];
int len;
while ((len = stream.Read(buffer, 0, buffer.Length)) > 0)
{
//Do with the content whatever you want
// ***YOUR CODE***
MemoryStream memoryStream = new MemoryStream();
if (len > 0)
{
memoryStream.Write(buffer, 0, len);
len = stream.Read(buffer, 0, buffer.Length);
}
file = memoryStream.ToArray();
fileStream.Write(buffer, 0, len);
}
}
}
fileStream.Close();
}
catch (Exception exc) { }
And i noticed that it's not download all the file with this.
I wan to do it because i want to download a file and in the same time work with it.
Any idea why this problem happen?
There is a much easier way to get the file bytes by using the System.Net.WebClient.WebClient():
private static byte[] DownloadFile(string absoluteUrl)
{
using (var client = new System.Net.WebClient())
{
return client.DownloadData(absoluteUrl);
}
}
Usage:
var bytes = DownloadFile(absoluteUrl);
The problem looks to be double-reading - you are putting different things into the memory-stream / file-stream - it should be more like:
// declare file/memory stream here
while ((len = stream.Read(buffer, 0, buffer.Length)) > 0)
{
memoryStream.Write(buffer, 0, len);
fileStream.Write(buffer, 0, len);
// if you need to process "len" bytes, do it here
}
You might be able to lose "memoryStream" completely if you are processing the "len" bytes immediately. If it fits in-memory, it may be easier to just use WebClient.DownloadData and then File.WriteAllBytes.

Categories