Autor Beitrag
rennmaus
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Di 10.04.18 13:01 
Hallo ich bin neu hier und ich hoffe ich schreibe hier richtig :)
Ich probiere mich gerade am Programmieren und stoße zur Zeit auf einen doofen Fehler welchen ich nicht gelöst bekomme.

Zunächst beschreibe ich euch mal meine Absicht:

Ich habe einen Notizblock programmiert, welcher den Text aus der Datei notes.txt liest und sobald neuer Text hinzukommt automatisch überschreibt. Das hat auch alles super funktioniert. Jetzt möchte ich gerne, dass die Datei notes.txt beim Schließen sofort gelöscht wird und dann direkt neu erstellt wird, um beim nächsten Start eine unbeschriebenes Blatt zu haben.
Das funktioniert soweit auch! Aber: Ich möchte den Fall Abdecken, dass die Datei notes.txt unter Umständen nicht mehr existiert und dann neu erstellt wird. Das habe ich mit Zeile 42: void loadtxt() versucht, aber sobald ich die Datei notes.txt lösche und das Programm dann starte um zu sehen, ob die Datei erstellt wird, bekomme ich folgende Meldung:
Zitat:
Zeile 53:
Unbehandelte Ausnahme:
"Der Prozess kann nicht auf die Datei "C:\Users\xxx\source\repos\Notizblock_2018_03_13\Notizblock_2018_03_13\bin\Debug\notes.txt" zugreifen, da sie von einem anderen Prozess verwendet wird."

System.IO.IOException
HResult=0x80070020
Nachricht = Der Prozess kann nicht auf die Datei "C:\Users\xxx\source\repos\Notizblock_2018_03_13\Notizblock_2018_03_13\bin\Debug\notes.txt" zugreifen, da sie von einem anderen Prozess verwendet wird.

Details:
Quelle = mscorlib
Stapelüberwachung:
bei System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
bei System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
bei System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
bei System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean checkHost)
bei System.IO.StreamReader..ctor(String path)
bei Notizblock_2018_03_13.Notizblock.loadtxt() in C:\Users\xxx\source\repos\Notizblock_2018_03_13\Notizblock_2018_03_13\Form1.cs: Zeile55
bei Notizblock_2018_03_13.Notizblock.Notizblock_Load(Object sender, EventArgs e) in C:\Users\xxx\source\repos\Notizblock_2018_03_13\Notizblock_2018_03_13\Form1.cs: Zeile33
bei System.Windows.Forms.Form.OnLoad(EventArgs e)
bei System.Windows.Forms.Form.OnCreateControl()
bei System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
bei System.Windows.Forms.Control.CreateControl()
bei System.Windows.Forms.Control.WmShowWindow(Message& m)
bei System.Windows.Forms.Control.WndProc(Message& m)
bei System.Windows.Forms.ScrollableControl.WndProc(Message& m)
bei System.Windows.Forms.Form.WmShowWindow(Message& m)
bei System.Windows.Forms.Form.WndProc(Message& m)
bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


...und das Programmfenster geht zu, scheint aber noch zu laufen, die Datei hat sich auch erstellt!

Wahrscheinlich ist der Fehler ganz schnell zu lösen, aber als Anfänger wird man oft nicht schlau aus solchen Meldungen..
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Linq;

namespace Notizblock_2018_03_13
{
    public partial class Notizblock : Form
    {


        public Notizblock()
        {
            InitializeComponent();
            lb_1.Text = DateTime.Now.ToLongDateString();
        }


        private void lb_1_Click(object sender, EventArgs e)
        {

        }

        private void Notizblock_Load(object sender, EventArgs e)
        {
            loadtxt();
        }

        private void Notizblock_FormClosing(object sender, FormClosingEventArgs e)
        {
            savetxt();
            File.Delete("C:/Users/xxx/source/repos/Notizblock_2018_03_13/Notizblock_2018_03_13/bin/Debug/notes.txt");
        }

