Click here to Skip to main content
14,300,487 members
Rate this:
Please Sign up or sign in to vote.
See more:
Hello, I'm trying to write to a text file from more then one method, but can't get the information in my second method (Getuserdetails) to go onto the file or in the place I need it to go (between BEGIN and END).

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace System.IO


{

    class Program

    {
		static void Main(string[] args)

		{


            mainMenu();
            
            Console.WriteLine("Happy coding");






        }

        public static void mainMenu()
        {
            int value = 0;

            StreamWriter writer = new StreamWriter("numbers.txt");
            do
            {
                Console.WriteLine("Menu \n 1. Main Method \n 2. Method \n 0. End");
                value = Convert.ToInt32(Console.ReadLine());

                switch (value)
                {
                    case 1:
                        writer.WriteLine("MAIN \nBEGIN");
                        GetUserDetails();
                        writer.WriteLine();
                        writer.WriteLine("END");
                        break;
                    case 2:
                        writer.WriteLine();
                        writer.WriteLine("METHOD \nBEGIN");
                        writer.WriteLine();
                        writer.WriteLine("END");
                        GetUserDetails();
                        break;

                }
            } while (value > 0);
            writer.Close();
        }

        public static void GetUserDetails()

        {
            int value = 0;
            int a = 0;
            StreamWriter writer = new StreamWriter("numbers.txt");
                do
                {

                    Console.WriteLine("Menu \n 1. CREATE \n 2. PRINT \n 3. ← READ user input \n 4. IF ELSE \n 5. SWITCH CASE \n 0. Exit");
                    value = Convert.ToInt32(Console.ReadLine());

                    switch (value)
                    {
                        case 1:
                            Console.WriteLine("How many CREATES would you like?");
                            a = Convert.ToInt32(Console.ReadLine());
                            do
                            {
                                writer.WriteLine("CREATE");
                                a = a - 1;
                            } while (a > 0);
                            writer.WriteLine();
                            break;
                        case 2:
                            Console.WriteLine("How many PRINT would you like?");
                            a = Convert.ToInt32(Console.ReadLine());
                            do
                            {
                                writer.WriteLine("PRINT");
                                a = a - 1;
                            } while (a > 0);
                            writer.WriteLine();
                            break;
                        case 3:
                            Console.WriteLine("How many ← READ user input would you like?");
                            a = Convert.ToInt32(Console.ReadLine());
                            do
                            {
                                writer.WriteLine("← READ user input");
                                a = a - 1;
                            } while (a > 0);
                            writer.WriteLine();
                            break;
                        case 4:
                            Console.WriteLine("How many ELSE would you like in your IF statement?");
                            a = Convert.ToInt32(Console.ReadLine());
                            writer.WriteLine("IF");
                            int b = 0;
                            do
                            {
                                b = b + 1;
                                writer.WriteLine("ELSE " + b);
                                a = a - 1;
                            } while (a > 0);
                            writer.WriteLine();
                            break;
                        case 5:
                            Console.WriteLine("How many CASE would you like in your SWITCH statement?");
                            a = Convert.ToInt32(Console.ReadLine());
                            writer.WriteLine("SWITCH");
                            b = 0;
                            do
                            {
                                b = b + 1;
                                writer.WriteLine("CASE " + b);
                                a = a - 1;
                            } while (a > 0);
                            writer.WriteLine();
                            break;

                    }
                } while (value > 0);

        }

    }

}

What I have tried:

I will greatly appreciate any help.
Posted
Updated 11-Sep-19 11:21am
v2
Comments
BillWoodruff 11-Sep-19 7:38am
   
If your program needs to insert text in the file at a certain position, or at the beginning (prepend), you will need to rebuild the file to achieve that.
Rate this:
Please Sign up or sign in to vote.

Solution 1

You can't open a file for writing twice: the system won't let you because it doesn't "know" which of the writes it should keep in the file if the two were to both write in the same place.

So when you open a file for writing, the system establishes what is called an exclusive lock which prevents any other code (for your app or another) from writing to the file.
There are two ways you can get round this:
1) change your code so that writer is a class level static variable, and is thus available to all code in your class:
        private static StreamWriter writer = null;
        public static void mainMenu()
        {
            int value = 0;

            writer = new StreamWriter("numbers.txt");
            do
...
And remove the other StreamWriter from the GetUserDetails method.

2) Don't use a StreamWriter at all. The File class has a method AppendAllText which opens the file, adds the string you pass, and closes it again:
File.AppendAllText(pathToFile, "MAIN \n BEGIN\n");
Replace your StreamWriter code with that and it'll work just fine.
   
Rate this:
Please Sign up or sign in to vote.

Solution 2

Hi Jmurphr,

You can pass the reference of the StreamWriter to the method, then it will open one writing channel for that file and append all the text into that file.
I hope this will do your job:-

