• Status: Solved
  • Priority: Low
  • Security: Public
  • Views: 32
  • Last Modified:

Help with batch file that compares file size to available space

I need a batch file created that can replace a broken backup feature of an old program. I need the batch file to look at the size of the file that will be backed up, compare it to the available space on the F: drive. If there is space, then it copies the file, if there isn't space, then it deletes the oldest file in the destination to make room for a new file.

Basically, I'm backing up one file, once per day, and just need to make sure that that the drive has space before copying. My current batch file is:
@echo off
set mydate=%date:~4,2%_%date:~7,2%_%date:~10,4%
copy /z "C:\Program Files (x86)\Camelot3\Database\CAMDB.FDB" "F:\Camelot\Camdb_%mydate%.fdb

This is just so that I can keep multiple copies of this file
0
einsteinq
Asked:
einsteinq
  • 7
  • 5
3 Solutions
 
Bill PrewCommented:
This is a little harder than you might think in a BAT script, because it is limited in the precision of numbers (integer only) that it can deal with.  Typically free space on a disk will be larger than the precision it can handle.  There are some ways to work around that though, but I'd like to understand a little better.

How large is the target drive?

How large (in bytes) are the files being backed up?

What if removing the oldest file doesn't result in enough space, should the next oldest also be removed, etc?

When finding the oldest file, is it true that all files in the folder need to be looked at, or only a certain filter of them (like *.FDB)?


»bp
0
 
einsteinqAuthor Commented:
This file is slightly smaller than 1GB, the destination is a 16GB flash drive. The only thing in the Camelot folder on the flash drive is this backup. If I can keep the last 10 days worth of backups, that would be great.
0
 
Bill PrewCommented:
I haven't tested this here, so don't test it immediately against useful data just in case...

I added comments, hopefully it makes sense, take a look, and think about what's going on to double check my thought process.

You might want to add some ECHO statements along the way and PAUSE a few times to make sure the variables are being set as expected, and the flow is as expected.

@echo off
setlocal EnableDelayedExpansion

rem Build date string for new backup copy
set MyDate=%DATE:~4,2%_%DATE:~7,2%_%DATE:~10,4%

rem Define source and destination paths
set BaseDir=C:\Program Files (x86)\Camelot3\Database
set DestDir=F:\Camelot
set BaseFile=%BaseDir%\CAMDB.FDB
set DestFile=%DestDir%\Camdb_%MyDate%.fdb

rem Make sure the file to backup exists
if not exist "%BaseFile%" (
    echo *ERROR* database file to backup does not exist
    exit /b
)

rem Make sure the dest folder exists, create it if needed
if not exist "%DestDir%" (
    mkdir "%DestDir%"
)

rem Get size (in bytes) of current file, left pad to build 16 byte string of size
for %%A in ("%BaseFile%") do set BaseSize=%%~zA
set BaseSize=0000000000000000%BaseSize%
set BaseSize=%BaseSize:~-16%

:CheckSpace

rem Get free space (in bytes) of dest drive, left pad to build 16 byte string of size
for /f "tokens=3" %%A in ('dir "%DestDir%"\^|find /i "bytes free"') do set "DestFree=%%A"
set DestFree=0000000000000000%DestFree%
set DestFree=%DestFree:~-16%

rem If this file won't fit, try to delete oldest backup
if "%BaseSize%" GTR "%DestFree%" (

    rem Doesn't fit, look for oldest file to delete
    set DeleteFile=
    for /f "tokens=*" %%A ('dir /a-d /b /o-d "%DestDir%"') do set DeleteFile=%DestDir%\%%~A

    rem If no files to delete in destination folder error out
    if not defined DeleteFile (
        echo *ERROR* No room for backup copy on destination drive, quiting
        exit /b
    )

    rem Delete oldest file, check if it fits now
    del "!DeleteFile!" >NUL
    goto :CheckSpace
)

