C# write memorystream to file [duplicate] - c#

This question already has answers here:
FileStream.Write not Writing to File
(2 answers)
Closed 2 years ago.
I have an easy function, which should receive Stream object and write it to the file "result.txt"
Here is my function:
public void WriteToFile(Stream stream)
{
StreamReader reader = new StreamReader(stream);
stream.Position = 0;
FileInfo f = new FileInfo("result.txt");
FileStream fs = f.Create();
stream.CopyTo(fs);
stream.Position = 0;
var text = reader.ReadToEnd();
Console.WriteLine(text);
}
But I have an issue with writing to the file. In result - file is empty. But, I receive output in console from this line of code:
var text = reader.ReadToEnd();
Console.WriteLine(text);
In console I get simple and short json output
{"startAt":0,"maxResults":0,"total":472,"issues":[]}
This function works fine with other, larger streams, but this 52 Byte stream just does not want to be written to the file. What am I doing wrong?

you don't need any StreamReader, just do it like this:
public void WriteToFile(Stream stream)
{
stream.Seek(0, SeekOrigin.Begin);
using(var fs = new FileStream("/path/to/file", FileMode.OpenOrCreate))
{
stream.CopyTo(fs);
}
}
//var memoryStream...
//...
WriteFoFile(memoryStream);

You can use something like this:
public void WriteToFile(Stream stream)
{
var writer = new System.IO.StreamWriter("result.txt");
StreamReader reader = new StreamReader(stream);
while ((line = reader.ReadLine()) != null)
{
writer.WriteLine(line);
}
var text = reader.ReadToEnd();
writer.Close();
reader.Close();
Console.WriteLine(text);
}

Related

StreamReader save ReadLine to string and use it in if

Hi I want to save the output from reader.ReadToEnd() to a string and check if the string is "Access" but I don't know how to do it.
string url = "https://mywebsite.com/check.php";
Stream mystream = client.OpenRead(url);
StreamReader reader = new StreamReader(mystream);
Console.WriteLine(reader.ReadToEnd()); //The text will be "Access"
//Pseudecode start
string line = reader.ReadToEnd();
if (line == "Access")
{
useraccess = true;
Console.WriteLine("Done!");
}
mystream.Close();
You are reading the stream twice without any sort of reset, it would be more advisable to read it only once. Also you should be disposing of your stream and streamreader appropriately. See the following:
string url = "https://mywebsite.com/check.php";
string remoteData = null;
using (Stream mystream = client.OpenRead(url))
using (StreamReader reader = new StreamReader(mystream))
remoteData = reader.ReadToEnd();
Console.WriteLine(remoteData); //The text will be "Access"
//Pseudecode start
if (remoteData == "Access")
{
useraccess = true;
Console.WriteLine("Done!");
}
This should work under the assumption that ReadToEnd() is returning what you wanted it to return. I don't know what your endpoint looks like so I can't verify.

How to reset the stream of StreamReader to beginning?

I have referred this Return StreamReader to Beginning, but couldn't figure out this problem.
This is code to read stream of a particular file in zip file. Here there are two stream of files inside two different zip files. Now I need to compare the streams.
I am unable to set the stream of BaseFileReader stream to beginning of stream.
using (FileStream BaseZipToOpen = new FileStream(BaseArchive,FileMode.Open) , CurrentZipToOpen = new FileStream(CurrentArchive,FileMode.Open))
{
using (ZipArchive BaseZip = new ZipArchive(BaseZipToOpen, ZipArchiveMode.Read), CurrentZip = new ZipArchive(CurrentZipToOpen, ZipArchiveMode.Read))
{
ZipArchiveEntry BaseFile = BaseZip.GetEntry(requiredFile);
ZipArchiveEntry CurrentFile = CurrentZip.GetEntry(requiredFile);
using (StreamReader BaseFileReader = new StreamReader(BaseFile.Open()), CurrentFileReader = new StreamReader(CurrentFile.Open()))
{
string baseFileLine, currentFileLine;
while (!CurrentFileReader.EndOfStream)
{
currentFileLine = CurrentFileReader.ReadLine();
while (!BaseFileReader.EndOfStream)
{
baseFileLine = BaseFileReader.ReadLine();
if (!currentFileLine.Equals(baseFileLine))
{
difference = true;
}
else
{
difference = false;
break;
}
}
// how to reset BaseFileReader Stream to beginning?
BaseZipToOpen.Seek(0, SeekOrigin.Begin); //This is not working
}
}
}
}
You can use
FileStream stream = new FileStream();
stream.Position = 0;

