I would like to like the WPF application saves time similar to the one in the rankings. Time and number of attempts is not a problem to list but the problem occurs when I want to sort it in a text file. The user will be able to turn on the leaderboard in a text file as well as when the application is completed, the chart (text file) will open and show the user's time.
private void writeText(string strPath, TimeSpan tsDuration)
{
using (StreamWriter str = new StreamWriter(strPath, true))
{
str.WriteLine(tsDuration / suma);
//duration= time of the game
//suma= number of attempts
}
}
readonly string path = #"C:\Users\info\Desktop\žebříček.txt";
TimeSpan duration = TimeSpan.FromMilliseconds(mt.ElapsedMilliseconds);//this is from other methods
The picture is seen as it is stored now:
But I would like it to be stored like this, and the other attempts were sorted by the value of time:
Each time the application is completed, the user's new time should be sorted by how fast it was.
I will be happy for any advice
Thank you
I'm sure there are much smarter ways of achieving the same result but a very simple way would be to:
Read the contents of the file
Assign the contents to a list
Append your value to the list
Use linq to order the list accordingly
Write the list back to the file
Example:
using System.Collections.Generic;
using System.IO;
using System.Linq;
private void WriteText(string strPath, TimeSpan tsDuration)
{
//Create new list of type 'TimeSpan'
var list = new List<TimeSpan>();
//Read the contents of the file and assign to list
string line;
using (var sr = new StreamReader(strPath))
{
while ((line = sr.ReadLine()) != null)
{
list.Add(TimeSpan.Parse(line));
}
}
//Add your time value to the list
list.Add(tsDuration);
//Order the list in descending order - use OrderBy for ascending
list.OrderByDescending(i => i);
//Write contents back to file - note: append = false
using StreamWriter str = new StreamWriter(strPath, false);
foreach (var item in list)
{
str.WriteLine(item);
}
}
readonly string path = #"C:\Users\info\Desktop\žebříček.txt";
TimeSpan duration = TimeSpan.FromMilliseconds(mt.ElapsedMilliseconds);//this is from other methods
Related
I am writing a program where I have 2 listboxes with the same data but the one listbox items are update with the student name and their TOTAL score and the other with the student name and each individual judge score next to the student name. Everything is going good so far but now I am stuck... I have two methods Save() and SaveAs() where Save() automatically writes data to "FormData.bin" and SaveAs() lets the user enter their own file name.
Is it possible to re-write the Save() method so that when I click save it saves the current data to the file that is open like in MS Word when you are typing in document and just click save to add new typed data to current file. Here is my Save() method I wrote.
public void SaveEntry()
{
int itemsCount = Math.Min(lstbxStudents.Items.Count, lstbxStudentScore.Items.Count);
saveFileDialog1.InitialDirectory = Application.StartupPath;
saveFileDialog1.FileName = "FormData.bin";
{
try
{
using (FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.Create))
using (BinaryWriter Save = new BinaryWriter(fs))
{
Save.Write(cmbbxAge.Text);
Save.Write(cmbbxBelt.Text);
Save.Write(cmbbxCategorie.Text);
Save.Write(cmbbxGender.Text);
Save.Write(cmbbxGup.Text);
Save.Write(txtJudge1.Text);
Save.Write(txtJudge2.Text);
Save.Write(txtJudge3.Text);
Save.Write(txtJudge4.Text);
Save.Write(txtJudge5.Text);
Save.Write(txtOperator.Text);
Save.Write(txtPos1.Text);
Save.Write(txtPos2.Text);
Save.Write(txtPos3.Text);
Save.Write(txtPos4.Text);
Save.Write(txtPos5.Text);
for (int i = 0; i < itemsCount; i++)
{
Save.Write(lstbxStudents.Items[i].ToString());
Save.Write(lstbxStudentScore.Items[i].ToString());
}
Save.Close();
fs.Close();
}
}
catch (Exception error)
{
MessageBox.Show(error.Message, "CTSD Forms");
}
}
}
Thank you in advance
Here is image of Form
Window Form
If I understood correctly what you are trying to achieve is to append text rather than overwrite it. Take a look upon the StreamWriter class that also allows to specify if you want to append the data or not when constructing the instance. It also allows to create/append to the file directly, without the need of a Stream.
Also, consider using proper names for variables:
Save is an action, not an object. writer would be better.
By using Write in the way you showed in your code, you will end with all the texts appended with no separators. You should consider using WriteLine functions.
[edit upon clarifications]
SaveEntry should take a parameter to specify if save is done as SaveAs or Save. First save should always be a SaveAs. Also filename should be saved in the context (your form class, but it is better to have a "view model")
private String _currentFileName;
public void SaveEntry(bool saveAs)
{
if (saveAs || String.IsNullOrEmpty(_currentFileName))
{
saveFileDialog1.InitialDirectory = Application.StartupPath;
saveFileDialog1.FileName = "FormData.bin";
var result = saveFileDialog1.ShowDialog();
// TODO: handle user cancellation
_currentFileName = saveFileDialog1.FileName;
}
using (var writer = new StreamWriter(_currentFileName))
{
// TODO: do stuff with your writer
}
}
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 some code that will load full file names (ex.F:\logs\1234.log) into a listbox depending on the directory the user chooses. When the user selects one or more of the files and clicks the output button, I want the code to read through each selected file. Before, I was using a combobox and the code:
StreamReader sr = new StreamReader(comboBox1.Text);
This obviously does not work for listboxes. What is the simplest way to have the program read the user selected file(s) from the listbox?
To access all selected items in a ListBox you can use the SelectedItems property:
foreach (string value in listBox1.SelectedItems)
{
StreamReader sr = new StreamReader(value);
...
}
If you are choocing one file per time to open, then a solution would be as follows:
string[] files = Directory.GetFiles(#"C:\");
listBox1.Items.Clear();
listBox1.Items.AddRange(files);
Then, to get to the file path selected:
if (listBox1.SelectedIndex >= 0)
{ // if there is no selectedIndex, property listBox1.SelectedIndex == -1
string file = files[listBox1.SelectedIndex];
FileStream fs = new FileStream(file, FileMode.Open);
// ..
}
What you can do it to create a generic list, which will hold all the text from selected files:
void GetTextFromSelectedFiles()
{
List<string> selectedFilesContent = new List<string>();
for (int i = 0; i < listBox1.SelectedItems.Count; i++)
{
selectedFilesContent.Add(ReadFileContent(listBox1.SelectedItems.ToString()));
}
//when the loop is done, the list<T> holds all the text from selected files!
}
private string ReadFileContent(string path)
{
return File.ReadAllText(path);
}
I think in your example when you explicitly said "as simple as possible" to read the file, would be best to use File.ReadAllText() method, better then using StreamReader class.
You should have been more clear in your original question... but if you need to read all the files:
var items = listBox.SelectedItems;
foreach (var item in items)
{
string fileName = listBox.GetItemText(item);
string fileContents = System.IO.File.ReadAllText(fileName);
//Do something with the file contents
}
I need to perform the following operations with a text file and a List:
Read all lines of text file (non delimited) into a string based list
Whilst the application is open I need to do the following:
Check for instances of a string in the List
Add new entries to the List
Remove all identical instances of a defined string from the List
Write the contents of the List back to the text file including any changes made as soon as they are made
Firstly, how do I read and write between Lists and text files?
Secondly, how do I search a List for a string?
Lastly, how do I safely remove an item out of a List without leaving gaps in the text file I write?
public void homework()
{
string filePath = #"E:\test.txt";
string stringToAdd = "test_new";
IList readLines = new List();
// Read the file line-wise into List
using(var streamReader = new StreamReader(filePath, Encoding.Default))
{
while(!streamReader.EndOfStream)
{
readLines.Add(streamReader.ReadLine());
}
}
// If list contains stringToAdd then remove all its instances from the list; otherwise add stringToAdd to the list
if (readLines.Contains(stringToAdd))
{
readLines.Remove(stringToAdd);
}
else
{
readLines.Add(stringToAdd);
}
// Write the modified list to the file
using (var streamWriter = new StreamWriter(filePath, false, Encoding.Default))
{
foreach(string line in readLines)
{
streamWriter.WriteLine(line);
}
}
}
Try to google before you post the question.
I'd start here:
Read from text file: http://dotnetperls.com/readline
List Actions
1. Removing from a list
2. Searching in a List
Write to a text file: http://www.csharp-station.com/HowTo/ReadWriteTextFile.aspx
I'll just share my idea...
using System.IO;
public void newMethod()
{
//get path of the textfile
string textToEdit = #"D:\textfile.txt";
//read all lines of text
List<string> allLines = File.ReadAllLines(textToEdit).ToList();
//from Devendra's answer
if (allLines.Contains(stringToAdd))
{
allLines.Remove(stringToAdd);
}
else
{
allLines.Add(stringToAdd);
}
//extra: get index and edit
int i = allLines.FindIndex(stringToEdit => stringToEdit.Contains("need to edit")) ;
allLines[i] = "edit";
//save all lines
File.WriteAllLines(textToEdit, allLines.ToArray());
}
Hi all i write a code to write my last row of datagrid view to a file as follows
private void Save_Click(object sender, EventArgs e)
{
if (dataGridView1.Rows.Count > 0)
{
List<string> lstContent = new List<string>();
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if ((string)row.Cells[0].Value == "FileControl")
{
lstContent.Add((string)row.Cells[1].Value);
string mydata = string.Join(",", lstContent.ToArray());
using (StreamWriter sw = new StreamWriter(Append.FileName, true))
{
sw.WriteLine();
sw.Write(mydata);
}
}
}
}
}
But if i click multiple times on save this is writing that line multiple times what i need is if already that line exists in the file i have to replace that line with new line. Any help please
Your StreamWriter is explicitly using the file with append = true. Change the second parameter of the constructor to false if you want to overwrite the file each time. Docs are here. Quote:
append
Type: System.Boolean
Determines
whether data is to be appended to the
file. If the file exists and append is
false, the file is overwritten. If the
file exists and append is true, the
data is appended to the file.
Otherwise, a new file is created.
Revised code:
using (StreamWriter sw = new StreamWriter(Append.FileName, false))
{
sw.WriteLine();
sw.Write(mydata);
}
Replacing a given line in your file rather than just overwriting the whole file is a lot more difficult - this code is not going to get it done. StreamWriter is not great for this, you need random access and the ability to replace one data segment (line) by a different data segment of different length, which is an expensive operation on disk.
You might want to keep the files in memory as a container of Strings and do your required line replacement within the container, then write out the file to disk using File.WriteAllLines - that's if the file is not too big.