        void loadtxt()
        {
            //LADEN
            if (System.IO.File.Exists("C:/Users/xxx/source/repos/Notizblock_2018_03_13/Notizblock_2018_03_13/bin/Debug/notes.txt"))
            {
               
            }
            else
            {
                File.Create("C:/Users/xxx/source/repos/Notizblock_2018_03_13/Notizblock_2018_03_13/bin/Debug/notes.txt");
            }
            System.IO.StreamReader sr = new System.IO.StreamReader("C:/Users/xxx/source/repos/Notizblock_2018_03_13/Notizblock_2018_03_13/bin/Debug/notes.txt");
            tb_1.Text = sr.ReadToEnd();
            sr.Close();
        }

        void savetxt()
        {
            //SPEICHERN
            StreamWriter sw = new System.IO.StreamWriter("C:/Users/xxx/source/repos/Notizblock_2018_03_13/Notizblock_2018_03_13/bin/Debug/notes.txt");
            sw.WriteLine(tb_1.Text);
            sw.Close();
        }

        private void tb_1_TextChanged(object sender, EventArgs e)
        {

        }

        private void eigenschaftenToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void dateiToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void öffnenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string Pfad = "";
            //Öffnet Dialogfeld
            OpenFileDialog
                openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
                Pfad = openFileDialog1.FileName;
            //Liest Datei und Lädt
            System.IO.StreamReader sr = new System.IO.StreamReader(Pfad);
            tb_1.Text = sr.ReadToEnd();
            sr.Close();
        }

        private void speichernToolStripMenuItem_Click(object sender, EventArgs e)
        {
            savetxt();
        }

        private void tb_1_KeyDown(object sender, KeyEventArgs e)
        {
            savetxt();
        }

        private void neuToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
    } 
}


*EDIT*

Für alle die das selbe Problem haben, hier die Lösung:

Zeile 51:

ausblenden C#-Quelltext
1:
File.Create("C:/Users/xxx/source/repos/Notizblock_2018_03_13/Notizblock_2018_03_13/bin/Debug/notes.txt");					


umändern in:

ausblenden C#-Quelltext
1:
using (File.Create("C:/Users/xxx/source/repos/Notizblock_2018_03_13/Notizblock_2018_03_13/bin/Debug/notes.txt"))					


***

Könnte das trotzdem jemand erklären, damit ich es nachvollziehen kann?

Moderiert von user profile iconTh69: Quote-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 10.04.18 14:12 
Hallo und :welcome:

File.Create gibt einen (geöffneten) FileStream zurück, daher muß dieser danach wieder geschlossen werden. In deinem Originalcode hast du aber den Rückgabewert ignoriert, so daß dieser nicht geschlossen wurde. Mittels Close() oder Dispose (bzw. durch die using-Anweisung) schließt du ihn wieder.

PS: Du solltest keine absoluten Pfadangaben in deinem Code verwenden.
Mittels
ausblenden C#-Quelltext
1:
string path = Path.Combine(Application.StartupPath, "notes.txt");					
ist der Code viel eleganter (da der Pfad immer noch stimmt, wenn das Programm von einem anderen Ort aus aufgerufen wird).
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 10.04.18 14:29 
- Nachträglich durch die Entwickler-Ecke gelöscht -


Zuletzt bearbeitet von Frühlingsrolle am Mi 11.04.18 13:43, insgesamt 2-mal bearbeitet
rennmaus Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Mi 11.04.18 07:57 
user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
PS: Du solltest keine absoluten Pfadangaben in deinem Code verwenden.
Mittels
ausblenden C#-Quelltext
1:
string path = Path.Combine(Application.StartupPath, "notes.txt");					
ist der Code viel eleganter (da der Pfad immer noch stimmt, wenn das Programm von einem anderen Ort aus aufgerufen wird).


Dankeschön schonmal, und wie würde ich den Pfad bearbeiten, wenn ich die Datei gerne an einer anderen Stelle hätte?


