why should I do when Stream.CanSeek is false - c#

I use this code to capture an image from IP Camera:
HttpWebRequest reqs = (HttpWebRequest)WebRequest.Create("http://" + ip + snapshotCommand);
reqs.Method = "POST";
reqs.Timeout = 4000;
reqs.Credentials = new NetworkCredential(user, pass);
reqs.PreAuthenticate = true;
HttpWebResponse resp = (HttpWebResponse)reqs.GetResponse();
if (resp != null)
{
Stream stm = resp.GetResponseStream();
img = new Bitmap(stm);
stm.Close();
}
But stream threw an exception because CanSeek & CanWrite is false.
I tried many ways, for example Copyto (MemoryStream), but the problem still persists.
Would you please help me on that?
This is the code using MemoryStream:
Stream stm = resp.GetResponseStream();
MemoryStream ms = new MemoryStream();
stm.CopyTo(ms);
ms.Position = 0;
And this "ms" for ReadTimeout & WriteTimeout threw:
Message "Timeouts are not supported on this stream."
Because canTimeout() is false for MemoryStream too.
Finally I found this solution, and it works well:
https://stackoverflow.com/a/2368505/492628

You should be able to copy the stream into a memory stream if it isn't seekable
Here's a post that might help.

Related

Exporting byte[] results to corrupted .zip

I am trying to make a CLR with .NET 2.0 integrated into MS SQL Server 2008. I call an API with and I should receive a .zip as response. I store the response into a Stream and I want to export this file to a physical .zip file.
I tried exporting the file with C# and SQL (BCB OR OLE) and all resulted into a corrupted file. So, I believe I am doing something wrong with in the making of the stream.
The C# code is the following:
private static byte[] GetStreamFileResult(Cookie loginCookie, Guid fileGuid, String baseUri)
{
byte[] output = null;
//String result = null;
string url = "some url"
CookieContainer cookies = new CookieContainer();
cookies.Add(new Uri(url), loginCookie);
WebRequest request = WebRequest.Create(url);
(request as HttpWebRequest).CookieContainer = cookies;
WebResponse response = request.GetResponse();
HttpWebResponse resp = response as HttpWebResponse;
Stream dataStream = response.GetResponseStream();
using (MemoryStream ms = new MemoryStream())
{
CopyStream(dataStream, ms);
output = ms.ToArray();
}
dataStream.Close();
response.Close();
return output;
}
The C# code to export the zip is the following:
File.WriteAllBytes("C:\\folder\\t.zip", stream); // Requires System.IO
The copy from stream to stream:
public static void CopyStream(Stream input, Stream output)
{
if (input != null)
{
using (StreamReader reader = new StreamReader(input))
using (StreamWriter writer = new StreamWriter(output))
{
writer.Write(reader.ReadToEnd());
}
}
}
Your CopyStream is broken. You need to talk binary. You're currently treating binary zip data as though it were text:
byte[] buffer = new byte[2048];
int bytesRead;
while((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0) {
output.Write(buffer, 0, bytesRead);
}

C# Google Speech api v2 returning empty string

I had the google speech v2 API working perfectly fine about a week ago and it was returning results with no problems however testing it today with the same .flac file keeps returning "{\"result\":[]}" no matter what I try. Wondering if
A) Anyone else is having this problem or
B) Anyone has a solution to my problem
my code is below thanks!
public static String gvoice ()
{
//set the input file name
FileStream fileStream = File.OpenRead(#"test1.flac");
MemoryStream memoryStream = new MemoryStream();
memoryStream.SetLength(fileStream.Length);
fileStream.Read(memoryStream.GetBuffer(), 0, (int)fileStream.Length);
byte[] BA_AudioFile = memoryStream.GetBuffer();
HttpWebRequest _HWR_SpeechToText = null;
//this points to the google speech API (key goes at end after &key=)
_HWR_SpeechToText =
(HttpWebRequest)HttpWebRequest.Create(
"https://www.google.com/speech-api/v2/recognize?output=json&lang=en-us&key=" + key);
_HWR_SpeechToText.Credentials = CredentialCache.DefaultCredentials;
_HWR_SpeechToText.Method = "POST";
//sets kMhz and file type (flac)
_HWR_SpeechToText.ContentType = "audio/x-flac; rate=44100";
_HWR_SpeechToText.ContentLength = BA_AudioFile.Length;
Stream stream = _HWR_SpeechToText.GetRequestStream();
stream.Write(BA_AudioFile, 0, BA_AudioFile.Length);
stream.Close();
HttpWebResponse HWR_Response = (HttpWebResponse)_HWR_SpeechToText.GetResponse();
if (HWR_Response.StatusCode == HttpStatusCode.OK)
{
StreamReader SR_Response = new StreamReader(HWR_Response.GetResponseStream());
string result = SR_Response.ReadToEnd();
return result;
}
else
{
return "error";
}
}
The requirements for the sound file have changed. It should be a MONO Flac file at 16000 rate
A) Anyone else is having this problem
Sure, Google impose usage limits on the API which makes it less practical than you might think.
or B) Anyone has a solution to my problem my code is below thanks!
Use other API's, there are many of them.

