Speichern einer kontinuierlich überschriebenen Datei im Temp-Ordner in anderem Ordner

carstue

Newbie
Registriert
Juni 2007
Beiträge
4
Ich setze regelmäßig ein Programm ein, mit dem in ein bestimmtes, firmenspezifisches Dateiformat eingebettete, verschlüsselte jpegs angezeigt werden können. Eine Kopie des jeweils angezeigten Bildes wird unverschlüsselt im Windows Temp-Ordner gespeichert, beim Anzeigen der nächsten Datei aber sofort wieder mit dem neuen jpeg überschrieben.

Ich benötige jetzt ein Programm,dass die jpegs aus dem Temp-Ordner in einen anderen Ordner überträgt, bevor sie wieder überschrieben werden.

Es wäre ideal, wenn man nur den Quell- und Ziel-Ordner eingeben müsste und das Programm dann das Gewünschte automatisch erledigt.

Kann mir da jemand helfen?

Im Voraus vielen Dank

Carsten
 
Zuletzt bearbeitet:
Hab dir ein Programm erstellt. Die exe findest du im Anhang. Probier's mal aus. Ich hoffe ich hab deine Anforderung richtig verstanden.

Benötigt .NET 4.5

Hier der Code, falls er dich interessiert:

Form1.cs
Code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;

namespace CB_17062015
{
    public partial class Form1 : Form
    {
        private List<string> _listeSchonImZiel;
        private DirectoryInfo _quelle;
        private DirectoryInfo _ziel;
        FolderBrowserDialog fbdQ = new FolderBrowserDialog();
        FolderBrowserDialog fbdZ = new FolderBrowserDialog();

