create dummy files of exact size

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
Sponge Belly
Posts: 231
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

create dummy files of exact size

#1 Post by Sponge Belly » 10 May 2014 16:45

Hello All! :-)

Apropos nothing, here’s a working draft of a subroutine to create a dummy file with the exact size of the original. Works up to the Batch limit. Never more than 58 passes (I think!) and no use of goto.

The idea is simple enough: keep all the temp files that double in size until the power of two before or equal to the original file size is reached, and re-use them on the way down to fill in the remainder. But I found the logic hard to nail down… either that or my wits aren’t as sharp as they used to be. ;-)

Code: Select all

@echo off & setlocal enableextensions enabledelayedexpansion
(call;)

set fsize=%~z1
set /a %fsize% 2>nul || goto die
if %fsize% equ 0 goto die

<nul set /p "=#" >dummy.txt

set /a p2=1,p2x2=2 & set "stub="
echo(| cmd /v:on /q /c for /l %%l in (^) do if not defined stub (^
if %fsize% geq ^^!p2x2^^! (type dummy.txt ^>dummy-^^!p2^^!.txt ^& ^
type dummy-^^!p2^^!.txt ^>^>dummy.txt ^& ^
set /a p2*=2,p2x2=p2*2 ^>nul^) else set /a stub=fsize - p2 ^>nul^) ^
else if ^^!stub^^! gtr 0 (set /a p2/=2 ^>nul ^& ^
if ^^!stub^^! geq ^^!p2^^! (set /a stub-=p2 ^>nul ^& ^
type dummy-^^!p2^^!.txt ^>^>dummy.txt^)^) else exit 0
del "dummy-*.txt"
goto end

:die
2>&1 echo(unexpected end of program
(call)
:end
endlocal & goto :eof


Next phase is beautification, adding options, etc. But before I go further, I thought I’d post it here in case anyone can spot some obvious inefficiency in the code. Constructive criticism appreciated!

- SB

einstein1969
Expert
Posts: 961
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: create dummy files of exact size

#2 Post by einstein1969 » 10 May 2014 17:56

hi Sponge Belly!

this work and is simple and fast. what do you think?

Code: Select all

@echo off & setlocal EnableDelayedExpansion

type nul > dd.tmp
<nul >d.tmp set /p ".=@"
set /a "ds=%~z1"
for /l %%n in (1,1,32) do (
  set /a "r=ds %% 2, ds/=2"
  if !r! equ 1 type d.tmp >>dd.tmp
  if !ds! gtr 0 type d.tmp >>d.tmp
)
del d.tmp

rem check the result
dir dd.tmp

exit /b


the same with some debug info:

Code: Select all

@echo off & setlocal EnableDelayedExpansion

echo %time%
type nul > dd.tmp
<nul >d.tmp set /p ".=@"
set /a "ds=%~z1"
for /l %%n in (1,1,32) do (
  set /a "r=ds %% 2, ds/=2"
  if !r! equ 1 (
        for %%T in (dd.tmp) do for %%U in (d.tmp) do echo %%~zT + %%~zU
        type d.tmp >>dd.tmp
        for %%T in (dd.tmp) do echo          = %%~zT
  )
  if !ds! gtr 0 type d.tmp >>d.tmp
)
del d.tmp
echo %time%

rem check the result
dir dd.tmp

exit /b


Edit: This version replace the previous that has a bug.
Edit2: Added info for debug
Edit3: Previous replace failed :D . I do now!

einstein1969
Last edited by einstein1969 on 14 May 2014 17:00, edited 5 times in total.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: create dummy files of exact size

#3 Post by foxidrive » 10 May 2014 23:44

Just adding in the thread that there is a tool in Windows to do this.

Code: Select all

fsutil file createnew file.ext 1000

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: create dummy files of exact size

#4 Post by Squashman » 11 May 2014 10:26

Have some code from Dave in a batch file he helped me with in one my threads. Will have to go find that.

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: create dummy files of exact size

#5 Post by penpen » 11 May 2014 11:51

Both versions don't work as expected, if cmd is using unicode ("cmd /U").
You may add something like this:

Code: Select all

if not "%~1" == "initialized" (
   cmd /A "%~f0" "initialized" "%*"
   exit /b %ErrorLevel%
)

penpen

Edit: Removed some minor bugs.
Last edited by penpen on 17 May 2014 08:34, edited 2 times in total.

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: create dummy files of exact size

#6 Post by Aacini » 11 May 2014 12:17

You may also use my FilePointer.exe auxiliary program to create a file of any size (up to 2 GB):

Code: Select all

(FilePointer 1 998 /E & echo/) > file1000.txt

Antonio

Sponge Belly
Posts: 231
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: create dummy files of exact size

#7 Post by Sponge Belly » 14 May 2014 14:27

Wow! :!:

Thanks to everyone for their great feedback. :-)

@Einstein1969:
Interesting approach. I mean to put your code under the microscope when I have more time. A quick test on a file 1049 bytes long created dd.tmp which was also 1049 bytes. Unfortunately, another file called d.tmp was left over after execution. It had a length of 2048 bytes.

@FoxiDrive:
The trouble with fsutil is that it needs to be run by admin on Vista and later. And it fills the file with NULs and not a char of the user’s choosing… which is an option I intend to add in a later version. ;-)

