Laden...

Dateien kopieren (cmd->copy)

Erstellt von Tanner vor 15 Jahren Letzter Beitrag vor 15 Jahren 3.077 Views
T
Tanner Themenstarter:in
19 Beiträge seit 2007
vor 15 Jahren
Dateien kopieren (cmd->copy)

Hallo zusammen,

wie schon im Titel ersichtlich möchte ich Dateien (mp3 zum Beispiel) wie über Kommandozeile binär addieren. Das ganze mache ich per copy Befehl im Command-Fenster so:

copy /b "datei1.mp3" +"datei2.mp3" "zieldatei.mp3"

Dadurch werden die zwei Dateien in die Datei "zieldatei.mp3" kopiert.
Das ganze möchte ich jetzt in C# umsetzen.
Habe also eine kleine GUI, in der ich meine Dateien zusammensuchen und einen Zielpfad angeben kann. Dann versuche ich wie folgt die Operation durchzuführen:

internal bool copyToOne(List<DataManager> listSources, DataManager destinationFile)
        {
            bool ret = false;
            try
            {
                System.String command = "copy /b ";
                bool firstFile = true;
                bool fFile = true;
                for (int i = 0; i < listSources.Count; ++i)
                {
                    
                    DataManager tmpManager = listSources[i];
                    if (fFile)
                    {
                        fFile = false;
                        command += "\"" + tmpManager.FileName + "\" ";
                    }
                    else
                    {
                        command += "+\"" + tmpManager.FileName + "\" ";
                    }
                }
                command += destinationFile.Folder + destinationFile.Name;
                ExecuteCommand(command);
            }
            catch (System.Exception ex)
            {
                err.showError(ex);
            }
            return ret;
        }

        private bool ExecuteCommand(System.String command)
        {
            bool ret = false;
            try
            {
                System.Diagnostics.ProcessStartInfo procStartInfor = new System.Diagnostics.ProcessStartInfo("cmd","/k " + command);
                procStartInfor.RedirectStandardInput = true;
                procStartInfor.UseShellExecute = false;
                procStartInfor.CreateNoWindow = false;
                System.Diagnostics.Process proc = new System.Diagnostics.Process();
                proc.StartInfo = procStartInfor;
                proc.Start();

            }
            catch(System.Exception ex)
            {
                err.showError(ex);
            }
            return ret;
        }
    

Ich bekomme keine Fehlermeldung. Lustigerweise kann ich auch eine einzelne Datei kopieren. Sobald ich aber zwei Dateien ausgewählt habe, bekomme ich keine Zieldatei erstellt. Es passiert scheinbar gar nichts.
Im Debug-Modus habe ich gesehen, dass der String, der erzeugt wird und als command übergeben wird korrekt ist. Das heisst, wenn ich ihn aus der Variable herauskopiere und in ein Command-Fenster schreibe, dann wird alles wie gewünscht ausgeführt, wenn das Programm das übernnimmt, dann funktioniert es nicht.
Wäre super, wenn mir jemand einen Tipp geben könnte, ob das irgendwie funktioniert.

Wenn es auf diesem Wege nicht funktioniert, gibt es dann einen anderen (performanten) Weg, mp3's zu addieren? Einlesen und binär addieren und rausschreiben sollte ziemlich speicherlastig sein, schätze ich. Würde mich über Hilfe freuen.

Gruß, Tanner

3.430 Beiträge seit 2007
vor 15 Jahren

Hallo Tanner,

bist du dir sicher dass der von deinem Programm erstelle Pfad auch richtig ist?
tmpManager.FileName gibt das den ganzen Pfad zurück oder nur den FileName?
Denn wenn letzteres der Fall ist so könntest du das Problem haben dass du dich mit deinem erstellen Prozess dann nicht im richtigen Folder befindest und dass somit die Dateien nicht gefunden werden können.

Hast du beim Debuggen kontrolliert ob er bis zum Starten des Prozesses kommt?
Wenn ja versuche mal das Fenster von der Konsole sichtbar zu machen und dann schaust du nach was die Konsole für einen Fehler ausspuckt.

Grüsse
Michael

T
Tanner Themenstarter:in
19 Beiträge seit 2007
vor 15 Jahren

Hallo Michael,

