An Issue With Writing In A File In C# - c#

I developed a simple program that asks the user if he wants to add a new record to a file or display all the records contained in the file, but I seem to have a problem in writing to the file. The file is created but still nothing is written in it. The reading function works fine since I wrote something in the file to see if it works.
Here is the code...
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace F01
{
class Program
{
static int ID;
static String Name;
static void Main(string[] args)
{
FileStream MyFiler = new FileStream("MyFile.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
StreamReader FileReader = new StreamReader(MyFiler);
StreamWriter FileWriter = new StreamWriter(MyFiler);
Console.WriteLine("Please Select One Of The Following Options... ");
Console.WriteLine("1. Enter A New Record In The File.");
Console.WriteLine("2. Read All The Records From The File.");
int Choice = int.Parse(Console.ReadLine());
if (Choice == 1)
{
Console.WriteLine("Enter The ID: ");
ID = int.Parse(Console.ReadLine());
FileWriter.WriteLine(ID);
Console.WriteLine("Enter The Name: ");
Name = Console.ReadLine();
FileWriter.WriteLine(Name);
}
else if (Choice == 2)
{
FileWriter.Close();
String fileText = File.ReadAllText("MyFile.txt");
for (int i = 0; i < fileText.Length; i++)
{
Console.Write(fileText[i]);
}
}
FileReader.Close();
}
}
}
Thanks in advance :)

You're not closing the writer in the only situation in which you're using it - "choice 1". Basically the data is being buffered, and lost when the process exits because you haven't closed the writer.
I would strongly advise you to:
Only open the file when you need to
Use local variables instead of class variables unless you need them in other methods
Use the File static methods to make all of this easier
Use using statements to clean up resources at the end of them (if you need a writer or a stream at all, that is...)
Break your code up into methods for separate operations
Name your variables in camelCase rather than PascalCase
Print your file a line at a time rather than a letter at a time
So for example:
using System;
using System.IO;
class Program
{
const string FileName = "MyFile.txt";
static void Main(string[] args)
{
Console.WriteLine("Please Select One Of The Following Options... ");
Console.WriteLine("1. Enter A New Record In The File.");
Console.WriteLine("2. Read All The Records From The File.");
int choice = int.Parse(Console.ReadLine());
switch (choice)
{
case 1:
AddEntry();
break;
case 2:
ReadFile();
break;
default:
Console.WriteLine("Sorry, that's not a valid option");
break;
}
}
static void AddEntry()
{
Console.WriteLine("Enter the ID:");
int id = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the name:");
string name = Console.ReadLine();
File.AppendAllLines(FileName, new[] { id.ToString(), name });
}
static void ReadFile()
{
foreach (var line in File.ReadLines(FileName))
{
Console.WriteLine(line);
}
}
}