@Squashman:
Don’t keep me on tenter hooks! Please find the link to the code you mentioned when you have a chance, thanks.

@Penpen:
Thanks! I didn’t think of that. The /a switch will be added to the next version.

@Aacini:
Your filepointer program would be overkill for the creation of dummy files, imho… but if I was using fp in the same program already, it would be the simplest solution by far.

Stay tuned for updates!

- SB

einstein1969
Expert
Posts: 961
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: create dummy files of exact size

#8 Post by einstein1969 » 14 May 2014 17:02

Hi SB,

my mistake! I have not update the post with right version. I do now!

einstein1969

siberia-man
Posts: 208
Joined: 26 Dec 2013 09:28
Contact:

Re: create dummy files of exact size

#9 Post by siberia-man » 14 May 2014 18:07

One more good solution inspired by this response http://stackoverflow.com/a/808249/3627676

Code: Select all

powershell -c "$f = New-Object System.IO.FileStream '.\filename.txt', Create, ReadWrite; $f.SetLength(4GB); $f.Close()"


As the bonus it allows to define the file size as a number or in symbolic form (as 4GB for 4 gigabytes in the example above)

Sponge Belly
Posts: 231
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: create dummy files of exact size

#10 Post by Sponge Belly » 15 Sep 2014 14:30

Hi Again! :)

Sorry for the delay, but I’m easily… oh look, a shiny object!

Anyways, I’ve rewritten the code to create a dummy file that has the same size as the original. The program accepts two arguments: the original filename (required); and the ASCII code of the fill character (0 by default). If all goes well, a file called “dummy.txt” will be created in the current directory.

Code: Select all

