Severus Josefsen Ответов: 2

Как я могу решить эту проблему: system.io.ioexception: 'процесс не может получить доступ к файлу '@.txt', потому что он используется другим процессом'.


Когда я нажимаю кнопку, все работает до тех пор, пока часть using Stream writer, где код выходит из строя, как я могу это исправить?

Код 1:

namespace Bankomat
{
    public partial class SättIn : Form
    {
        bool check = false;
        string[] hämtaSaldo;
        string line;
        public SättIn()
        {
            InitializeComponent();
        }

        private void btnTillbaka_Click(object sender, EventArgs e)
        {
            this.Hide();
            Alternativ alternativ = new Alternativ();
            alternativ.ShowDialog();
        }

        private void btnSättIn_Click(object sender, EventArgs e)
        {
            using (StreamReader reader = new StreamReader("Konto.txt"))
            {
                while ((line = reader.ReadLine()) != null)
                {
                    if (line.Contains(LoggaIn.användarnamn + "," + LoggaIn.lösenord))
                    {
                        check = true;
                        hämtaSaldo = line.Split(',');
                    }
                }
                reader.Close();
            }
            if (check)
            {
                using (StreamWriter writer = new StreamWriter("Konto.txt"))
                {
                    string nyttSaldo = (double.Parse(hämtaSaldo[2]) + double.Parse(txtBelopp.Text)).ToString();
                    line.Replace(hämtaSaldo[2], nyttSaldo);
                    writer.Close();
                }
            }
        }
    }
}


Код 2:

namespace Bankomat
{
    public partial class LoggaIn : Form
    {
        public LoggaIn()
        {
            InitializeComponent();
        }

        private void btnTillbaka_Click(object sender, EventArgs e)
        {
            //Stänger formen LoggaIn och öppnar formen Startsida
            this.Hide();
            Startsida startsida = new Startsida();
            startsida.ShowDialog();
        }

        public static string användarnamn, lösenord;

        private void btnLoggaIn_Click(object sender, EventArgs e)
        {
            //Läser vare rad i filen Konto efter skrivet användarnamn och lösenord
            using (StreamReader reader = new StreamReader("Konto.txt"))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    if (line.Contains(txtAnvändarnamn.Text + "," + txtLösenord.Text))
                    {
                        användarnamn = txtAnvändarnamn.Text;
                        lösenord = txtLösenord.Text;
                        //Stänger formen LoggaIn och öppnar formen Alternativ
                        this.Hide();
                        Alternativ alternativ = new Alternativ();
                        alternativ.ShowDialog();
                    }
                }
            }
        }
    }
}


Код 3:

 namespace Bankomat
{
    public partial class SkapaKonto : Form
    {
        public SkapaKonto()
        {
            InitializeComponent();
        }

        private void btnTillbaka_Click(object sender, EventArgs e)
        {
            //Stänger formen SkapaKonto och öppnar formen Startsida
            this.Hide();
            Startsida startsida = new Startsida();
            startsida.ShowDialog();
        }

        private void btnSkapaKonto_Click(object sender, EventArgs e)
        {
            //Skriver ned det nya kontot i text filen Konto
            using (StreamWriter writer = new StreamWriter("Konto.txt"))
            {
                writer.WriteLine(txtAnvändarnamn.Text + "," + txtLösenord.Text + "," + "0");
                txtAnvändarnamn.Text = "";
                txtLösenord.Text = "";
            }
            //Visar användaren att kontot har skapats
            MessageBox.Show("Ditt konto har skapats!");
            //Stänger formen SkapaKonto och öppnar formen Startsida
            this.Hide();
            Startsida startsida = new Startsida();
            startsida.ShowDialog();
        }
    }
}


Что я уже пробовал:

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

Richard MacCutchan

Где происходит ошибка? У вас есть три отдельные формы здесь, так что вы должны по крайней мере знать, какая из них активна.

Severus Josefsen

Ошибка возникает в коде 1 и это StreamWriter

Richard Deeming

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

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

