115129
Goto Top

Dateien in einem Lokalordner verschieben auf Netzwerk-HDD, aber nur wenn Restkapazität auf Netzwerk-HDD ausreicht.

Hallo,

wie würde ein Batch-Script aussehen, das folgende Funktion erfüllen soll:

Verschiebe alle Dateien in C:\Test\ nach \\USB\HDD\ (ist eine Festplatte im Netzwerk), aber nur wenn Gesamtgröße der zu verschiebenden Dateien auf Netzwerk-HDD (3TB) mit bereits vorhandenen Dateien passt.
1. Ist \\USB\HDD\ erreichbar, wenn nicht nichts tun!
2. Prüfe C:\Test\ auf Inhaltsgröße
3. Prüfe \\USB\HDD\ auf Inhaltsgröße
4. Reicht Restkapazität von \\USB\HDD\ nicht aus, nichts tun!
5. Reicht Restkapazität von \\USB\HDD\ aus verschiebe Inhalt C:\Test\ nach \\USB\HDD\
Ich bin mir nicht 100% sicher, ich meine irgendwo gelesen zu haben, dass die Festplattengröße einer Netzwerk-HDD nicht übers Netzwerk ausgelesen werden kann...kann mich auch täuschen.
Bei meiner hab ich`s versucht, unter Eigenschaften bekomme ich 0Bytes angezeigt, aber vielleicht kommt man doch irgendwie dran?

Gibt's hierzu eine Lösung?

Mein derzeitiges Script sieht so aus:
@echo off
if exist \\USB\HDD goto MOVE
if not exist \\USB\HDD goto END

:MOVE
set mypath1=C:\Test
set mypath2=\\USB\HDD 
for %%i in ("%mypath1%\*.*") do move "%%i" "%mypath2%"  

:END
Vielen Dank schon mal face-smile

Grüße

Content-Key: 230554

Url: https://administrator.de/contentid/230554

Printed on: April 18, 2024 at 23:04 o'clock

Member: Pjordorf
Pjordorf Feb 21, 2014 at 00:55:12 (UTC)
Goto Top
Hallo,

Zitat von @115129:
Ich bin mir nicht 100% sicher, ich meine irgendwo gelesen zu haben, dass die Festplattengröße einer Netzwerk-HDD nicht übers Netzwerk ausgelesen werden kann...kann mich auch täuschen.
Das hängt aber auch von den OSen ab ob du überhaupt diese Info bekommst. Aber davon abgesehen, was ist wenn Platz zwar da, aber er trotzdem nicht reicht weil
- während du fleißig kopierst jemand anders schnell noch was drauf pappt (Zeitfaktor?)
- viele (kleine) Dateien hast die (zu viele) Sektoren belegen und damit deinen Platz aufbrauchen obwohl nur wenig von den Sektoren in Byte tatsächlich gebraucht wird? (Sektoren Größe)

Nur meine 2 Gedanken....

Gruß,
Peter
Member: Endoro
Endoro Feb 21, 2014 at 01:23:01 (UTC)
Goto Top
Hey,

wenn du über Windows Shares im "Heimnetzwerk" gehst (net use usw.), bekommst du auch den freien Platz "dir \\ComputerName\ShareName". Wegen der Rechnerei ist pure batch hier nicht besonders praktisch; VB oder PS böte sich an.
Gruss.
Mitglied: 115129
115129 Feb 21, 2014 updated at 08:05:55 (UTC)
Goto Top
Hallo Pjordorf,

- während du fleißig kopierst jemand anders schnell noch was drauf pappt (Zeitfaktor?)
...passiert nicht, ich bin der einzigste der verschieben darf und das soll nur über das Script passieren.

- viele (kleine) Dateien hast die (zu viele) Sektoren belegen und damit deinen Platz aufbrauchen obwohl nur wenig von den Sektoren
in Byte tatsächlich gebraucht wird? (Sektoren Größe)
...die Dateien die verschoben werden sind >500MB, zum anderen wenn das Script gestartet wird soll es Speicherplatz erfassen und wenn genug Platz vorhanden verschieben.

Grüße
Mitglied: 115129
115129 Feb 21, 2014 at 07:55:11 (UTC)
Goto Top
Hi Endoro,

nach so kurzer Zeit lese ich wieder von dir face-smile

wenn du über Windows Shares im "Heimnetzwerk" gehst (net use usw.), bekommst du auch den freien Platz
"dir \\ComputerName\ShareName". Wegen der Rechnerei ist pure batch hier nicht besonders praktisch; VB oder PS
böte sich an.
Nutze keine windowseigene Sharefunktion (Windows Mediashare oder wie das heißt), habe manuelle Ordnerfreigaben und Berechtigungen gesetzt.

Bist du den Sprachen VB oder PS ebenso mächtig? Dann lass mich ein Script testen face-smile

Grüße
Member: Endoro
Endoro Feb 21, 2014 at 10:06:09 (UTC)
Goto Top
Zitat von @115129:
Nutze keine windowseigene Sharefunktion (Windows Mediashare oder wie das heißt), habe manuelle Ordnerfreigaben und
Berechtigungen gesetzt.
Das meine ich, "Freigaben", wenn du am Server angemeldet bist bekommst du den freien Platz der Freigabe: "dir \\ComputerName\FreigabeName".

Bist du den Sprachen VB oder PS ebenso mächtig?
Leider nicht.
Gruss.
Mitglied: 115129
115129 Feb 21, 2014 at 10:10:33 (UTC)
Goto Top
Hi Endoro,

Das meine ich, "Freigaben", wenn du am Server angemeldet bist bekommst du den freien Platz der Freigabe: "dir\\ComputerName\FreigabeName"
Somit bekomme ich doch nur den Inhalt nicht aber die Kapazität gelistet!?
Member: Endoro
Endoro Feb 21, 2014 at 10:51:48 (UTC)
Goto Top
Nö, in der letzten Zeile steht "xx Bytes frei".
Mitglied: 115129
115129 Feb 21, 2014 at 11:16:09 (UTC)
Goto Top
Zitat von @Endoro:

Nö, in der letzten Zeile steht "xx Bytes frei".
Stimmt :p
Habe nun mal testweise ein Verzeichnis angelegt und ausgelesen (Teilausschnitt), allerdings lokal nicht übers Netzwerk (grad nicht zu Haus):
22.03.2012  18:34           711.552 DSC_0979.JPG
22.03.2012  18:38           714.673 DSC_0987.JPG
03.04.2012  06:16           642.990 DSC_0988.JPG
22.03.2012  18:41           699.108 DSC_0998.JPG
              92 Datei(en),     70.421.926 Bytes
               2 Verzeichnis(se), 182.986.862.592 Bytes frei
Wäre es möglich die Zeile "2 Verzeichnis(se), 182.986.862.592 Bytes frei" auszulesen und den Wert 182.986.862.592 Bytes für den Vergleich zu verwenden?
Oder rätst du definitiv zu einer anderen Sprache für diese Anwendung?

Grüße
Member: Pjordorf
Pjordorf Feb 21, 2014 at 11:46:46 (UTC)
Goto Top
Hallo,

Zitat von @115129:
allerdings lokal nicht übers Netzwerk (grad nicht zu Haus):
Was dann auch mit der Ausgabe (Rückgabe) deiner Netzwerk-HDD nicht übereinstimmen muss. Wir kennen noch nicht mal deine beteiligten Betreibssysteme um erkennen zu können wie diese dir deine Netzwerk-HDD bereitstellen und was dir bei einem Zugriff darauf an Informationen zurückgegeben werden.

Wäre es möglich die Zeile "2 Verzeichnis(se), 182.986.862.592 Bytes frei" auszulesen und den Wert 182.986.862.592 Bytes für den Vergleich zu verwenden?
Ja. Find ist dein Freund und du solltest dann nach "Bytes Frei" oder "Bytes free" oder soetwas suchen, was immer deine Netzwerk-HDD dir da anbietet. Und ja, je nach Betriebssystem und Sprache kann da auch ganz was anderes stehen.

Oder rätst du definitiv zu einer anderen Sprache für diese Anwendung?
Batch war noch nie gut in Rechnen, aber es kann. Schaust du Rechnen in Batch

Gruß,
Peter
Member: Endoro
Endoro Feb 21, 2014 updated at 12:33:20 (UTC)
Goto Top
Zitat von @115129:
Wäre es möglich die Zeile "2 Verzeichnis(se), 182.986.862.592 Bytes frei" auszulesen und den Wert
182.986.862.592 Bytes für den Vergleich zu verwenden?
Ja:
@ECHO OFF &SETLOCAL disableDelayedExpansion
FOR /f "tokens=3" %%a IN ('DIR /-c') DO SET "FreeBytes=%%a"  
ECHO(%FreeBytes%
Zum Vergleichen muss nicht zwingend gerechnet werden.
Member: Friemler
Solution Friemler Feb 21, 2014 updated at 16:27:57 (UTC)
Goto Top
Hallo BlattlausOG,

Batchscript ist im Zeitalter von Zig-Gigabyte-Festplatten für die Lösung Deines Problems nicht geeignet. Die Krux steht auch in dem von @Pjordorf verlinkten Beitrag:
32Bit-Integer mit negativen Ergebnissen

Positive Werte haben somit nur einen Wertebereich bis 2^31 - 1 = 2.147.483.647. Daher würde schon der freie Festplattenplatz aus Deinem Beispiel die Batch-Arithmetik auf die Bretter schicken, denn solch einen Wert könnte man auch nicht durch Division mit 1024 für die weitere Verarbeitung kleiner machen.

Deshalb hier ein Vorschlag mit einem Inline-VBScript, das nur ermittelt, ob auf dem Ziel genug freier Platz vorhanden ist:
@echo off & setlocal

set "SrcPath=C:\Test"  
set "DstPath=\\USB\HDD"  


set "VBScript=%TEMP%\DestFitsSize.vbs"  

> "%VBScript%" echo Set objFSO = CreateObject("Scripting.FileSystemObject")  
>>"%VBScript%" echo.  
>>"%VBScript%" echo strSrcPath = WScript.Arguments(0)  
>>"%VBScript%" echo strDstPath = WScript.Arguments(1)  
>>"%VBScript%" echo.  
>>"%VBScript%" echo dblSrcSize = objFSO.GetFolder(strSrcPath).Size  
>>"%VBScript%" echo dblDstSize = objFSO.GetDrive(objFSO.GetDriveName(strDstPath)).FreeSpace  
>>"%VBScript%" echo.  
>>"%VBScript%" echo If dblDstSize ^> dblSrcSize Then  
>>"%VBScript%" echo   WScript.Quit 0  
>>"%VBScript%" echo Else  
>>"%VBScript%" echo   WScript.Quit 1  
>>"%VBScript%" echo End If  


if not exist "%DstPath%" goto :Terminate  
cscript /nologo "%VBScript%" "%SrcPath%" "%DstPath%" || goto :Terminate  
for %%i in ("%SrcPath%\*.*") do move "%%i" "%DstPath%"  


:Terminate
del "%VBScript%"  

Die Zeilen 3 und 4 musst Du anpassen.

Gruss
Friemler
Member: Endoro
Endoro Feb 21, 2014 at 13:59:12 (UTC)
Goto Top
Zitat von @Friemler:

Hallo BlattlausOG,

Batchscript ist im Zeitalter von Zig-Gigabyte-Festplatten für die Lösung Deines Problems nicht geeignet.

Das würd ich so apodiktisch nicht sehen.
Aber weil bald Wochenende ist mag ich den Beweis jetzt nicht führen face-smile
Gruss.
Member: Friemler
Friemler Feb 21, 2014 at 14:49:55 (UTC)
Goto Top
Hallo Endoro,

schon klar, man könnte auch sowas benutzen:
@echo off & setlocal

set "SrcPath=C:\Test"  
set "DstPath=\\USB\HDD"  

if not exist "%DstPath%" goto :EOF  

for /f "tokens=3" %%s in ('dir /d /-c "%SrcPath%" ^| find /i "Datei(en)"') do set "SrcSize=0000000000000000000%%s"  
for /f "tokens=3" %%d in ('dir /d /-c "%DstPath%" ^| find /i "Verzeichnis(se)"') do set "DstSize=0000000000000000000%%d"  

set "SrcSize=%SrcSize:~-20%"  
set "DstSize=%DstSize:~-20%"  

if "%DstSize%" gtr "%SrcSize%" (  
  for %%i in ("%SrcPath%\*.*") do move "%%i" "%DstPath%"  
)

Aber was ist, wenn das Quellverzeichnis ein verschachtelter Verzeichnisbaum mit Unterverzeichnissen ist? Die Größe der dort enthaltenen Dateien kann man aufgrund der beschränkten Möglichkeiten der Batch-Arithmetik durch rekursives Durchwandern des Verzeichnisbaums und Addition der Dateigrößen in den einzelnen Verzeichnissen nicht ermitteln. Der obige VBScript-Schnipsel muss dazu noch nicht einmal geändert werden.

Außerdem lauert bei der Batch-Lösung noch das Problem, dass man sich auf ein deutsches Windows festlegt:
find /i "Datei(en)"

Alles mit Batchscript zu lösen ist zwar eine sportliche Herausforderung, man muss aber schon aufpassen, dass da nicht der Spieltrieb mit einem durchgeht. face-wink

Gruß
Friemler
Member: Endoro
Endoro Feb 21, 2014 at 15:24:14 (UTC)
Goto Top
Hallo @Friemler,

Zitat von @Friemler:

Hallo Endoro,

schon klar, man könnte auch sowas benutzen:

Ja genau, es geht sogar noch schicker.


Aber was ist, wenn das Quellverzeichnis ein verschachtelter Verzeichnisbaum mit Unterverzeichnissen ist? Die Größe der
dort enthaltenen Dateien kann man aufgrund der beschränkten Möglichkeiten der Batch-Arithmetik durch rekursives
Durchwandern des Verzeichnisbaums und Addition der Dateigrößen in den einzelnen Verzeichnissen nicht ermitteln.

Doch, dir /s zeigt das für einen Verzeichnisbaum richtig an. Zur Not könnte man noch Links/Junctions anlegen, wenn es um mehrere geht.

Außerdem lauert bei der Batch-Lösung noch das Problem, dass man sich auf ein deutsches Windows festlegt:

Keineswegs:
@ECHO OFF &SETLOCAL disableDelayedExpansion
FOR /f "tokens=3" %%a IN ('DIR /-c /s') DO (  
	CALL SET "FileSize=%%FreeBytes%%"  
	SET "FreeBytes=%%a"  
)
ECHO(%FileSize%
Aber du hast insofern recht, als dass es mit einem koreanischen Windows vielleicht nicht läuft.

Alles mit Batchscript zu lösen ist zwar eine sportliche Herausforderung, man muss aber schon aufpassen, dass da nicht der Spieltrieb mit einem durchgeht.

Dafür lieben wir es, dafür tun wir es face-big-smile
Gruss, und schönes Wochenende!
Member: Friemler
Friemler Feb 21, 2014 at 16:25:09 (UTC)
Goto Top
Zitat von @Endoro:

Dafür lieben wir es, dafür tun wir es

Auch wieder wahr. face-big-smile

Auch Dir ein schönes WE.

Gruß
Friemler
Mitglied: 115129
115129 Feb 21, 2014 updated at 16:30:00 (UTC)
Goto Top
> @echo off & setlocal
> 
> set "SrcPath=C:\Test"  
> set "DstPath=\\USB\HDD"  
> 
> 
> set "VBScript=%TEMP%\DestFitsSize.vbs"  
> 
> > "%VBScript%" echo Set objFSO = CreateObject("Scripting.FileSystemObject")  
> >>"%VBScript%" echo.  
> >>"%VBScript%" echo strSrcPath = WScript.Arguments(0)  
> >>"%VBScript%" echo strDstPath = WScript.Arguments(1)  
> >>"%VBScript%" echo.  
> >>"%VBScript%" echo dblSrcSize = objFSO.GetFolder(strSrcPath).Size  
> >>"%VBScript%" echo dblDstSize = objFSO.GetDrive(objFSO.GetDriveName(strDstPath)).FreeSpace  
> >>"%VBScript%" echo.  
> >>"%VBScript%" echo If dblDstSize ^> dblSrcSize Then  
> >>"%VBScript%" echo   WScript.Quit 0  
> >>"%VBScript%" echo Else  
> >>"%VBScript%" echo   WScript.Quit 1  
> >>"%VBScript%" echo End If  
> 
> 
> if not exist "%DstPath%" goto :Terminate  
> cscript /nologo "%VBScript%" "%SrcPath%" "%DstPath%" || goto :Terminate  
> for %%i in ("%SrcPath%\*.*") do move "%%i" "%DstPath%"  
> 
> 
> :Terminate
> del "%VBScript%"  
> 

Die Zeilen 3 und 4 musst Du anpassen.

Hallo Friemler,

habe deinen vorgeschlagenen Code angepasst und getestet, funktioniert genau so, wie ich es mir vorgestellt hatte.

Werde nun das Script auf meine Anwendung ansetzen, daher schließe ich diesen Thread noch nicht, vielleicht tritt noch ein Problem auf.

Besten Dank und Grüße aus dem Süden Deutschlands face-smile