ja, der Pfad ist definitiv der komplette Pfad zur Zieldatei. Daran kann es also nicht liegen.
Das Fenster schließt sich leider immer viel zu schnell, so dass ich nicht wirklich sehen kann, was genau passiert.
Wie gesagt, das wunderliche ist ja, dass das kopieren ohne "addieren" funktioniert. Wenn also nur eine Datei ausgewählt ist, wird diese ganz ordnungsgemäß in die angegebene Zieldatei kopiert. Nur, wenn zwei oder mehr Dateien ausgewählt sind, dann passiert gar nichts...

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Tanner,

vergiss das mit dem copy mal. Für sowas brauchst du keinen extern Befehl. Lies einfach beide Dateien ein und schreibe sie in die Zieldatei. Siehe [Tutorial] Alles über Dateien 2.2.

herbivore

T
Tanner Themenstarter:in
19 Beiträge seit 2007
vor 15 Jahren

Hallo Herbivore,

das habe ich mir auch schon überlegt.
Aber wie ist das mit großen Dateien?
Nehmen wir mal an, mein Festplattenrecorder nimmt einen langen Film auf. Dieser wird in Stücke aufgeteilt, die jeweils ca. 1GB groß sind. Insgesamt kommen 5-6 GB zusammen. Dann funktioniert die Copy-Methode von Windows immer noch. Aber die Dateien einladen und dann selbst addieren sollte einen ziemlichen Speicherbedarf haben...
Oder sehe ich das falsch?

309 Beiträge seit 2007
vor 15 Jahren

Aber die Dateien einladen und dann selbst addieren sollte einen ziemlichen Speicherbedarf haben...
Oder sehe ich das falsch?

Wo steht, dass du die Dateien komplett laden musst???

Wenn du möchtest (im Extremfall 😄) kannst du die Dateien sogar Byte weise lesen und schreiben ... Halt nur 5-6 Milliarden mal ... 8o

(Aber wozu gibt es Buffer ...)

mfg Hajoseb

**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France

T
Tanner Themenstarter:in
19 Beiträge seit 2007
vor 15 Jahren

Hallo Hajoseb,

stimmt, an die Möglichkeit das so zu machen hab ich gar nicht gedacht.
Wie performant wäre das denn wohl, wenn ich die Dateien auf diese Weise laden und schreiben würde? Und mit welchen Mitteln mache ich sowas am besten?

Der Ablauf wäre doch dann wohl so:

  1. Neue Datei erstellen und zum binären schreiben öffnen
  2. Erste Teildatei einladen und in Zieldatei schreiben
  3. Erste Teildatei aus Speicher entladen
  4. Zweite Teildatei einladen und in Zieldatei schreiben
  5. ....
    n. Neue Datei schließen und glücklich sein.

Hab ich das so richtig verstanden?

Gruß, Tanner

5.742 Beiträge seit 2007
vor 15 Jahren

Hab ich das so richtig verstanden?

Nicht ganz.
1.Neue Datei erstellen und zum binären Schreiben öffnen 1.Die erste Teildatei zum Lesen öffnen 1.In einer Schleife immer x bytes (in einen Buffer) der ersten Teildatei einlesen und in die Zieldatei schreiben. 1.Erste Teildatei schließen 1....

So hast du zu keinem Zeitpunkt eine Teildatei vollständig im Speicher.

T
Tanner Themenstarter:in
19 Beiträge seit 2007
vor 15 Jahren

Hey, super, so klappt das ganze echt wunderbar!
Für alle die es interessiert, ich habe das ganze jetzt so gelöst:

internal bool binaryCopyToOne(List<DataManager> listSources, DataManager destinationFile)
        {
            bool ret = false;
            try
            {
                FileStream destFile = new FileStream(destinationFile.FileName, FileMode.Create, FileAccess.Write);

                for (int i = 0; i < listSources.Count; ++i)
                {
                    FileStream sourceFile = new FileStream(listSources[i].FileName, FileMode.Open, FileAccess.Read);
                    
                    byte[] streamBuffer = new byte[32768];
                    int remain = (int)streamBuffer.Length;
                    int offset = 0;

                    int read;
                    while ((read = sourceFile.Read(streamBuffer, offset, remain)) > 0)
                    {
                        destFile.Write(streamBuffer, offset, remain);                            
                    }
                    sourceFile.Close();
                }
                destFile.Close();

            }
            catch (System.Exception e)
            {
                err.showError(e);
            }
            return ret;
        }

Danke an alle, die mir geholfen haben!