Безопасная Аутентификация Паролем Объясняется Просто[^]
Соленое хэширование паролей - делаем это правильно[^]

Я могу только надеяться, что это игрушечное приложение для школьного проекта, а не что-то, предназначенное для реального использования!

Severus Josefsen

Ну, этот проект-это то, что я изучаю StreamWriter и StreamReader только потому, что это то, что я узнал во время занятий.

2 Ответов

Рейтинг:
4

Richard Deeming

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

Вариант 1:
Считайте весь файл в память. Замените строку в данных, которые вы прочитали. Запишите весь файл снова.

private void btnSättIn_Click(object sender, EventArgs e)
{
    string prefix = LoggaIn.användarnamn + "," + LoggaIn.lösenord + ",";
    bool found = false;
    
    string[] lines = File.ReadAllLines("Konto.txt");
    for (int index = 0; index < lines.Length; index++)
    {
        if (lines[index].StartsWith(prefix))
        {
            string[] parts = lines[index].Split(',');
            double oldValue = double.Parse(parts[2]);
            double belopp = double.Parse(txtBelopp.Text);
            double newValue = oldValue + belopp;
            parts[2] = newValue.ToString();
            lines[index] = string.Join(",", parts);
            found = true;
            break;
        }
    }
    
    if (found)
    {
        File.WriteAllLines("Konto.txt", lines);
    }
    else
    {
        // Notify the user that the line was not found...
    }
}
Файл.Метод ReadAllLines (System.IO) | Microsoft Docs[^]
Файл.Метод WriteAllLines (System.IO) | Microsoft Docs[^]

Вариант 2:
Если файл слишком велик для чтения в память, вам нужно будет скопировать его построчно в другой файл, а затем заменить оригинал:
private void btnSättIn_Click(object sender, EventArgs e)
{
    string prefix = LoggaIn.användarnamn + "," + LoggaIn.lösenord + ",";
    bool found = false;
    
    using (var reader = new StreamReader("Konto.txt"))
    using (var writer = new StreamWriter("Konoto.tmp"))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            if (found || !line.StartsWith(prefix))
            {
                writer.WriteLine(line);
            }
            else
            {
                string[] parts = line.Split(',');
                double oldValue = double.Parse(parts[2]);
                double belopp = double.Parse(txtBelopp.Text);
                double newValue = oldValue + belopp;
                parts[2] = newValue.ToString();
                writer.WriteLine(string.Join(",", parts));
                found = true;
            }
        }
    }
    
    if (found)
    {
        // Overwrite the file with the updated file:
        File.Delete("Konoto.txt");
        File.Move("Konoto.tmp", "Konoto.txt");
    }
    else
    {
        // No changes - delete the temp file:
        File.Delete("Konoto.tmp");
    }
}


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


Рейтинг:
12

OriginalGriff

1) Почему вы открываете файл для записи, но никогда не пишете в него?

if (check)
{
    using (StreamWriter writer = new StreamWriter("Konto.txt"))
    {
        string nyttSaldo = (double.Parse(hämtaSaldo[2]) + double.Parse(txtBelopp.Text)).ToString();
        line.Replace(hämtaSaldo[2], nyttSaldo);
        writer.Close();
    }
}
2) В приведенном выше фрагменте кода, line гарантированно будет null потому что он может только когда-либо выйти из while петля над ним, когда он есть, так что Replace вызов бросит а NullReferenceException
3) Не храните (или не пытайтесь записывать) файлы данных в папке вашей программы - и когда вы не указываете какую - либо папку, это именно то место, где она хранится, - так как в производстве она очень вероятно потерпит неудачу, так как она будет находиться в разделе "Программные файлы" и защищена от записи, чтобы предотвратить или, по крайней мере, уменьшить вирусную активность. Это может помочь: Где я должен хранить свои данные?[^]
4) проблема, с которой вы столкнулись, вероятно, не в этом коде: она находится в другом коде, который обращается к файлу, но который не заключает поток в using блок. На твоем месте я бы просмотрел весь остальной код.


Severus Josefsen

Я загрузил другие коды