I have a CSV file that I grab & convert it into Stream. I need a way to modify header without converting stream to string. Is there a way around?
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream resStream = response.GetResponseStream();
//need to update stream here & continue with the CSV reader
using (CsvReader csv = new CsvReader(new StreamReader(resStream), true))
{
//other code
}
Derive your own class from StreamReader and override the function you use for reading it, inserting the proper behavior.
Related
i have this C# code for download xlsx document from url
var request = (HttpWebRequest)WebRequest.Create("url to xlsx file");
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
request.Headers[HttpRequestHeader.AcceptEncoding] = "gzip,deflate";
using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
using (var output = File.Create("H:\\doc.xlsx"))
{
stream.CopyTo(output);
}
my target programming language is VB.net so i changed C# to vb like below
Dim request As HttpWebRequest = WebRequest.Create("url to xlsx file")
request.AutomaticDecompression = DecompressionMethods.GZip Or DecompressionMethods.Deflate
request.Headers(HttpRequestHeader.AcceptEncoding) = "gzip,deflate"
Dim response As WebResponse = request.GetResponse()
Dim stream As Stream = response.GetResponseStream()
Dim output As FileStream = File.Create("H:\doc.xlsx")
stream.CopyTo(output)
xlsx file that is downloaded by VB is corrupted and unreadable but C# works well
what is the mistake?
Try including the using statements: It is possible the whole content has not been flushed to the output so you get the corrupt message.
Using response = request.GetResponse()
Using stream = response.GetResponseStream()
Using output = File.Create("H:\doc.xlsx")
stream.CopyTo(output)
End Using
End Using
End Using
The using block will make sure to dispose of the objects, which you should be doing regardless of the issue of ending with a corrupted file, and it will also call Close() method on the underlying to stream and any data previously written to the buffer will be copied to the file before the file stream is closed,
Im trying to create a web service which gets to a URL e.g. www.domain.co.uk/prices.csv and then reads the csv file. Is this possible and how? Ideally without downloading the csv file?
You could use:
public string GetCSV(string url)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
string results = sr.ReadToEnd();
sr.Close();
return results;
}
And then to split it:
public static void SplitCSV()
{
List<string> splitted = new List<string>();
string fileList = getCSV("http://www.google.com");
string[] tempStr;
tempStr = fileList.Split(',');
foreach (string item in tempStr)
{
if (!string.IsNullOrWhiteSpace(item))
{
splitted.Add(item);
}
}
}
Though there are plenty of CSV parsers out there and i would advise against rolling your own. FileHelpers is a good one.
// Download the file to a specified path. Using the WebClient class we can download
// files directly from a provided url, like in this case.
System.Net.WebClient client = new WebClient();
client.DownloadFile(url, csvPath);
Where the url is your site with the csv file and the csvPath is where you want the actual file to go.
In your Web Service you could use the WebClient class to download the file, something like this ( I have not put any exception handling, not any using or Close/Dispose calls, just wanted to give the idea you can use and refine/improve... )
using System.Net;
WebClient webClient = new WebClient();
webClient.DownloadFile("http://www.domain.co.uk/prices.csv");
then you can do anything you like with it once the file content is available in the execution flow of your service.
if you have to return it to the client as return value of the web service call you can either return a DataSet or any other data structure you prefer.
Sebastien Lorion's CSV Reader has a constructor that takes a Stream.
If you decided to use this, your example would become:
void GetCSVFromRemoteUrl(string url)
{
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
using (CsvReader csvReader = new CsvReader(response.GetResponseStream(), true))
{
int fieldCount = csvReader.FieldCount;
string[] headers = csvReader.GetFieldHeaders();
while (csvReader.ReadNextRecord())
{
//Do work with CSV file data here
}
}
}
The ever popular FileHelpers also allows you to read directly from a stream.
The documentation for WebRequest has an example that uses streams. Using a stream allows you to parse the document without storing it all in memory
I want to send a url as query string e.g.
localhost/abc.aspx?url=http:/ /www.site.com/report.pdf
and detect if the above URL returns the PDF file. If it will return PDF then it gets saved automatically otherwise it gives error.
There are some pages that uses Handler to fetch the files so in that case also I want to detect and download the same.
localhost/abc.aspx?url=http:/ /www.site.com/page.aspx?fileId=223344
The above may return a pdf file.
What is best way to capture this?
Thanks
You can download a PDF like this
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
HttpWebResponse response = req.GetResponse();
//check the filetype returned
string contentType = response.ContentType;
if(contentType!=null)
{
splitString = contentType.Split(';');
fileType = splitString[0];
}
//see if its PDF
if(fileType!=null && fileType=="application/pdf"){
Stream stream = response.GetResponseStream();
//save it
using(FileStream fileStream = File.Create(fileFullPath)){
// Initialize the bytes array with the stream length and then fill it with data
byte[] bytesInStream = new byte[stream.Length];
stream.Read(bytesInStream, 0, bytesInStream.Length);
// Use write method to write to the file specified above
fileStream.Write(bytesInStream, 0, bytesInStream.Length);
}
}
response.Close();
The fact that it may come from an .aspx handler doesn't actually matter, it's the mime returned in the server response that is used.
If you are getting a generic mime type, like application/octet-stream then you must use a more heuristical approach.
Assuming you cannot simply use the file extension (eg for .aspx), then you can copy the file to a MemoryStream first (see How to get a MemoryStream from a Stream in .NET?). Once you have a memory stream of the file, you can take a 'cheeky' peek at it (I say cheeky because it's not the correct way to parse a PDF file)
I'm not an expert on PDF format, but I believe reading the first 5 chars with an ASCII reader will yield "%PDF-", so you can identify that with
bool isPDF;
using( StreamReader srAsciiFromStream = new StreamReader(memoryStream,
System.Text.Encoding.ASCII)){
isPDF = srAsciiFromStream.ReadLine().StartsWith("%PDF-");
}
//set the memory stream back to the start so you can save the file
memoryStream.Position = 0;
Okay so let's say I have a program which makes a WebRequest and gets a WebResponse, and uses that WebResponse for a StreamReader in a using statement, which obviously gets disposed of after, but what about the WebResponse stream? For example:
WebResponse response = request.GetResponse();
using(StreamReader reader = new StreamReader(response.GetResponseStream()))
{
x = reader.ReadToEnd();
}
So obviously the StreamReader will get disposed after, and all resources devoted to it, but what about the Response Stream from response? Does that? Or should I do it like this:
WebResponse response = request.GetResponse();
using(Stream stream = response.GetResponseStream())
{
using(StreamReader reader = new StreamReader(stream))
{
x = reader.ReadToEnd();
}
}
Thanks
StreamReader assumes ownership of the Stream that you pass to its constructor. In other words, when you dispose the StreamReader object it will automatically also dispose the Stream object that you passed. That's very convenient and exactly what you want, simplifying the code to:
using (var response = request.GetResponse())
using (var reader = new StreamReader(response.GetResponseStream()))
{
x = reader.ReadToEnd();
}
When I use Visual Studio 2013's Code Analysis, it claims the use of two 'usings' here will cause Dispose() to be called twice on 'response' and will generate a hidden 'System.ObjectDisposedException'?
warning CA2202: Microsoft.Usage : Object 'response' can be disposed
more than once in method 'xxx'. To avoid generating a
System.ObjectDisposedException you should not call Dispose more than
one time on an object.
Has anyone else seen this?
private static void DownloadFile()
{
FtpWebRequest reqFTP;
WebResponse webResponse;
GetTheResponseFromFTP(out reqFTP, out webResponse, true);
FtpWebResponse response = (FtpWebResponse)webResponse;
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
using (StreamWriter streamWriter =
new StreamWriter("d:\\TestUnity.pdf", true))
{
streamWriter.WriteLine(reader.ReadToEnd());
}
reader.Close();
response.Close();
}
I have the above function, that download a file from the FTP location.
I am reading the text and trying to write it in a file in my local machine.
The PDf file generated is of the same size as it is downloaded but when I open the file its blank. Now I have two questions:
Can any one suggest how to save the downloaded file to a path which can be changed.
Whats the reason for the above problem mentioned.
From the documentation.
StreamWriter implements a TextWriter for writing characters to a stream
This means you haven't created a pdf file but a textfile with the *.pdf extension.
There are multiple utilities available to create a pdf
WkHtmlToPDF and ITextSharp are just two
Here is very simple code which works for me
void GeneratePDF(WebResponse response)
{
using (var streamFile = File.Create("E:/JSS.pdf"))
response.GetResponseStream().CopyTo(streamFile);
}