I want to store variables in a .txt file - like I always see in peoples config.txt files, where it's like:
var_name = ['"test url"']
I've got the code below that opens the file and reads it (at the moment just debugging and displays what's in the file, at the moment just 1 variable)
System.IO.StreamReader myFile = new System.IO.StreamReader("C:\\conf\\config.txt");
string myString = myFile.ReadToEnd();
myFile.Close();
MessageBox.Show(myString);
What's in the file is
file_name="C:\\test.txt"
Now I'd like to be able to use that variable in my functions in my VB form. How do I go about doing this? And also, how can I do multiple; so I can have basically a big list of vars that the form loads at launch?
So for example:
// Opens file and reads all variables
// Saves all variables to form
// Can now use varaible in form, e.g. messageBox.Show(file_name);
I'm new to C#, I imagine it's similar to an include but the include is local instead of part of the project.
Disclamer: standard practice (i.e. Settings) usually is the best policy, however the question has been asked and can be asnwered:
I suggest using dictionary, e.g.
Dictionary<String, String> MySettings = File
.ReadLines(#"C:\conf\config.txt")
.ToDictionary(line => line.Substring(0, line.IndexOf('=')).Trim(),
line => line.Substring(line.IndexOf('=') + 1).Trim().Trim('"'));
...
String testUrl = MySettings[var_name];
However, if you prefer "variables" you can try ExpandoObject:
dynamic ExpSettings = new ExpandoObject();
var expandoDic = (IDictionary<string, object>) ExpSettings;
foreach (var pair in MySettings)
expandoDic.Add(pair.Key, pair.Value);
...
String testUrl = ExpSettings.var_name;
I store and load data (or variables) with Json Deserialization/ serialization in c#.
Here is Serialiazation: I make an object (postlist which is an object list) that i want to save in a text file That way:
private void save_file()
{
string path = Directory.GetCurrentDirectory() + #"\list.txt";
string json = JsonConvert.SerializeObject(postlist);
File.WriteAllText(path, json);
Application.Exit();
}
You need to install Newtonsoft.Json: http://www.newtonsoft.com/json
.You can do it with the Nuget tool console.
Don"t forget to use:
using Newtonsoft.Json;
Here is a way to get all your data from the text file, this is the deserialization:
private void read_file_list()
{
string line;
try
{
using (StreamReader sr = new StreamReader("list.txt"))
{
line = sr.ReadToEnd();
}
JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;
postlist = JsonConvert.DeserializeObject<List<Post>>(line, jsonSerializerSettings);
}
catch
{
// catch your exception if you want
}
}
And here is how i store all my text in my object list "postlist".
Newtonsoft is very usefull and easy to use, i mostly use it to get data from api's.
This my first answer I hope it will help you.
Related
I want to write my current state of a game into a JSON file so that once the user comes back they can either resume or start new. I'm creating a hello world to take user input, store it in JSON and load it back in.
I currently can load JsonObject very quickly using this method
public JObject GetJsonData(string jsonFileName, string dirNameJsonLivesIn)
{
if (string.IsNullOrEmpty(jsonFileName))
throw new ArgumentNullException(jsonFileName);
var assembly = typeof(MainPage).GetTypeInfo().Assembly;
var defaultPath = $"{assembly.GetName().Name}.{jsonFileName}";
var extendedPath = $"{assembly.GetName().Name}.{dirNameJsonLivesIn}.{jsonFileName}";
if (string.IsNullOrEmpty(dirNameJsonLivesIn))
extendedPath = defaultPath;
Stream stream = assembly.GetManifestResourceStream(extendedPath);
using (var reader = new StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
return JObject.Parse(jsonString);
}
}
With this method, I can access objects with ["strings"] just like python does very easily and painlessly.
Problem accures when I try to write to the file. I get an error Access denied... I have given permission on the manifest for Write_External_Files or something along the line. Still get the same error. I've also done some research and there has been a few line of code which people recommended to add to the MainActivity.cs but that didn't work either.
Using this method to write file
private void StoreData_Clicked(object sender, EventArgs e)
{
var jsonFileName = "Statefile.json";
var text = entryBox.Text;
var state = new Dictionary<string, string>();
var assembly = typeof(MainPage).GetTypeInfo().Assembly;
var defaultPath = $"{assembly.GetName().Name}.{jsonFileName}";
state.Add("CurrentState", text);
var json = JsonConvert.SerializeObject(state, Formatting.Indented);
File.WriteAllText(defaultPath, json);
}
Could someone explain why this is happening? Why do I have the ability to read the external_resources but not write to them? Oh yeah, I have set my properties to Embedded Resource and also Always Copy.
Update - Error
System.UnauthorizedAccessException
Message=Access to the path "/HelloWorldXamarin.Statefile.json" is denied.
I'm trying to make a game within my Discord Bot where it is wholly based on Dokkan Battle, the user creates their own passive and the command can view some stats based on what they inputted.
What I'm trying to do is take this data and store it in a JSON file but the way I have it laid out I want it to write it all in one category like this so then it'll be easier to search for specific passives to display
{
"userPassiveStorage": "Storage for user created passives using /passivecreator",
"members": [
{
"passiveName": "",
"leaderName": "",
"unitHP":,
"unitATK":,
"unitDEF":,
"leaderValue":,
"passiveATK":,
"passiveDEF":,
"supportBuff":,
"links": "",
}
]
}
The way I have it done its not writing to the JSON file in the correct format, but instead stores it all as one line
public void StoreUserPassives(DokkanUserPassiveBuilder classObj)
{
using (StreamWriter sw = new StreamWriter("UserPassivesStorage.json"))
{
JsonSerializer serializer = new JsonSerializer();
List<DokkanUserPassiveBuilder> data = new List<DokkanUserPassiveBuilder>();
data.Add(classObj);
string json = JsonConvert.SerializeObject(data.ToArray(), Formatting.Indented);
serializer.Serialize(sw, json);
}
}
So I just need to know how can I add write another member to this category with the same properties as I showed in that JSON file
If there is an easier way rather than using categories I would like to know if that is an easier way since I just need a way to store each passive information and it needs to be easy to search
you are serializing twice. Try this code
var path = #"UserPassivesStorage.json";
var json = File.ReadAllText(path);
var jsonObj = JObject.Parse(json);
var members = jsonObj["members"].ToObject<List<DokkanUserPassiveBuilder>>();
members.Add(classObj);
jsonObj["members"] = JArray.FromObject(members);
File.WriteAllText(path, jsonObj.ToString());
I am building an application in C# that has a textbox field. In this field, a user will write text and the text will autocomplete from a file found on a remote repository. I am using a library called SharpSVN and I am trying to find a method where I can fetch that file from the repository based on a certain path I provide, then parse the content into strings that will be added to the list in the autocomplete of the textbox mentioned previously.
There are two ways:
Download the file text using the repository url. If you want the file at a specific revision, try entering in "?r=12345" as to get the file's appearance at a specific revision number:
string fileText = new WebClient().DownloadFile("https://myrepo.com/myfile.txt", localFilename);
Or, you could also use SharpSVN, removing the revision options if you want the latest version:
public string GetFileContentsAsString(long revisionNumber)
{
return new StreamReader(GetFileContents(revisionNumber)).ReadToEnd();
}
private MemoryStream GetFileContents(long revisionNumber)
{
SvnRevision rev = new SvnRevision(revisionNumber);
MemoryStream stream = new MemoryStream();
using (SvnClient client = GetClient())
{
client.FileVersions(SvnTarget.FromUri(RemotePath), new SvnFileVersionsArgs() { Start = rev, End = rev }, (s, e) =>
{
e.WriteTo(stream);
});
}
stream.Position = 0;
return stream;
}
When you have the file as a text string, you can use .NET's String.Split() method to split the text into a list of lines using the '\n' line-break character as the delimiter:
string[] fileAsLines = fileText.Split(new char[] {'\n'});
I have a group of delimited text files I need to read, create a class and objects, and store members inside. I am a beginner that's just looking to be pointed in the right direction. Any help would be appreciated greatly. Thank you very much.
I made a class with objects with:
public string left;
public string right;
and my form code :
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog of = new OpenFileDialog();
of.ShowDialog();
textBox1.Text = of.FileName;
}
private void button2_Click(object sender, EventArgs e)
{
StreamReader sr = new StreamReader(textBox1.Text);
textBox2.Text = sr.ReadToEnd();
// sr.Close();
}
private void button3_Click(object sender, EventArgs e)
{
string[] split1 = textBox2.Text.Split(';');
foreach (string segment in split1)
{
//split sub-segment
string[] split2 = segment.Split(':');
//check if it's valid
if (split2.Count().Equals(2))
{
id textfile = new id();
textfile.left += // ????
id textfile1 = new id();
textfile.right += // ????
Generally, it's much preferable to use JSON or XML to save data to text files rather than delimited text or custom formats. That's because good JSON and XML support is available in my languages and it's easy to work with.
public class MyCustomClass //this class will hold your data
{
public string Left {get; set;}
public string Right {get;set;}
}
MyCustomClass mcc=new MyCustomClass(); //create an instance of your class
mcc.Left="yes"; //set some properties
mcc.Right="nope";
string json=JsonConvert.SerializeObject(mcc); //convert to JSON string
File.WriteAllText("mcc.txt",json); //save to file
//later on, when you want to read it back from the file
string json=File.ReadAllText("mcc.text"); //read from file into a string
MyCustomClass mcc=JsonConvert.DeserializeObject<MyCustomClass>(json); //convert the string back to an instance of MyCustomClass
Above, we use Json.NET which is a library available for the .NET Framework (available on NuGet). We use it to convert our object to a string (serialize) and then later on to convert it back to an object (deserialize). Note that in order to use the JsonConvert class, you'll need the Json.NET references and to add a using statement at the top of your class using Newtonsoft.Json;.
What you're looking for is serialization. When you have a known structure (like your class with string left and string right), you want to write that structure out to a text file. Then later, you want to read that information back in and automatically populate the class with each of the values.
As mason pointed out, JSON is fairly easy to setup. You create the class structure that you want, and tell JSON to save that out to a specified file (via SerializeObject).
Since .NET allows for reflection, JSON is able to turn the text file back into the contents of a class without you having to manually 'myClass.left = [some_value_from_json]'.
Personally, I'd go with JSON or XML, since naming your blocks of data means it is both more readable, and that your parser is able to handle someone rearranging the data (it doesn't matter if the file defines left before it defines right). If you rearranged a .CSV file, then you get data corruption.
Reading delimited files is common and there are many approaches to the subject. Personally I use a streamReader to read in the file and split it on the delimiter:
Foo foo = new Foo(); // custom class
string file = "export.CSV";
if (System.IO.File.Exists(file))
{
// Do work
using (var reader = new StreamReader(file))
{
while (!reader.EndOfStream)
{
// split on the delimeter
var readLine = reader.ReadLine();
if (readLine == null) continue;
var lines = readLine.Split(new[] { ',' });
foreach (string s in lines)
{
// do something with the data from the line
}
// alternatively, you could specify your objects if your files
// layout never changes. Just be careful to catch the exceptions!
foo.bar = lines[0];
foo.baz = lines[1];
}
}
}
I'm just being stupid here...thought this would be simple but got befuddled with my various attempts to make this work and all my online searches yielded nothing.
The first function (see below) is one of several that specifically serialize one type of object to an xml file and it works fine. I'm trying to consolidate/refactor because I have 3 objects so I have 6 functions - 3 to read and 3 to write the objects. I want to generalize and then move my functions into my business objects layer. So when I try to generalize it, I need to pass in the object as an unknown type and then handle that. In the first function, the type is known and like I said that works. So the second function (below) shows my latest attempt to generalize but I'm not doing it right. I want to pass in the object and the file path...
private void ReadEmailConfigurationXML()
{
XmlSerializer serializer = new XmlSerializer(typeof(EmailConfiguration));
System.IO.StreamReader file = new System.IO.StreamReader(DataFilePath + "Data/EmailConfiguration.xml");
EmailConfig = (EmailConfiguration)serializer.Deserialize(file);
file.Close();
}
private void ReadXMLFile(ref Object obj, string fullPath)
{
XmlSerializer serializer = new XmlSerializer(typeof(obj));
System.IO.StreamReader file = new System.IO.StreamReader(fullPath);
obj = (typeof(obj))serializer.Deserialize(file);
file.Close();
}
Use generics to handle the different types:
private T ReadXMLFile<T>(string fullPath) {
XmlSerializer serializer = new XmlSerializer(typeof(T));
System.IO.StreamReader file = new System.IO.StreamReader(fullPath);
T obj = (T)serializer.Deserialize(file);
file.Close();
return obj;
}
Usage:
EmailConfiguration conf =
ReadXMLFile<EmailConfiguration>(DataFilePath + "Data/EmailConfiguration.xml");