Page 1 of 2

create dummy files of exact size

Posted: 10 May 2014 16:45
by Sponge Belly
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

Re: create dummy files of exact size

Posted: 10 May 2014 17:56
by einstein1969
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

Re: create dummy files of exact size

Posted: 10 May 2014 23:44
by foxidrive
Just adding in the thread that there is a tool in Windows to do this.

Code: Select all

fsutil file createnew file.ext 1000

Re: create dummy files of exact size

Posted: 11 May 2014 10:26
by Squashman
Have some code from Dave in a batch file he helped me with in one my threads. Will have to go find that.

Re: create dummy files of exact size

Posted: 11 May 2014 11:51
by penpen
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.

Re: create dummy files of exact size

Posted: 11 May 2014 12:17
by Aacini
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

Re: create dummy files of exact size

Posted: 14 May 2014 14:27
by Sponge Belly
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

Re: create dummy files of exact size

Posted: 14 May 2014 17:02
by einstein1969
Hi SB,

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

einstein1969

Re: create dummy files of exact size

Posted: 14 May 2014 18:07
by siberia-man
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)

Re: create dummy files of exact size

Posted: 15 Sep 2014 14:30
by Sponge Belly
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

Re: create dummy files of exact size

Posted: 15 Sep 2014 15:53
by Aacini
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

Re: create dummy files of exact size

Posted: 17 Mar 2015 16:34
by Sponge Belly
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

Re: create dummy files of exact size

Posted: 18 Mar 2015 19:26
by Ed Dyreen
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.

Re: create dummy files of exact size

Posted: 19 Mar 2015 04:42
by Sponge Belly
Hi Ed,

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

- SB

Re: create dummy files of exact size

Posted: 19 Mar 2015 17:34
by Liviu
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