I see your MyFiler which is a FileStream type which is IDisposable type is not wrapped in using statement, nor do you call .Dispose() manually. Same for your readers (which are also disposable types). This can lead to this type of behavior...
Try the follwing:
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace F01
{
class Program
{
static int ID;
static String Name;
static void Main(string[] args)
{
using(FileStream MyFiler = new FileStream("MyFile.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using(StreamReader FileReader = new StreamReader(MyFiler))
{
using(StreamWriter FileWriter = new StreamWriter(MyFiler))
{
Console.WriteLine("Please Select One Of The Following Options... ");
Console.WriteLine("1. Enter A New Record In The File.");
Console.WriteLine("2. Read All The Records From The File.");
int Choice = int.Parse(Console.ReadLine());
if (Choice == 1)
{
Console.WriteLine("Enter The ID: ");
ID = int.Parse(Console.ReadLine());
FileWriter.WriteLine(ID);
Console.WriteLine("Enter The Name: ");
Name = Console.ReadLine();
FileWriter.WriteLine(Name);
}
else if (Choice == 2)
{
FileWriter.Close();
String fileText = File.ReadAllText("MyFile.txt");
for (int i = 0; i < fileText.Length; i++)
{
Console.Write(fileText[i]);
}
}
FileReader.Close();
}
}
}
}
}
}

Related

C#: System.IO.Exception. Why can the process not access the file? How do I allow the StreamWriter to access the file after it gets created?

using System;
using System.IO;
namespace File_Dumping_Script
{
class Program
{
static void Main(string[] args)
{
Random rn = new Random();
string fileName = Convert.ToString(rn.Next(1000));
string path = ("C:\\Users\\taylo\\OneDrive\\Desktop\\FileTesting\\" + fileName);
if (File.Exists(path))
{
fileName = Convert.ToString(rn.Next(1000));
path = ("C:\\Users\\taylo\\OneDrive\\Desktop\\FileTesting\\" + fileName + ".txt");
}
File.CreateText(path);
StreamWriter sw = new StreamWriter(path);
Console.Write("Please enter a seed for the random numbers: ");
int seed = Convert.ToInt32(Console.ReadLine());
int written = 0;
while (written != seed-1)
{
written = rn.Next(seed);
sw.Write(" "+written);
Console.WriteLine(written);
}
sw.Write("\n Process ended.");
Console.WriteLine("Process complete.");
Console.ReadLine();
}
}
}
I want this program to create a file with a random number for a name, and then write a bunch of random numbers to that file. I am currently facing a problem that the File.CreateText(); is using the path, which means that the StreamWriter cannot create an object based off that path. Is there any way I can stop the File.CreateText(); from using the file so the StreamWriter can access it instead?
Also, as a secondary, less important, problem, the files created are not text files, and the way I have tried to fix that with the path = ("C:\\Users\\taylo\\OneDrive\\Desktop\\FileTesting\\" + fileName); doesn't make it a text file and nor does the File.CreateText(); How do I make it a text file instead of a 'file'?
Thank you in advance,
Taylor

How can I achieve to not only read one line from the txt file but also all the lines?

Im a beginner programmer. I started to learn c# about two weeks ago, and now I'm programming a simple Login/Register program but it's a bit hard for me. My question is: there is this
adat1= olvas.ReadLine(); code, and I think this is for read only one line from the txt. How can I achieve to read all the lines and then select the UserName which we write into the Console? After the solution we will be able to create new Users.
Thank you guys for your help!
My source code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
namespace Gyak
{
class Program
{
static void Main(string[] args)
{
bool helyes = false;
do {
Console.Clear();
Console.WriteLine("1 = Login\n2 = Registration");
int valasz = int.Parse(Console.ReadLine());
if (valasz == 1)
{
StreamReader olvas = new StreamReader(#"D:\k\Gyakorlás 2\UserName.txt", Encoding.Default);
while (!olvas.EndOfStream)
{
string adat1;
helyes = true;
Console.Clear();
Console.WriteLine("Login");
Console.WriteLine("UserName: ");
Console.Write("Password: ");
Console.SetCursorPosition(10, 1);
string valasz1 = Console.ReadLine();
adat1 = olvas.ReadLine();
Console.SetCursorPosition(10, 2);
string valasz2 = Console.ReadLine();
if (adat1.StartsWith(valasz1))
{
string[] keresett_adat = adat1.Split(':');
string keresett_eredmény = keresett_adat[1];
if (valasz2 == keresett_eredmény)
{
Console.WriteLine("Login Succeeded");
Console.ReadLine();
}
else
{
Console.WriteLine("Access Denied!\nTry again!");
Console.ReadLine();
}
}
}
}
else if (valasz == 2)
{
StreamWriter iras = new StreamWriter(#"D:\k\Gyakorlás 2\UserName.txt", true, Encoding.Default);
helyes = true;
Console.Clear();
Console.WriteLine("Registration");
Console.WriteLine("UserName: ");
Console.Write("Password: ");
Console.SetCursorPosition(10, 1);
string valasz3 = Console.ReadLine();
Console.SetCursorPosition(10, 2);
string valasz4 = Console.ReadLine();
iras.WriteLine( "\n" + valasz3 + ":" + valasz4);
iras.Close();
}
else
{
helyes = false;
Console.WriteLine("Incorrect!");
Thread.Sleep(2000);
}
}while(helyes != true);
}
}
}
You can use File.ReadAllText or File.ReadAllLines.

C# Delete line from .txt extension with a changing filename

I am currently trying to make an .exe in c# that I can drag and drop a .txt file onto to remove lines of text that contain the keywords "CM" and/or "Filling". It must be able to overwrite the existing data so there are no new files created. The filename is different every time except for the extension. The data is tab delimited if that has any bearing. I'm aware that there are similar questions to this but I haven't managed to adapt them to suit my needs. Also, I'm very new to this and I've been trying for about a week with no luck.
if (args.Length == 0)
return; // return if no file was dragged onto exe
string text = File.ReadAllText("*.txt");
text = text.Replace("cm", "");
string path = Path.GetDirectoryName(args[0])
+ Path.DirectorySeparatorChar
+ Path.GetFileNameWithoutExtension(args[0])
+ "_unwrapped" + Path.GetExtension(args[0]);
File.WriteAllText("*.txt", text);
\\attempt 1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Text.RegularExpressions;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
string concrete = "CM";
string line;
using (StreamReader reader = new StreamReader(#"C:\\Users\drocc_000\Desktop\1611AN24T99-041805221704.txt"))
{
using (StreamWriter writer = new StreamWriter(#"C:\\Users\drocc_000\Desktop\1611AN24T99-041805221704NEW.txt"))
{
while ((line = reader.ReadLine()) != null)
{
// if (String.Compare(line, yourName) == 0)
// continue;
writer.WriteLine(line.Replace(concrete, ""));
}
}
}
\\attempt 2
Thanks for your time.
Regards,
Danny
You can create a console application with the code below and then drag and drop your text file into the .exe file without opening it.
class Program
{
static void Main(string[] args)
{
if (args.Length > 0 && File.Exists(args[0]))
{
string path = args[0];
EditFile(new List<string>() { "CM", "Filling" }, path);
}
Console.Read();
}
public static void EditFile(List<string> keyWords, string filename)
{
List<string> lines = new List<string>();
using (StreamReader sr = new StreamReader(filename))
{
while (sr.Peek() >= 0)
{
lines.Add(sr.ReadLine());
}
sr.Close();
}
int removedLinesCount = 0;
bool writeline;
using (StreamWriter sw = new StreamWriter(filename))
{
foreach (var line in lines)
{
writeline = true;
foreach (var str in keyWords)
{
if (line.Contains(str))
{
writeline = false;
removedLinesCount++;
break;
}
}
if (writeline)
sw.WriteLine(line);
}
Console.WriteLine(removedLinesCount + " lines removed from the file " + filename);
sw.Close();
}
}
}
Something like this?
using System;
using System.IO;
using System.Linq;
namespace ConsoleApp1
{
internal static class Program
{
private static void Main(string[] args)
{
try
{
// Get the filename from the applications arguments
string filename = args[0];
// Read in all lines in the file.
var linesInFile = File.ReadLines(filename);
// Filter out the lines we don't need.
var linesToKeep = linesInFile.Where(line => !line.Contains("CM") && !line.Contains("Filling")).ToArray();
// Overwrite the file.
File.WriteAllLines(filename, linesToKeep);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}

c# value not being stored into accessor

I have 4 class files Driver class (contains main method)
UserInput class (contains GenerateLines & TxtLoadFile methods)
FileHandling.class(contains LoadFile & LoadingFile methods)
Crypting class (empty class at the moment)
My issue is I am trying to get the user to choose which directory out of three to choose a file from. Once chosen I want them to input the file name (.txt) and when that is done I want that value stored and taken to FileHandling class and the LoadFile accessor stores the value into 'TxtFile' variable. I then want to use 'TxtFile' in the method LoadingFile to load the file.
Issue is the value gets stored while in UserInput class but when I call: LoadingFile method in the Driver class it drops the value.
Bear in mind I am student still learning C#, so may not be the best constructed programs as I am just practicing for assignment.
EDIT: I forgot to mention I did check this through debugger but I could not work out how to fix it
Driver class :
namespace UniAssignVigereneCipher
{
class Driver
{
static void Main(string[] args)
{
UserInput UI = new UserInput();
Crypting CR = new Crypting();
FileHandling FH = new FileHandling();
Console.WriteLine(UI.test);
Console.WriteLine(UI.test2);
FH.LoadingFile();
}
}
}
UserInput class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace UniAssignVigereneCipher
{
class UserInput
{
public string test = GenerateLines();
public string test2 = TxtLoadFile();
public static string GenerateLines()
{
string input;
Console.WriteLine("Would you like to encrypt/decrypt a .txt(t) file or a piece text string(s)?\r\nPlease type (t) or (s)");
input = Console.ReadLine();
switch (input)
{
case "t":
case "T":
Console.WriteLine("You have selected a txt file.");
break;
case "s":
case "S":
Console.WriteLine("You have selected to input your own text string.");
break;
default:
break;
}
return input;
}
public static string TxtLoadFile()
{
FileHandling Location = new FileHandling();
int n;
string FileInput;
string TxtFileLoc;
Console.WriteLine("Please choose the location of the .txt file you would like to load from.\r\n1 (Current Location): {0} \r\n2 (Desktop): {1} \r\n3 (My Documents): {2}", Location.CurrentDir, Location.DesktopPath,Location.DocumentsPath);
FileInput = Console.ReadLine();
bool test = int.TryParse(FileInput, out n);
switch (n)
{
case 1:
Console.WriteLine("File Location: {0} \r\nName of file to load: ", Location.CurrentDir);
TxtFileLoc = Console.ReadLine();
Location.LoadFile = Location.DesktopPath + "\\" + TxtFileLoc;
break;
case 2:
Console.WriteLine("File Location: {0} \r\nName of file to load: ", Location.DesktopPath);
TxtFileLoc = Console.ReadLine();
Location.LoadFile = Location.DesktopPath + "\\" + TxtFileLoc;
break;
case 3:
Console.WriteLine("File Location: {0} \r\nPName of file to load: ", Location.DocumentsPath);
TxtFileLoc = Console.ReadLine();
Location.LoadFile = Location.DocumentsPath + "\\" + TxtFileLoc;
break;
default:
break;
}
return FileInput;
}
}
}
FileHandling class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace UniAssignVigereneCipher
{
class FileHandling
{
public string DesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
public string DocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
public string CurrentDir = Environment.CurrentDirectory;
string TxtFile;
public string LoadFile
{
get
{
return TxtFile;
}
set
{
TxtFile = value;
}
}
public void LoadingFile()
{
Console.WriteLine("name:" + TxtFile);
StreamReader LF = new StreamReader(TxtFile);
string FileContent = LF.ReadLine();
Console.WriteLine(FileContent);
}
}
}
Try:
static void Main(string[] args)
{
UserInput UI = new UserInput();
Crypting CR = new Crypting();
FileHandling FH = new FileHandling();
Console.WriteLine(UI.test);
Console.WriteLine(UI.test2);
FH.LoadFile = UI.test2;
FH.LoadingFile();
}
Note: It's very odd to put your worker methods into the class construction. it would probably be better to call them like this:
UserInput UI = new UserInput();
string textFile = UI.TxtLoadFile();
//... later on...
FH.LoadFile = textFile;

StreamWriter not writing to file in C# console

I'm new to programming and C# is the language I'm learning. My homework instructions are:
Create a program named WritelnventoryRecords that allows you to enter data for items you sell at an online auction site and saves the data to a file. Create an Inventory class that contains fields for item number, description, and asking price.
The code I've written will not write to the text file, it's just blank. What am I missing?
using System;
using System.IO;
class Inventory
{
static void Main()
{
Console.Write("How many items would you like to enter? ");
FileStream file = new FileStream("ItemsSold.txt", FileMode.Create, FileAccess.Write);
StreamWriter writer = new StreamWriter(file);
int num = Convert.ToInt32(Console.ReadLine());
int itemNum = 0;
string desc;
double price;
for (int count = 0; count < num; ++count)
{
Console.Write("Enter an item number: ");
itemNum = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the item description: ");
desc = Console.ReadLine();
Console.Write("Enter the item price (no dollar sign): ");
price = Convert.ToDouble(Console.ReadLine());
writer.WriteLine(itemNum + "," + desc + "," + price);
}
writer.Close();
file.Close();
Console.ReadLine();
}
}
Thank you for your help.
Your code works on my machine.
If it's still not works, you can try following steps:
When open the file stream, use "FileMode.OpenOrCreate" flag.
Reset the file using "file.SetLength(0);" just after create the file steam.
Flush the buffer before close the file stream: "writer.Flush();"
=== EDIT ===
And yes, like #Preston Guillot posted, check if you are opening the right file.

Categories