Moderiert von user profile iconTh69: Zitat verkürzt.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 11.04.18 08:41 
Was genau meinst du mit "an einer anderen Stelle"?
Mit meinem Code wird immer auf das Verzeichnis zugegriffen, in dem auch das Programm (die EXE) liegt. Von dort aus kannst du dann auch relativ zugreifen, also z.B. noch einen weiteren Unterordner:
ausblenden C#-Quelltext
1:
string path = Path.Combine(Application.StartupPath, "MyTextFiles""notes.txt");					

Wenn du auf Systemverzeichnisse zugreifen möchtest, dann gibt es dafür die Methode Environment.GetFolderPath(Environment.SpecialFolder) (schau dir dazu einfach die Liste unter Environment.SpecialFolder an).

Für diesen Beitrag haben gedankt: rennmaus
rennmaus Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Mi 11.04.18 08:53 
Du hast mir meine Frage eigentlich genau beantwortet! Dankeschön! Ich wollte nämlich einen eigenen Ordner für sämtliche Notizen erstellen.
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 11.04.18 09:44 
- Nachträglich durch die Entwickler-Ecke gelöscht -
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 11.04.18 10:18 
Zitat:
Darf man fragen, warum du mein Beispiel nicht anwenden möchtest?


Vielleicht solltest du es einfach weiter vereinfachen.

Sowohl StreamReader als auch StreamWriter kann direkt mit einem Pfad arbeiten und braucht keinen explizit erzeugten FileStream. Und wenn man keinen Streamzugriff braucht sondern nur den kompletten Inhalt der Datei lesen schreiben will kann man gleich File.ReadAllText/File.WriteAllText nehmen die das Streamhandling wegkapseln.

File.Delete ignoriert wenn das zu löschende File fehlt und man braucht nicht checken ob das existiert. Letztlich bleibt dann von der Klasse so wenig übrig das man die eigentlich nicht nicht verstehen kann ;)
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 11.04.18 10:38 
- Nachträglich durch die Entwickler-Ecke gelöscht -
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 11.04.18 13:20 
Zitat:
"Datei anlegen, wenn nicht gegeben, und überschreiben, falls gegeben".


Das beschreibt wie die Write Methoden der File Klasse funktionieren ziemlich genau ;)
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 11.04.18 13:40 
- Nachträglich durch die Entwickler-Ecke gelöscht -
rennmaus Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Mi 11.04.18 17:22 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:


Darf man fragen, warum du mein Beispiel nicht anwenden möchtest? Verstehst du es nicht? Wenn ja, warum fragst du nicht?


Hi, einerseits habe ich es (noch) nicht ganz nachvollziehen können und zweitens war mir soweit fürs erste genug geholfen.
Als Frischling kommt man schnell durcheinander auch wenn es eventuell ganz einfach aussieht.
Dankeschön geht natürlich auch an dich!


Zuletzt bearbeitet von rennmaus am Mi 11.04.18 17:31, insgesamt 1-mal bearbeitet
rennmaus Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Mi 11.04.18 17:31 
Ich hätte aber eine andere Frage:

Ich möchte gerne über einen Menübutton die zugehörige Text-Datei zum momentan angezeigten string in der Textbox löschen.
Bisher habe ich einen Ordner mit sämtlichen Notizen, diese haben alle verschiedenen Inhalt, aber wie kann ich ganz gezielt die Datei löschen die gerade dargestellt wird?

Ich habe versucht den Textbox.Text mit den Strings aller im Notizordner befindlichen Dateien zu vergleichen, falls der Content identisch ist, würde die Datei gelöscht werden.
Aber das ist wahrscheinlich viel zu Umständlich oder?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 11.04.18 17:53 
Merke dir doch einfach den Dateinamen der zuletzt angezeigten Textdatei. :idea:
rennmaus Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Mi 11.04.18 20:16 
Soweit klappt alles, dankeschön! :)