Get dynamically generated image into win form

I am trying to get an image via HttpWebRequest and show it in the win form imagebox. While tracking the request via Fiddler ImageView tab I can see that image can be seen correctly but while reading the stream I got Stream was not readable error on
Image img = Image.FromStream(stream).
What am I missing?
HttpWebRequest req = HttpWebRequest request = (HttpWebRequest)WebRequest.Create("[URL here]");
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
Stream stream = response.GetResponseStream();
Image img = Image.FromStream(stream); // ERROR occurs here
stream.Close();
After some digging found an answer here C# gif Image to MemoryStream and back (lose animation):
HttpWebRequest req = HttpWebRequest request = (HttpWebRequest)WebRequest.Create("[URL here]");
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
Stream stream = response.GetResponseStream();
MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
memoryStream.Position = 0;
stream = memoryStream;
Image img = Image.FromStream(stream);
stream.Close();

How do i buffer an image from external link

I have a external link with an image which i want to stream, but i get this error when i try.
error
"URI formats are not supported."
I tried to stream:
Stream fileStream = new FileStream("http://www.lokeshdhakar.com/projects/lightbox2/images/image-2.jpg", FileMode.Open);
byte[] fileContent = new byte[fileStream.Length];
can anyone put some light on this.
Thanks
The FileStream contructor you are using must be provided with a path on your local harddrive and not with an external URL.
You are probably looking for this:
string url = "http://www.lokeshdhakar.com/projects/lightbox2/images/image-2.jpg";
HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
HttpWebResponse httpWebReponse = (HttpWebResponse)httpWebRequest.GetResponse();
Stream stream = httpWebReponse.GetResponseStream();
Probably also for this:
Image pic = Image.FromStream(stream);
MemoryStream ms = new MemoryStream();
pic.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
Byte[] arr = ms.ToArray();
FileStream doesn't support the opening files over the internet.
Try this:
var webClient = new WebClient();
using(var fileStream = webClient.OpenRead("http://www.lokeshdhakar.com/projects/lightbox2/images/image-2.jpg"))
{
byte[] fileContent = new byte[fileStream.Length];
}

How can I read an Http response stream twice in C#?

I am trying to read an Http response stream twice via the following:
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
stream = response.GetResponseStream();
RssReader reader = new RssReader(stream);
do
{
element = reader.Read();
if (element is RssChannel)
{
feed.Channels.Add((RssChannel)element);
}
} while (element != null);
StreamReader sr = new StreamReader(stream);
feed._FeedRawData = sr.ReadToEnd();
However when the StreamReader code executes there is no data returned because the stream has now reached the end. I tried to reset the stream via stream.Position = 0 but this throws an exception (I think because the stream can't have its position changed manually).
Basically, I would like to parse the stream for XML and have access to the raw data (in string format).
Any ideas?
Copy it into a new MemoryStream first. Then you can re-read the MemoryStream as many times as you like:
Stream responseStream = CopyAndClose(resp.GetResponseStream());
// Do something with the stream
responseStream.Position = 0;
// Do something with the stream again
private static Stream CopyAndClose(Stream inputStream)
{
const int readSize = 256;
byte[] buffer = new byte[readSize];
MemoryStream ms = new MemoryStream();
int count = inputStream.Read(buffer, 0, readSize);
while (count > 0)
{
ms.Write(buffer, 0, count);
count = inputStream.Read(buffer, 0, readSize);
}
ms.Position = 0;
inputStream.Close();
return ms;
}
Copying the stream to a MemoryStream as suggested by Iain is the right approach. But since
.NET Framework 4 (released 2010) we have Stream.CopyTo. Example from the docs:
// Create the streams.
MemoryStream destination = new MemoryStream();
using (FileStream source = File.Open(#"c:\temp\data.dat",
FileMode.Open))
{
Console.WriteLine("Source length: {0}", source.Length.ToString());
// Copy source to destination.
source.CopyTo(destination);
}
Console.WriteLine("Destination length: {0}", destination.Length.ToString());
Afterwards you can read destination as many times as you like:
// re-set to beginning and convert stream to string
destination.Position = 0;
StreamReader streamReader = new StreamReader(destination);
string text = streamReader.ReadToEnd();
// re-set to beginning and read again
destination.Position = 0;
RssReader cssReader = new RssReader(destination);
(I have seen Endy's comment but since it is an appropriate, current answer, it should have its own answer entry.)
have you tried resetting the stream position?
if this does not work you can copy the stream to a MemoryStream and there you can reset the position (i.e. to 0) as often as you want.

Categories

Resources