Read the content of an xml file within a zip package

I am required to read the contents of an .xml file using the Stream (Here the xml file is existing with in the zip package). Here in the below code, I need to get the file path at runtime (here I have hardcoded the path for reference). Please let me know how to read the file path at run time.
I have tried to use string s =entry.FullName.ToString(); but get the error "Could not find the Path". I have also tried to hard code the path as shown below. however get the same FileNotFound error.
string metaDataContents;
using (var zipStream = new FileStream(#"C:\OB10LinuxShare\TEST1\Temp" + "\\"+zipFileName+".zip", FileMode.Open))
using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Read))
{
foreach (var entry in archive.Entries)
{
if (entry.Name.EndsWith(".xml"))
{
FileInfo metadataFileInfo = new FileInfo(entry.Name);
string metadataFileName = metadataFileInfo.Name.Replace(metadataFileInfo.Extension, String.Empty);
if (String.Compare(zipFileName, metadataFileName, true) == 0)
{
using (var stream = entry.Open())
using (var reader = new StreamReader(stream))
{
metaDataContents = reader.ReadToEnd();
clientProcessLogWriter.WriteToLog(LogWriter.LogLevel.DEBUG, "metaDataContents : " + metaDataContents);
}
}
}
}
}
I have also tried to get the contents of the .xml file using the Stream object as shown below. But here I get the error "Stream was not readable".
Stream metaDataStream = null;
string metaDataContent = string.Empty;
using (Stream stream = entry.Open())
{
metaDataStream = stream;
}
using (var reader = new StreamReader(metaDataStream))
{
metaDataContent = reader.ReadToEnd();
}
Kindly suggest, how to read the contents of the xml with in a zip file using Stream and StreamReader by specifying the file path at run time
Your section code snippet is failing because when you reach the end of the first using statement:
using (Stream stream = entry.Open())
{
metaDataStream = stream;
}
... the stream will be disposed. That's the point of a using statment. You should be fine with this sort of code, but load the XML file while the stream is open:
XDocument doc;
using (Stream stream = entry.Open())
{
doc = XDocument.Load(stream);
}
That's to load it as XML... if you really just want the text, you could use:
string text;
using (Stream stream = entry.Open())
{
using (StreamReader reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
}
Again, note how this is reading before it hits the end of either using statement.
Here is a sample of how to read a zip file using .net 4.5
private void readZipFile(String filePath)
{
String fileContents = "";
try
{
if (System.IO.File.Exists(filePath))
{
System.IO.Compression.ZipArchive apcZipFile = System.IO.Compression.ZipFile.Open(filePath, System.IO.Compression.ZipArchiveMode.Read);
foreach (System.IO.Compression.ZipArchiveEntry entry in apcZipFile.Entries)
{
if (entry.Name.ToUpper().EndsWith(".XML"))
{
System.IO.Compression.ZipArchiveEntry zipEntry = apcZipFile.GetEntry(entry.Name);
using (System.IO.StreamReader sr = new System.IO.StreamReader(zipEntry.Open()))
{
//read the contents into a string
fileContents = sr.ReadToEnd();
}
}
}
}
}
catch (Exception)
{
throw;
}
}

BinaryFile Read to byte[]

I have binary file
BinaryWriter binwriter = new BinaryWriter(File.Open("C:\\temp\\Users.bin", FileMode.Create));
binwriter.Write(buff);
binwriter.Close();
It works, but how can I read data from this file?
I need to read new line each time, while it is not end of file.
BinaryReader binreader = new BinaryReader(File.Open("C:\\temp\\Users.bin", FileMode.Open));
byte[] m = binreader.ReadBytes(??????); //I to read only 1 line to m, and then I need to read again new line to m.
Binary file doesn't have the concept of a "line", however you can try to read it like a text file by doing this way :
using (var streamReader = new StreamReader(filePath))
{
string line;
while ((line = streamReader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
using (StreamReader sr = new StreamReader(path))
{
while (sr.Peek() >= 0)
{
Console.WriteLine(sr.ReadLine());
}
}
you can of course adapt it to your needs instead of printing it on the Console.

How to use WebResponse to Download .wmv file

I'm using the following code to grab a wmv file through a WebResponse. I'm using a thread to call this function:
static void GetPage(object data)
{
// Cast the object to a ThreadInfo
ThreadInfo ti = (ThreadInfo)data;
// Request the URL
WebResponse wr = WebRequest.Create(ti.url).GetResponse();
// Display the value for the Content-Length header
Console.WriteLine(ti.url + ": " + wr.Headers["Content-Length"]);
string toBeSaved = #"C:\Users\Kevin\Downloads\TempFiles" + wr.ResponseUri.PathAndQuery;
StreamWriter streamWriter = new StreamWriter(toBeSaved);
MemoryStream m = new MemoryStream();
Stream receiveStream = wr.GetResponseStream();
using (StreamReader sr = new StreamReader(receiveStream))
{
while (sr.Peek() >= 0)
{
m.WriteByte((byte)sr.Read());
}
streamWriter.Write(sr.ReadToEnd());
sr.Close();
wr.Close();
}
streamWriter.Flush();
streamWriter.Close();
// streamReader.Close();
// Let the parent thread know the process is done
ti.are.Set();
wr.Close();
}
The file seems to download just fine, but Windows Media Viewer cannot open the file properly. Some silly error about not being able to support the file type.
What incredibly easy thing am I missing?
You just need to download it as binary instead of text. Here's a method that should do the trick for you.
public void DownloadFile(string url, string toLocalPath)
{
byte[] result = null;
byte[] buffer = new byte[4097];
WebRequest wr = WebRequest.Create(url);
WebResponse response = wr.GetResponse();
Stream responseStream = response.GetResponseStream;
MemoryStream memoryStream = new MemoryStream();
int count = 0;
do {
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, count);
if (count == 0) {
break;
}
}
while (true);
result = memoryStream.ToArray;
FileStream fs = new FileStream(toLocalPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
fs.Write(result, 0, result.Length);
fs.Close();
memoryStream.Close();
responseStream.Close();
}
I do not understand why you are filling MemoryStream m one byte at a time, but then writing the sr to the file. At that point, I believe the sr is empty, and MemoryStream m is never used.
Below is some code I wrote to do a similar task. It gets a WebResponse in 32K chunks at a time, and dumps it directly to a file.
public void GetStream()
{
// ASSUME: String URL is set to a valid URL.
// ASSUME: String Storage is set to valid filename.
Stream response = WebRequest.Create(URL).GetResponse().GetResponseStream();
using (FileStream fs = File.Create(Storage))
{
Byte[] buffer = new Byte[32*1024];
int read = response.Read(buffer,0,buffer.Length);
while (read > 0)
{
fs.Write(buffer,0,read);
read = response.Read(buffer,0,buffer.Length);
}
}
// NOTE: Various Flush and Close of streams and storage not shown here.
}
You are using a StreamReader and a StreamWriter to transfer your stream, but those classes are for handling text. Your file is binary and chances are that sequences of CR, LF and CR LF may get clobbered when you transfer the data. How NUL characters are handled I have no idea.

Categories