        public Form1()
        {
            InitializeComponent();
        }
        private void StartStop_Click(object sender, EventArgs e)
        {
            try
            {
                if (timer1.Enabled)
                {
                    timer1.Stop();
                    btnStartStop.Text = "Start";
                }
                else
                {
                    _quelle = new DirectoryInfo(txtQuelle.Text);
                    _ziel = new DirectoryInfo(txtZiel.Text);
                    FülleListeSchonImZiel();
                    timer1.Start();
                    btnStartStop.Text = "Stop";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                timer1.Stop();
                btnStartStop.Text = "Start";
            }
        }
        private void btnWähleQuelle_Click(object sender, EventArgs e)
        {
            if (fbdQ.ShowDialog() == DialogResult.OK)
            {
                txtQuelle.Text = fbdQ.SelectedPath;
            }
        }
        private void btnWähleZiel_Click(object sender, EventArgs e)
        {
            if (fbdZ.ShowDialog() == DialogResult.OK)
            {
                txtZiel.Text = fbdZ.SelectedPath;
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            Debug.Print("timer1_Tick");
            try
            {
                foreach (var f in _quelle.GetFiles())
                {
                    string hash = BerechneHash(f);
                    Debug.Print("Datei '{0}' Hashcode '{1}'", f.FullName, hash);
                    if (!_listeSchonImZiel.Contains(hash))
                    {
                        f.CopyTo(FügeHashAnDateiNameAn(f, hash));
                        _listeSchonImZiel.Add(hash);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                timer1.Stop();
                btnStartStop.Text = "Start";
            }
        }


        void FülleListeSchonImZiel()
        {
            Debug.Print("fülleListeSchonImZiel");
            _listeSchonImZiel = new List<string>();
            foreach (var f in _ziel.GetFiles())
            {
                string hash = BerechneHash(f);
                Debug.Print("Datei '{0}' Hashcode '{1}'", f.FullName, hash);
                _listeSchonImZiel.Add(hash);
            }
        }
        string BerechneHash(FileInfo fInfo)
        {
            FileStream fileStream = fInfo.Open(FileMode.Open);
            fileStream.Position = 0;
            RIPEMD160 myRIPEMD160 = RIPEMD160Managed.Create();
            byte[] hashValue = myRIPEMD160.ComputeHash(fileStream);
            StringBuilder sb=new StringBuilder();
            for (int i = 0; i < hashValue.Length; i++)
            {
                sb.Append(String.Format("{0:X2}", hashValue[i]));
            }
            fileStream.Close();
            return sb.ToString();
        }

        private string FügeHashAnDateiNameAn(FileInfo f, string hash)
        {
            string nurName=Path.GetFileNameWithoutExtension(f.Name);
            string extension = f.Extension;
            return Path.Combine(_ziel.FullName, nurName + "_" + hash + "." + extension);
        }
    }
}

Form1.Designer.cs
Code:
namespace CB_17062015
{
    partial class Form1
    {
        /// <summary>
        /// Erforderliche Designervariable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Verwendete Ressourcen bereinigen.
        /// </summary>
        /// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Vom Windows Form-Designer generierter Code

        /// <summary>
        /// Erforderliche Methode für die Designerunterstützung.
        /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.btnStartStop = new System.Windows.Forms.Button();
            this.txtQuelle = new System.Windows.Forms.TextBox();
            this.txtZiel = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.btnWähleQuelle = new System.Windows.Forms.Button();
            this.btnWähleZiel = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // btnStartStop
            // 
            this.btnStartStop.Location = new System.Drawing.Point(12, 100);
            this.btnStartStop.Name = "btnStartStop";
            this.btnStartStop.Size = new System.Drawing.Size(75, 23);
            this.btnStartStop.TabIndex = 0;
            this.btnStartStop.Text = "Start";
            this.btnStartStop.UseVisualStyleBackColor = true;
            this.btnStartStop.Click += new System.EventHandler(this.StartStop_Click);
            // 
            // txtQuelle
            // 
            this.txtQuelle.Location = new System.Drawing.Point(9, 25);
            this.txtQuelle.Name = "txtQuelle";
            this.txtQuelle.Size = new System.Drawing.Size(271, 20);
            this.txtQuelle.TabIndex = 2;
            this.txtQuelle.Text = "C:\\tmp\\testQuelle";
            // 
            // txtZiel
            // 
            this.txtZiel.Location = new System.Drawing.Point(12, 64);
            this.txtZiel.Name = "txtZiel";
            this.txtZiel.Size = new System.Drawing.Size(268, 20);
            this.txtZiel.TabIndex = 3;
            this.txtZiel.Text = "C:\\tmp\\testZiel";
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(6, 9);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(66, 13);
            this.label1.TabIndex = 4;
            this.label1.Text = "Quell-Ordner";
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(6, 48);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(59, 13);
            this.label2.TabIndex = 5;
            this.label2.Text = "Ziel-Ordner";
            // 
            // timer1
            // 
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            // 
            // btnWähleQuelle
            // 
            this.btnWähleQuelle.Location = new System.Drawing.Point(303, 25);
            this.btnWähleQuelle.Name = "btnWähleQuelle";
            this.btnWähleQuelle.Size = new System.Drawing.Size(75, 23);
            this.btnWähleQuelle.TabIndex = 6;
            this.btnWähleQuelle.Text = "wählen";
            this.btnWähleQuelle.UseVisualStyleBackColor = true;
            this.btnWähleQuelle.Click += new System.EventHandler(this.btnWähleQuelle_Click);
            // 
            // btnWähleZiel
            // 
            this.btnWähleZiel.Location = new System.Drawing.Point(303, 64);
            this.btnWähleZiel.Name = "btnWähleZiel";
            this.btnWähleZiel.Size = new System.Drawing.Size(75, 23);
            this.btnWähleZiel.TabIndex = 7;
            this.btnWähleZiel.Text = "wählen";
            this.btnWähleZiel.UseVisualStyleBackColor = true;
            this.btnWähleZiel.Click += new System.EventHandler(this.btnWähleZiel_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(380, 133);
            this.Controls.Add(this.btnWähleZiel);
            this.Controls.Add(this.btnWähleQuelle);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.txtZiel);
            this.Controls.Add(this.txtQuelle);
            this.Controls.Add(this.btnStartStop);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button btnStartStop;
        private System.Windows.Forms.TextBox txtQuelle;
        private System.Windows.Forms.TextBox txtZiel;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Timer timer1;
        private System.Windows.Forms.Button btnWähleQuelle;
        private System.Windows.Forms.Button btnWähleZiel;
    }
}
 

Anhänge

Vielen dank für deine Mühe und die superschnelle Beantwortung. Ob das Programm funktioniert, kann ich aber nicht prüfen.

Wenn ich es auf dem XP-Betriebssystem öffnen will, kommt immer der Hinweis, es sei keine zulässige WIN32-Anwendung. Das Programm zum Extrahieren der jpegs läuft leider nur bis XP und unter Win7 und neuer nicht.

Noch einmal zur Erläuterung der Anforderung: das Programm soll nur die nach dem Öffnen der Datei im Temp-Ordner abgelegte Graphik in den anderen Ordner speichern, nicht evtl noch hinzugekommene Zusatzdaten.

Der Ablauf geht so, dass ich die verschlüsselte Datei mit einem Viewer öffne. Dabei wird automatisch eine Kopie des angezeigten Bilds im temp-Ordner abgelegt. Die muss dann in dem anderen Ordner gespeichert werden, da sie beim Öffnen einer weiteren Datei mit der neuen Bilderkopie, die dann auch gespeichert werden soll, überschrieben wird.


Gruß, Carsten
Ergänzung ()

So, ich habe gerade die aktuelle Version des Viewers bekommen. Die läuft auch unter WIN7. Dein Progrämmchen aber nicht. Die Bilddatei wird mit der Endung .sbf zwar im Temp-Ordner abgelegt, von dem Tool aber nicht übernommen.

Stattdessen werden am Anfang eine Reihe von Dateien in den Zielordner gepackt, die mit dem Viewer nichts zu tun haben und das Programm bricht mit der folgenden Fehlermeldung ab: Der Prozess kann nicht auf...Quell-Ordner\adb.log... zugreifen, da sie von einem anderen Prozess genutzt wird.

Das hier funktioniert zwar prinzipiell, vergisst aber zwischendurch immer mal wieder Dateinen oder diese sind nicht lesbar, was bei datensätzen mit 500 oder mehr Bildern die bearbeitbarkeit zu stark behindert.:

Const tempPath = "Pfad eingeben"
Const copyToPath = "Pfad eingeben"

Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.CreateFolder("Pfad eingeben")
CreateFolderDemo = f.Path

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM __InstanceCreationEvent WITHIN 0.8 WHERE " _
& "TargetInstance ISA 'CIM_DirectoryContainsFile' AND " _
& "TargetInstance.GroupComponent = 'Win32_Directory.Name=""" _
& Replace(tempPath, "\", "\\\\") _
& """'")
Do
Set objEvent = colEvents.NextEvent()
On Error Resume Next
WScript.sleep 900
strFile = Replace(Replace(Split(objEvent.TargetInstance.PartComponent, "=")(1), "\\", "\"), """", "")
If 0 = StrComp(objFSO.GetExtensionName(strFile), "sbf", vbTextCompare) Then
objFSO.CopyFile strFile, copyToPath & "\" & objFSO.GetBaseName(strFile) & ".jpg", True
End If
On Error Goto 0
Loop


Gruß, Carsten
 
Zuletzt bearbeitet:
Hab das Programm angepasst. Es schaut jetzt nur nach Dateien mit der Endung .sbf. Wenn du auf Start klickst werden die Hashes aller sbf-Datein im Quellordner in einer Liste gespeichert, ebenso im Zielordner. Dann prüft das Programm jede Sekunde ob im Quellordner eine sbf-Datei ist, deren Hash in keiner der beiden Listen ist. Wenn das der Fall ist wird diese Datei in den Zielordner kopiert (wobei der Hash in den Dateinamen eingefügt wird, damit dieser eindeutig ist) und der Hash in der Liste gespeichert. Sollten Fehler auftreten, werden diese ohne Meldung ignoriert und das Programm arbeitet trotzdem weiter.

Ich bin nicht ganz sicher, was passiert, wenn mein Programm die Datei kopiert, während das andere Prorgamm sie gerade erst schreibt. Evtl. wird die Datei dann nur teilweise kopiert und ist somit ungültig. Im nächsten Zyklus, wenn sie vollständig ist, wird sie dann korrekt kopiert. Ist das schimm?

Da der Code nur jede Sekunde aufgerufen wird, gibt es Probleme, wenn die Datei von dem anderen Programm schneller überschrieben wird. Kommt das vor?

hier der angepasste Code:
Code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;

namespace CB_17062015
{
    public partial class Form1 : Form
    {
        private List<string> _listeSchonImZiel;
        private List<string> _listeVorherSchonInQuelle;

        private DirectoryInfo _quelle;
        private DirectoryInfo _ziel;
        FolderBrowserDialog fbdQ = new FolderBrowserDialog();
        FolderBrowserDialog fbdZ = new FolderBrowserDialog();

        public Form1()
        {
            InitializeComponent();
        }
        private void StartStop_Click(object sender, EventArgs e)
        {
            try
            {
                if (timer1.Enabled)
                {
                    timer1.Stop();
                    btnStartStop.Text = "Start";
                }
                else
                {
                    _quelle = new DirectoryInfo(txtQuelle.Text);
                    _ziel = new DirectoryInfo(txtZiel.Text);
                    try
                    {
                        FülleListeSchonImZiel();
                        FülleListeSchonInQuelle();
                    }
                    catch {/*Fehler ignorieren*/}
                    timer1.Start();
                    btnStartStop.Text = "Stop";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                timer1.Stop();
                btnStartStop.Text = "Start";
            }
        }
        private void btnWähleQuelle_Click(object sender, EventArgs e)
        {
            if (fbdQ.ShowDialog() == DialogResult.OK)
            {
                txtQuelle.Text = fbdQ.SelectedPath;
            }
        }
        private void btnWähleZiel_Click(object sender, EventArgs e)
        {
            if (fbdZ.ShowDialog() == DialogResult.OK)
            {
                txtZiel.Text = fbdZ.SelectedPath;
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            Debug.Print("timer1_Tick");
            try
            {
                foreach (var f in _quelle.GetFiles())
                {
                    if (f.Extension==".sbf")
                    {
                        try
                        {
                            string hash = BerechneHash(f);
                            Debug.Print("Datei '{0}' Hashcode '{1}'", f.FullName, hash);
                            if (!_listeVorherSchonInQuelle.Contains(hash))
                            {
                                if (!_listeSchonImZiel.Contains(hash))
                                {
                                    try
                                    {
                                        f.CopyTo(FügeHashAnDateiNameAn(f, hash));
                                        _listeSchonImZiel.Add(hash);
                                    }
                                    catch {/*Fehler ignorieren*/}
                                }
                            }
                        }
                        catch {/*Fehler ignorieren*/}
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                timer1.Stop();
                btnStartStop.Text = "Start";
            }
        }

        void FülleListeSchonInQuelle()
        {
            Debug.Print("FülleListeSchonInQuelle");
            _listeVorherSchonInQuelle = new List<string>();
            foreach (var f in _quelle.GetFiles())
            {
                if (f.Extension == ".sbf")
                {
                    string hash = BerechneHash(f);
                    Debug.Print("Datei '{0}' Hashcode '{1}'", f.FullName, hash);
                    _listeVorherSchonInQuelle.Add(hash);
                }
            }
        }

        void FülleListeSchonImZiel()
        {
            Debug.Print("fülleListeSchonImZiel");
            _listeSchonImZiel = new List<string>();
            foreach (var f in _ziel.GetFiles())
            {
                if (f.Extension == ".sbf")
                { 
                    string hash = BerechneHash(f);
                    Debug.Print("Datei '{0}' Hashcode '{1}'", f.FullName, hash);
                    _listeSchonImZiel.Add(hash);
                }
            }
        }
        string BerechneHash(FileInfo fInfo)
        {
            FileStream fileStream = fInfo.Open(FileMode.Open);
            fileStream.Position = 0;
            RIPEMD160 myRIPEMD160 = RIPEMD160Managed.Create();
            byte[] hashValue = myRIPEMD160.ComputeHash(fileStream);
            StringBuilder sb=new StringBuilder();
            for (int i = 0; i < hashValue.Length; i++)
            {
                sb.Append(String.Format("{0:X2}", hashValue[i]));
            }
            fileStream.Close();
            return sb.ToString();
        }

        private string FügeHashAnDateiNameAn(FileInfo f, string hash)
        {
            string nurName=Path.GetFileNameWithoutExtension(f.Name);
            string extension = f.Extension;
            return Path.Combine(_ziel.FullName, nurName + "_" + hash + "." + extension);
        }
    }
}

Anhang anzeigen CB_18062015.zip
 
Polling ist nicht so schön. Ich würde FileSystemWatcher verwenden. Muss man nur mit der Puffergröße aufpassen, falls sehr viele Änderungen auf einmal reinkommen. Es empfiehlt sich eine Queue zu verwenden, die in einem eigenen Thread abgearbeitet wird.
 
danke, das kannte ich noch nicht
 
Moin Moin,

jetzt funzt es teilweise. Ich habe mal nachgemessen: als ich das Programm mit der im Viewer enthaltenen Automatik durchlaufen lasse habe, wurde 24 Datensätze in 22 Sekunden bearbeitet. Die Zeit müsste also etwas kürzer als 1 sein.

Aber auch wenn ich die Datensätze im Viewer manuell weiterschalte, gibt es teilweise Probleme: ich bekomme da die Fehlermeldung "Fehler beim Öffnen der Datei". Wenn ich die wegklicke, ist das sbf-jpeg mit der jeweiligen Nummer (die bei den Datensätzen unterschiedlich ist, es wird durchgezählt) im Zielordner. Es passiert allerdings auch, dass die Datensätze ungestört durchlaufen, die sbf-jpegs aber nicht in den Zielordner übertragen werden, obwohl sie im temp-Ordner enthalten sind.
 

Ähnliche Themen

Zurück
Oben