Jmurphr Ответов: 4

Как записать текстовый файл из нескольких методов


Здравствуйте, я пытаюсь записать текстовый файл из нескольких методов, но не могу получить информацию в моем втором методе (Getuserdetails), чтобы перейти в файл или в то место, где мне это нужно (между началом и концом).

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.

BillWoodruff

Если вашей программе нужно вставить текст в файл в определенной позиции или в начале (prepend), вам нужно будет перестроить файл для достижения этой цели.

4 Ответов

Рейтинг:
26

JayantaChatterjee

Привет Jmurphr,

Вы можете передать ссылку на StreamWriter затем он откроет один канал записи для этого файла и добавит весь текст в этот файл.
Я надеюсь, что это сделает вашу работу:-

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);

        }


В будущем, если вам понадобится какой-либо другой метод, из которого вы хотите записать текст в этот файл, то вы должны реализовать параметр и передать объект StreamWriter в этот метод.


Рейтинг:
2

Maciej Los

Это плохая идея для чтения/записи данных из/в текстовый файл в рамках нескольких процессов. Это может быть причиной нескольких проблем. Видеть: c# - несколько процессов чтения и записи одного файла - переполнение стека[^]

Я бы настоятельно рекомендовал прочитать это: Чтение и запись текстовых файлов с одновременным доступом к ним нескольких программ – Sitecore Endeavor[^]

На мой взгляд, вы должны создать один метод, который будет записывать некоторую часть данных в текстовый файл (в конце или будет искать уже существующий файл для записи конкретных данных на конкретную позицию). Альтернативно, вы можете захватить данные, введенные пользователем в List<string>() или List<int> затем, когда пользователь закончит вводить данные, вы сможете записать их в текстовый файл.

Удачи вам!


BillWoodruff

+5

Maciej Los

Спасибо, Билл.

Рейтинг:
1

BillWoodruff

Если ваша программа нуждается в этом вставлять текст В а закрытый файл в определенной позиции или в начале (prepend) вам нужно будет перестроить файл, чтобы достичь этого.

Ваш код, по-видимому, не требует вставки в существующий закрытый файл.

Отчасти по причинам, которые Мацей описал в своем решении, я предлагаю вам всегда использовать StringBuilder: add все текст; затем, когда он будет завершен, запишите содержимое StringBuilder в файл.

Я думаю, что вы можете переупорядочить поток пользовательского ввода в консоли так, чтобы вам никогда не приходилось вставлять его в файл.

Однако в случае, если вы должны вставить:

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());
        }
    }
}
Пример использования:
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");
Обратите внимание, что функция StringBuilder 'Replace заменит все экземпляры его целевой строки.


Maciej Los

Отличное решение!

Рейтинг:
0

OriginalGriff

Вы не можете открыть файл для записи дважды: система не позволит вам, потому что она не "знает", какую из записей она должна хранить в файле, если они оба будут писать в одном и том же месте.

Поэтому, когда вы открываете файл для записи, система устанавливает то, что называется монопольная блокировка это предотвращает запись в файл любого другого кода (для вашего приложения или другого).
Есть два способа обойти это:
1) измените свой код так, чтобы writer это статическая переменная уровня класса, и поэтому она доступна для всего кода в вашем классе:

        private static StreamWriter writer = null;
        public static void mainMenu()
        {
            int value = 0;

            writer = new StreamWriter("numbers.txt");
            do
...
И удалить другие модулю записи StreamWriter от GetUserDetails метод.

2) Не используйте StreamWriter вообще. Класс File имеет метод AppendAllText, который открывает файл, добавляет переданную строку и снова закрывает ее:
File.AppendAllText(pathToFile, "MAIN \n BEGIN\n");
Замените свой код StreamWriter на этот, и он будет работать просто отлично.