@if (@X==@Y) @then
:: Batch
@echo off & rem creates dummy file with same size as original
setlocal enableextensions disabledelayedexpansion
set "sp= " & set "arg1=%~1"
if defined arg1 (set arg1 | findstr /ivx "arg1=\/ascii" >nul
) else (>&2 echo(file name expected & goto die)
if %errorlevel% equ 0 (cmd /d /a /c call "%~dpnx0" /ascii %*%sp%
goto end)

shift /1
call :makeDummy "%~1" "%~2"
goto end

:die
(call)
:end
endlocal & goto :eof

:makeDummy
setlocal disabledelayedexpansion
set "fileSize=%~z1"
if not defined fileSize (>&2 echo(file "%~1" not found & goto die
) else if "%fileSize%"=="0" (>&2 echo(file "%~1" is empty & goto die)

set /a "asc=%~2"
if not defined asc set "asc=0"
rem http://consolesoft.com/batch/binary/genchr.txt
call :genChr %asc%
move /y "%asc%.chr" "dummy.txt" >nul

for /f "delims=" %%X in ('
cscript //nologo //e:jscript "%~dpnx0" %fileSize%
') do set "expStr=%%X"

set "x=0" & set "exp="
echo(|cmd /v:on /q /c for /l %%I in (^) do (^
(if not defined exp for /f %%A in ("!expStr!"^) do ^
set "exp=%%A"^) ^& (if ^^!x^^! equ ^^!exp^^! (^
for %%B in (^^!exp^^!^) do set "expStr=!expStr: %%B = !" ^& ^
(if "!expStr!"==" " exit 0^) ^& ^
type "dummy.txt" ^>"dummy-!x!.txt" ^& set "exp="^)^) ^& ^
type "dummy.txt" ^>^>"dummy.txt" ^& set /a x+=1 ^>nul^)
2>nul type "dummy-*.txt" >>"dummy.txt"
del "dummy-*.txt"
goto end

:die
endlocal & exit /b 1
:end
endlocal & exit /b 0

@end // JScript

// http://bocoup.com/weblog/find-the-closest-power-of-2-with-javascript/

var fileSize = WScript.Arguments.Item(0);
var p2Str = "";
var leqExp, leqPow2, diff;

do {
    leqExp = Math.floor(Math.log(fileSize) / Math.log(2));
    leqPow2 = Math.pow(2, leqExp);
    diff = fileSize - leqPow2;
    p2Str = leqExp+" "+p2Str;
    fileSize -= leqPow2;
} while (diff > 0)

WScript.Echo("",p2Str);


Surprisingly fast. Made a dummy of a 5.7Mb test file in an eye blink. But be warned! The program has no upper size limit for the dummy file, so be careful what you ask for. :wink:

As always, I look forward to your constructive comments and suggestions.

- SB
Last edited by Sponge Belly on 19 Mar 2015 04:32, edited 1 time in total.

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: create dummy files of exact size

#11 Post by Aacini » 15 Sep 2014 15:53

The code below may create a file up to 2 GB size:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

if "%~1" equ "" echo File name expected & goto :EOF
if not exist %1 echo File not found: %1 & goto :EOF

set fileSize=%~Z1
set /P "=0" > thisSize.txt < NUL
(for /L %%i in (0,1,30) do (
   set /A "bit=(1<<%%i)&fileSize, fileSize&=~(1<<%%i)"
   if !bit! neq 0 type thisSize.txt
   if !fileSize! neq 0 type thisSize.txt >> thisSize.txt
)) > dummy.txt
del thisSize.txt


Antonio

Sponge Belly
Posts: 231
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: create dummy files of exact size

#12 Post by Sponge Belly » 17 Mar 2015 16:34

Me Again!

And a festive St. Patrick’s Day to everyone! :)

Antonio, your bit logic confounds me. Please explain what’s going on in your last post. It’s late and I’m tired and I’ve had a bit too much to drink. :shock:

In the meantime, here’s another approach that exploits the more /t option:

Code: Select all

@echo off & setlocal enableextensions disabledelayedexpansion
set "tabsub=%tmp%\tabsub"

if not exist "%tabsub%.txt" call :mktabsub
if %~1 gtr 0 if %~1 lss 65535 (set "inrange=1"
more /t%~1 "%tabsub%.txt" >"%tmp%\sp%~1.tmp"
>nul copy /y "%tmp%\sp%~1.tmp" /a "%tmp%\sp%~1.txt" /b
del "%tmp%\sp%~1.tmp")
if not defined inrange >&2 echo(parameter must be between 1 and 65534

endlocal & goto :eof

:mktabsub
:: http://www.consolesoft.com/batch/binary/genchr.cmd
type nul >"%tabsub%.tmp"
makecab /d compress=off /d reserveperdatablocksize=26 /d ^
reserveperfoldersize=9 "%tabsub%.tmp" "%tabsub%.txt" >nul
type "%tabsub%.txt" | ((for /l %%N in (1 1 38) do pause) >nul & ^
findstr "^" >"%tabsub%.tmp")
>nul copy /y "%tabsub%.tmp" /a "%tabsub%.txt"
del "%tabsub%.tmp"
exit /b 0


First, we make a file containing a tab and a SUB (Ctrl-Z) character. Then, we use more /t to expand the tab into however many spaces we want. Lastly, we use copy to chop off the trailing SUB and newline, leaving only the spaces (take a bow, Jeb).

Max size for dummy files is 65534 bytes, but you can glue them together to make any size you want. The only real drawback is the fill character has to be a space.

- SB

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: create dummy files of exact size

#13 Post by Ed Dyreen » 18 Mar 2015 19:26

Hi Sponge, the jScript code you call through cScript, is not an abbreviation for JavaScript. jScript is Microsoft's response to java which was popular in the 90's. Java was never specifically written to be run inside browsers, this misuse led to security weaknesses. To address these issues javaScript was developed. It only runs inside browsers, may look and feel a bit like java, yet despite it's name, the only thing it has in common with java is it's name.

Sponge Belly
Posts: 231
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: create dummy files of exact size

#14 Post by Sponge Belly » 19 Mar 2015 04:42

Hi Ed,

Thanks for pointing that out. Apologies for my sloppy terminology. The error has been corrected.

- SB

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: create dummy files of exact size

#15 Post by Liviu » 19 Mar 2015 17:34

Ed Dyreen wrote:Hi Sponge, the jScript code you call through cScript, is not an abbreviation for JavaScript. jScript is Microsoft's response to java which was popular in the 90's. Java was never specifically written to be run inside browsers, this misuse led to security weaknesses. To address these issues javaScript was developed. It only runs inside browsers, may look and feel a bit like java, yet despite it's name, the only thing it has in common with java is it's name.

@Ed, what you wrote came out a bit confusing, so here is my liberal rewrite of it ;-)

[Microsoft] jScript is not an abbreviation for [Netscape] JavaScript, in fact Microsoft chose "jScript" precisely in order to avoid naming/licensing issues. However, both jScript and Javascript are implementations of the same scripting language formally standardized as ECMAScript (http://en.wikipedia.org/wiki/ECMAScript). Neither jScript nor JavaScript are related to the Java programming language (or the Java virtual machine). While primarily used as a client-side scripting language in browsers, jScript scripts can be run outside browsers, for example in Windows' scripting hosts wscript/cscript, or inside any application that implements the IActiveScriptSite interface (https://technet.microsoft.com/en-us/library/z70w3w6a(v=vs.94).aspx).

Liviu

Post Reply