New StreamReader class doesn't accept filename - c#

I have been trying to get out a demo for MVC 6.0 and I find that I can't read a file anymore using StreamReader class as it doesn't accept a string anymore.
So code like this
StreamReader reader= new StreamReader("filename.txt")
is not valid?
I am using .NET Core 1.0

I think they've removed it as a StreamReader shouldn't be responsible for creating streams - it's a violation of the Single Responsibility Principle.
You'll need to create a FileStream or similar in order to get the same functionality
using (var stream = new FileStream(#"C:\temp\test.txt", FileMode.Open))
using (var reader = new StreamReader(stream))
{
// do stuff.
}

Related

ZipArchive, update entry: read - truncate - write

I'm using System.IO.Compression's ZipArchive to modify a file within a ZIP. I need first to read the whole content (JSON), transform the JSON then truncate the file and write the new JSON to the file. At the moment I have the following code:
using (var zip = new ZipArchive(new FileStream(zipFilePath, FileMode.Open, FileAccess.ReadWrite), ZipArchiveMode.Update))
{
using var stream = zip.GetEntry(entryName).Open();
using var reader = new StreamReader(stream);
using var jsonTextReader = new JsonTextReader(reader);
var json = JObject.Load(jsonTextReader);
PerformModifications(json);
stream.Seek(0, SeekOrigin.Begin);
using var writer = new StreamWriter(stream);
using var jsonTextWriter = new JsonTextWriter(writer);
json.WriteTo(jsonTextWriter);
}
However, the problem is: if the resulting JSON is shorter than the original version, the remainder of the original is not truncated. Therefore I need to properly truncate the file before writing to it.
How to truncate the entry before writing to it?
You can either delete the entry before writing it back or, which I prefer, use stream.SetLength(0) to truncate the stream before writing. (See also https://stackoverflow.com/a/46810781/62838.)

Extra bytes using FileStream (or so it seems)

I am writing some JSON directly to a file, which is then read at a later date. The JSON is then deserialized using newton into an object.
I was initially do the writing like so and it was working fine:
using (var sw = File.CreateText(jsonFile))
{
sw.Write(content);
}
I then ran into a race condition and I was told to go this route instead
using (var fs = new FileStream(jsonFile, FileMode.Open, FileAccess.Write,
FileShare.ReadWrite))
{
using (var sr = new StreamWriter(fs))
{
sr.Write(content);
}
}
But when deserializing the JSON, I got this this message
Newtonsoft.Json.JsonReaderException: Additional text encountered after finished reading JSON content: u. Path ''
When I added encoding to the StreamWriter (UTF8), I got the same message but a different character.
So as a suggestion from a comment I tried this for the streamwriter for the encoding to remove the BOM
var utf8WithoutBom = new System.Text.UTF8Encoding(false);
Then added it to the streamwriter. The same error was returned but this time the character was blank.
Using jsonlint the JSON (content) that was written validates correctly using both methods above.
Does anyone know why the second method (using FileStream) doesn't work? And if so, do you have a suggestion on what I should do instead?

ArgumentException in StreamWriter in Xamarin.Forms

I am writing a Xamarin.Form PLC for Android and iOS, and have a place where I need to write some application stuff to a text file embedded resource. I've implemented reading from the same text file successfully, with same syntax just using StreamReader, but the StreamWriter implementation looks like this:
Assembly assembly = GetType().GetTypeInfo().Assembly;
string resource = "jetStream.Results.settings.txt";
using (Stream stream = assembly.GetManifestResourceStream(resource)) {
using (StreamWriter writer = new StreamWriter(stream)) {
//do stuff
}
}
StreamWriter is throwing an argument of "Stream is not writeable" at System.IO.StreamWriter. Am I doing something obvsiously wrong? Why is the Stream Readable but not Writeable using the same assembly/resource/stream construction?
The stream from GetManifestResourceStream is not writable. The stream's file is embedded in the assembly at build time and cannot be changed. You'll have to write the file to disk before you can write to it.
string resource = "jetStream.Results.settings.txt";
using (Stream stream = assembly.GetManifestResourceStream(resource))
using (var fs = new FileStream(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal)), FileMode.Create, FileAccess.Write))
using (var stream = new MemoryStream())
using (var writer = new StreamWriter(fs))
{
rStream.Stream.CopyTo(stream);
writer.Write(stream.ToArray());
}
After this you can read and write to the file on disk.
Depending on what you want to write, if it's just things like application settings, you can use the Application.Properties collection http://www.kymphillpotts.com/exploring-xamarin-forms-1-3-properties-dictionary/ otherwise I agree with Jon's answer.

Can stacked using be combined into one using statement? [duplicate]

This question already has answers here:
Using various types in a 'using' statement (C#)
(4 answers)
Closed 8 years ago.
I have a method that returns like this:
using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream))
return reader.ReadToEnd();
Can I combine the three usings like this and have the same level of safety?
using (var reader = new StreamReader(request.GetResponse().GetResponseStream()))
return reader.ReadToEnd();
Or since this is inside a privately scoped function, can I return safely without a using?
return new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
The object that contains this method is not IDisposable. I'm guessing no to both my questions but I am curious on other viewpoints.
For the general case, you can't make this assumption. For your specific case, some consolidation is possible. In particular, disposing the StreamReader will also close the underlying stream, because the documentation for StreamReader.Close() makes this guarantee:
Closes the StreamReader object and the underlying stream
(Emphasis mine). Therefore, you can skip middle using block from your sample. However, the same guarantee is not made from the Stream to the HttpResponse object, meaning you still want to keep that. So you can do this:
using (var response = request.GetResponse())
using (var reader = new StreamReader(response.GetResponseStream()))
return reader.ReadToEnd();
Additionally, there is one other situation where you can combine stacked using blocks into a single block. When all of the items managed by the using blocks are of the same type, you can separate each object with a comma. For example, opening one file for reading and processing the output to another file can be done like this:
using (var infile = new FileStream("infile"), outfile = new FileStream("outfile"))
{
//...
}
In general, you need the separate statements to ensure that everything gets cleaned up properly:
using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream))
return reader.ReadToEnd();
Otherwise, an error partway through might leave resources undisposed. E.g. if GetResponseStream() threw an exception in this code, you'd end up with an undisposed response:
using (var reader = new StreamReader(request.GetResponse().GetResponseStream()))
return reader.ReadToEnd();

Rename File in IsolatedStorage

I need to rename a file in the IsolatedStorage. How can I do that?
There doesn't appear to anyway in native C# to do it (there might be in native Win32, but I don't know).
What you could do is open the existing file and copy it to a new file and delete the old one. It would be slow compared to a move, but it might be only way.
var oldName = "file.old"; var newName = "file.new";
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (var readStream = new IsolatedStorageFileStream(oldName, FileMode.Open, store))
using (var writeStream = new IsolatedStorageFileStream(newName, FileMode.Create, store))
using (var reader = new StreamReader(readStream))
using (var writer = new StreamWriter(writeStream))
{
writer.Write(reader.ReadToEnd());
}
In addition to the copy to a new file, then delete the old file method, starting with Silverlight 4 and .NET Framework v4, IsolatedStorageFile exposes MoveFile and MoveDirectory methods.
Perfectly execute this piece of code
string oldName="oldName";
string newName="newName";
var file = await ApplicationData.Current.LocalFolder.GetFileAsync(oldName);
await file.RenameAsync(newName);

Categories