rem Since it should fit, copy it now
copy /z "%BaseFile%" "%DestFile%"

Open in new window


»bp
1
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
einsteinqAuthor Commented:
I tested on the backup  test server i created during this super long recovery I've been doing. I've attached the error I'm getting.

BTW, Thanks so much.
BatchCapture.JPG
0
 
Bill PrewCommented:
Looks like I made a typo, change:

   for /f "tokens=*" %%A ('dir /a-d /b /o-d "%DestDir%"') do set DeleteFile=%DestDir%\%%~A

to:

   for /f "tokens=*" %%A in ('dir /a-d /b /o-d "%DestDir%"') do set DeleteFile=%DestDir%\%%~A


»bp
0
 
einsteinqAuthor Commented:
YOU ARE THE MAN!!! You are my savior!

Under normal circumstances, I usually could come up with something that accomplished this job in a far less elegant way. But, after staying up all night, recovering this clients haphazardly assembled server, only to find that the backup they've been doing didn't even contain the most important data, and then breaking my glasses while trying to make this batch file, I was ready to give up and call an Uber home (because I can't drive without my glasses).
0
 
Bill PrewCommented:
Great, glad that was helpful, thanks for the feedback...


»bp
0
 
einsteinqAuthor Commented:
Turns out that I celebrated too soon. I forgot to make sure that it deleted the oldest file if the drive was full. That part doesn't work.
0
 
Bill PrewCommented:
Sorry, was away on holiday, and then took ill for a bit, do you still need additional help with this?  If so can you post some additional info about the test you did, the setup for it, the results, and what your expected results were please.


»bp
0
 
Bill PrewCommented:
Okay, made several adjustments, see if this deletes older file(s).

@echo off
setlocal EnableDelayedExpansion

rem Build date string for new backup copy
set MyDate=%DATE:~4,2%_%DATE:~7,2%_%DATE:~10,4%

rem Define source and destination paths
set BaseDir=C:\Program Files (x86)\Camelot3\Database
set DestDir=F:\Camelot
set BaseFile=%BaseDir%\CAMDB.FDB
set DestFile=%DestDir%\Camdb_%MyDate%.fdb

rem Make sure the file to backup exists
if not exist "%BaseFile%" (
    echo *ERROR* database file to backup does not exist
    exit /b
)

rem Make sure the dest folder exists, create it if needed
if not exist "%DestDir%" (
    mkdir "%DestDir%"
)

rem Get size (in bytes) of current file, left pad to build 16 byte string of size
for %%A in ("%BaseFile%") do set BaseSize=%%~zA
set BaseSize=0000000000000000%BaseSize%
set BaseSize=%BaseSize:~-16%

:CheckSpace

rem Get free space (in bytes) of dest drive, left pad to build 16 byte string of size
for /f "tokens=3" %%A in ('dir "%DestDir%"\^|find /i "bytes free"') do set "DestFree=%%A"
set DestFree=!DestFree:,=!
set DestFree=0000000000000000!DestFree!
set DestFree=!DestFree:~-16!

rem If this file won't fit, try to delete oldest backup
if "%BaseSize%" GTR "!DestFree!" (

    rem Doesn't fit, look for oldest file to delete
    set DeleteFile=
    for /f "tokens=*" %%A in ('dir /a-d /b /o-d "%DestDir%"') do set DeleteFile=%DestDir%\%%~A

    rem If no files to delete in destination folder error out
    if not defined DeleteFile (
        echo *ERROR* No room for backup copy on destination drive, quiting
        exit /b
    )

    rem Delete oldest file, check if it fits now
    del "!DeleteFile!" >NUL
    goto :CheckSpace
)

rem Since it should fit, copy it now
copy /z "%BaseFile%" "%DestFile%"

Open in new window


»bp
0
 
einsteinqAuthor Commented:
I tested this one extensively, and it works awesome. Thanks.
0
 
Bill PrewCommented:
Great, glad that helped.

~bp
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 7
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now