public static void mainMenu()
        {
            int value = 0;

            StreamWriter writer = new StreamWriter("numbers.txt");
            do
            {
                Console.WriteLine("Menu \n 1. Main Method \n 2. Method \n 0. End");
                value = Convert.ToInt32(Console.ReadLine());

                switch (value)
                {
                    case 1:
                        writer.WriteLine("MAIN \nBEGIN");
                        GetUserDetails(writer);
                        writer.WriteLine();
                        writer.WriteLine("END");
                        break;
                    case 2:
                        writer.WriteLine();
                        writer.WriteLine("METHOD \nBEGIN");
                        writer.WriteLine();
                        writer.WriteLine("END");
                        GetUserDetails(writer);
                        break;

                }
            } while (value > 0);
            writer.Close();
        }

        public static void GetUserDetails(StreamWriter writer)

        {
            int value = 0;
            int a = 0;
            //StreamWriter writer = new StreamWriter("numbers.txt");
            do
            {

                Console.WriteLine("Menu \n 1. CREATE \n 2. PRINT \n 3. ← READ user input \n 4. IF ELSE \n 5. SWITCH CASE \n 0. Exit");
                value = Convert.ToInt32(Console.ReadLine());

                switch (value)
                {
                    case 1:
                        Console.WriteLine("How many CREATES would you like?");
                        a = Convert.ToInt32(Console.ReadLine());
                        do
                        {
                            writer.WriteLine("CREATE");
                            a = a - 1;
                        } while (a > 0);
                        writer.WriteLine();
                        break;
                    case 2:
                        Console.WriteLine("How many PRINT would you like?");
                        a = Convert.ToInt32(Console.ReadLine());
                        do
                        {
                            writer.WriteLine("PRINT");
                            a = a - 1;
                        } while (a > 0);
                        writer.WriteLine();
                        break;
                    case 3:
                        Console.WriteLine("How many ← READ user input would you like?");
                        a = Convert.ToInt32(Console.ReadLine());
                        do
                        {
                            writer.WriteLine("← READ user input");
                            a = a - 1;
                        } while (a > 0);
                        writer.WriteLine();
                        break;
                    case 4:
                        Console.WriteLine("How many ELSE would you like in your IF statement?");
                        a = Convert.ToInt32(Console.ReadLine());
                        writer.WriteLine("IF");
                        int b = 0;
                        do
                        {
                            b = b + 1;
                            writer.WriteLine("ELSE " + b);
                            a = a - 1;
                        } while (a > 0);
                        writer.WriteLine();
                        break;
                    case 5:
                        Console.WriteLine("How many CASE would you like in your SWITCH statement?");
                        a = Convert.ToInt32(Console.ReadLine());
                        writer.WriteLine("SWITCH");
                        b = 0;
                        do
                        {
                            b = b + 1;
                            writer.WriteLine("CASE " + b);
                            a = a - 1;
                        } while (a > 0);
                        writer.WriteLine();
                        break;

                }
            } while (value > 0);

        }


In future if you need any other method from which you want to write the text into that file then you have to implement the parameter and pass the StreamWriter object in that method.
   
Rate this:
Please Sign up or sign in to vote.

Solution 3

This is bad idea to read/write data from/to text file within multi proccesses. It might be the reason of several problems. See: c# - Multi processes read&write one file - Stack Overflow[^]

I'd strongly recommend to read this: Reading and Writing in Text Files with multiple programs accessing it simultaneously – Sitecore Endeavor[^]

In my opinion, you should create one method which will write some portion of data to a text file (at the end or will seek already existing file to write specific data on the specific position). Alternativelly, you can grab data entered by the user to a List<string>() or List<int>, then - when user finishes entering data - you'll be able to write it to a text file.

Good luck!
   
Comments
BillWoodruff 11-Sep-19 8:20am
   
+5
Maciej Los 11-Sep-19 8:25am
   
Thank you, Bill.
Rate this:
Please Sign up or sign in to vote.

Solution 4

If your program needs to insert text in a closed file at a certain position, or at the beginning (prepend), you will need to rebuild the file to achieve that.

Your code doesn't appear to require inserting in an existing closed file.

Partly for reasons that Maciej described in his solution, I suggest you always use a StringBuilder: add all the text; then, when complete, write the StringBuilder content to the file.

I think you can re-order the flow of user input in the Console so that you never have to insert within the file.

However, in case you must insert:
using System;
using System.IO;
using System.Text;

namespace YourNameSpace
{
    public enum WriteWhere
    {
       Append, PrePend, InsertReplacingMarker, InsertPreservingMarker
    }

    public class SBWriter
    {
        public SBWriter(string fileName)
        {
            if (!File.Exists(fileName))
            {
                throw new FileNotFoundException(@"{FileName} invalid");
            }

            FileName = fileName;
        }

        StringBuilder sb = new StringBuilder();

        private StreamWriter Writer;

        private string FileName;

        public void WriteToSB(string text, WriteWhere whereto = WriteWhere.Append, string marker = "")
        {
            switch(whereto)
            {
                case WriteWhere.Append:
                    sb.AppendLine(text);
                    break;
                case WriteWhere.PrePend:
                    sb.Insert(0, text + Environment.NewLine);
                    break;
                case WriteWhere.InsertReplacingMarker:
                    sb.Replace(marker + Environment.NewLine, text + Environment.NewLine);
                    break;
                case WriteWhere.InsertPreservingMarker:
                    sb.Replace(marker, string.Format("{0}{1}", marker + Environment.NewLine, text));
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(whereto), whereto, null);
            }
        }

        public void WriteFile()
        {
            // add try catch !
            File.WriteAllText(FileName, sb.ToString());
        }
    }
}
Sample usage:
SBWriter sbw = new SBWriter(@"C:\Users\test_user\Desktop\Test\test.txt");

sbw.WriteToSB("hello");
sbw.WriteToSB("xxx");  // will function as marker
sbw.WriteToSB("qwr");
sbw.WriteToSB("sffsfqf");
sbw.WriteToSB("beginning", WriteWhere.PrePend);
sbw.WriteToSB("zzzz");
sbw.WriteToSB("yyyyy");

//sbw.WriteToSB(@"yo mama", WriteWhere.InsertPreservingMarker, "xxx");

sbw.WriteToSB(@"yo mama", WriteWhere.InsertReplacingMarker, "xxx");
Note that the StringBuilder 'Replace function will replace all instances of its target string.
   
v3
Comments
Maciej Los 11-Sep-19 9:23am
   
Excellent solution!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100