12
\$\begingroup\$

Your task today will be to take an existing file and append zeros to it until it reaches a certain size.

You must write a program or function which takes the name of a file in the current directory f and a number of bytes b. While maintaining the original content of f, you must write zeroes (null bytes, not ascii 0s) to the end so that its new size is b bytes.

You may assume that f only has alphanumeric ascii in its name, that you have full permissions over it, that it initially is not larger than b, but may be as large as b, and that there is infinite free disk space.

You may not assume f is nonempty, or that it does not already contain null bytes.

Other existing files should not be modified and new files should not exist after execution ends.

Test Cases

Contents of f | b  | Resulting contents of f
12345         | 10 | 1234500000
0             | 3  | 000
[empty]       | 2  | 00
[empty]       | 0  | [empty]
123           | 3  | 123
\$\endgroup\$
5
  • \$\begingroup\$ @totallyhuman it initially is not larget than b \$\endgroup\$
    – Adám
    Commented Jun 9, 2017 at 17:56
  • \$\begingroup\$ Can we take the contents of the file as input and output the modified contents? \$\endgroup\$
    – Shaggy
    Commented Jun 9, 2017 at 18:21
  • \$\begingroup\$ May we use libraries? \$\endgroup\$
    – Adám
    Commented Jun 9, 2017 at 18:35
  • 1
    \$\begingroup\$ @Phoenix The problem is that Dennis put the library in a far away folder (not my choice). Can I count as if it was available in the search path? \$\endgroup\$
    – Adám
    Commented Jun 9, 2017 at 18:40
  • \$\begingroup\$ Can we assume the file will not already contain null bytes? \$\endgroup\$ Commented Jun 9, 2017 at 19:37

14 Answers 14

20
\$\begingroup\$

Bash + coreutils, 13

truncate -s$@

Input from the command-line - the first parameter is the file size and the second is the filename.

From man truncate:

If a FILE is shorter, it is extended and the extended part (hole) reads as zero bytes.

Try it online.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Can truncate extend too? \$\endgroup\$
    – Adám
    Commented Jun 9, 2017 at 18:19
  • 11
    \$\begingroup\$ A man who knows his mans in a manly man indeed. \$\endgroup\$ Commented Jun 9, 2017 at 18:25
  • \$\begingroup\$ I wonder if it works on a FAT partition, where the truncate syscall fails. \$\endgroup\$ Commented Jun 10, 2017 at 13:59
  • 1
    \$\begingroup\$ My implementation of the same idea would have been dd bs=1 of=$1 seek=$2<&- (which prints an error message that can be ignored). Yours is far shorter. Nice. \$\endgroup\$
    – hvd
    Commented Jun 10, 2017 at 18:08
  • \$\begingroup\$ @hvd yep I figured dd could probably do this \$\endgroup\$ Commented Jun 11, 2017 at 0:01
4
\$\begingroup\$

Groovy, 54 47 43 41 bytes

{a,b->(c=new File(a))<<'\0'*(b-c.size())}

-6 thanks to manatwork's idea of removing the loop; that was my original idea, don't know why I thought it wouldn't work and opted for a loop... It definitely works, just tested it.

Ungolfed:

{
    a,b->                    // Two inputs: a is the File name, b is the desired size.
    File c = new File(a)     // Make and store the file.
    c << '\0'*(b-c.size())   // Append the difference between b and c.size() in nullbytes.
}
                             // Usually a close would be required, but, in Groovy,
                             // because private data isn't so protected, if a File
                             // Object goes out of scope, the attached Stream is 
                             // automatically flushed to disk.
\$\endgroup\$
5
  • 1
    \$\begingroup\$ Wouldn't be shorter loopless? {a,b->c=new File(a);c<<('\0'*(b-c.size()))} \$\endgroup\$
    – manatwork
    Commented Jun 9, 2017 at 18:18
  • \$\begingroup\$ @manatwork yeah! And it can actually be even better than that. \$\endgroup\$ Commented Jun 9, 2017 at 18:19
  • \$\begingroup\$ @manatwork nevermind, same bytecount for (c=new File(a)) due to required parenthesis. \$\endgroup\$ Commented Jun 9, 2017 at 18:23
  • 1
    \$\begingroup\$ No idea why I put parenthesis around the entire value to append. Not needed. \$\endgroup\$
    – manatwork
    Commented Jun 9, 2017 at 18:25
  • \$\begingroup\$ @manatwork Groovy is pretty temperamental about the parenthesis, can't blame you haha. \$\endgroup\$ Commented Jun 9, 2017 at 18:30
3
\$\begingroup\$

APL (Dyalog), 33 17 bytes

⎕⎕NRESIZE⍞⎕NTIE¯1

Try it online!

\$\endgroup\$
2
3
\$\begingroup\$

Python 2, 59 57 54 bytes

-5 bytes thanks to chepner

def g(n,b):f=open(n,'a');f.write('\0'*b);f.truncate(b)
\$\endgroup\$
7
  • 1
    \$\begingroup\$ @totallyhuman \x00 is a null byte. \$\endgroup\$
    – Pavel
    Commented Jun 9, 2017 at 18:19
  • 1
    \$\begingroup\$ @totallyhuman no, it is more like a flag thing (to disallow interactino with closed files) \$\endgroup\$
    – Rod
    Commented Jun 9, 2017 at 18:19
  • 1
    \$\begingroup\$ @Rod I love interactino! Best child-friendly interactive game ever \$\endgroup\$ Commented Jun 9, 2017 at 18:25
  • \$\begingroup\$ You can use \0 in place of \x00. \$\endgroup\$
    – chepner
    Commented Jun 9, 2017 at 21:50
  • \$\begingroup\$ You can save another three bytes by overextending, then truncating: def g(n,b):f=open(n,'a');f.write('\0'*b);f.truncate(b). \$\endgroup\$
    – chepner
    Commented Jun 9, 2017 at 22:05
3
\$\begingroup\$

PHP, 66 bytes

for($p=fopen($f=$argv[1],a);filesize($f)<$argv[2];)fputs($p,"\0");

Takes input from command line arguments; run with -nr.


These 55 bytes might, but most probably will not, work:

fseek($p=fopen($argv[1],"w+"),$argv[2]);fputs($p,"\0");
\$\endgroup\$
2
\$\begingroup\$

Java (Oracle JRE), 55 bytes

f->b->new java.io.RandomAccessFile(f,"rw").setLength(b)

The spec of setLength(int) says that the appended bytes are undefined, but practically the Oracle JRE appends only the 0 byte (that's why I specified it).

The resource is automatically closed by the JVM so we don't need to do it ourself.

Test

public class Pcg125661 {
  interface F {
    B f(String f);
  }
  interface B {
    void b(int b) throws java.io.IOException;
  }
  public static void main(String[] args) throws java.io.IOException {
    F a = f->b->new java.io.RandomAccessFile(f,"rw").setLength(b);
    a.f("a").b(100);
  }
}
\$\endgroup\$
1
\$\begingroup\$

AHK, 48 bytes

FileGetSize,s,%1%
2-=s
Loop,%2%
FileAppend,0,%1%

1 and 2 are the first two parameters in an AHK script.
FileGetSize works in bytes by default.
It's not exciting, but it's simple: Get the size, subtract it from the desired size, and add that many zeroes.

\$\endgroup\$
1
\$\begingroup\$

Perl 6, 40 bytes

{$_=$^a.IO;.open(:a).put("\0"x($^b-.s))}

$^a and $^b are the parameters to the function--the file name and the length, respectively.

\$\endgroup\$
1
\$\begingroup\$

Python 2, 68 bytes

def g(f,b):
 with open(f,'r+')as c:c.write('\x00'*(b-len(c.read())))

Try it online! (When printing the file's content, the code replaces null bytes with ASCII 0's for visibility.)

\$\endgroup\$
5
  • 1
    \$\begingroup\$ I think this writes ASCII zeroes and not null bytes \$\endgroup\$
    – Pavel
    Commented Jun 9, 2017 at 18:18
  • \$\begingroup\$ Ah... the word zeroes was misleading... \$\endgroup\$ Commented Jun 9, 2017 at 18:20
  • \$\begingroup\$ Well, it does say in large letters in the challenge itself. \$\endgroup\$
    – Pavel
    Commented Jun 9, 2017 at 18:20
  • \$\begingroup\$ Can you use a literal \x00 in the string (not an escape sequence)? \$\endgroup\$ Commented Jun 9, 2017 at 19:09
  • 2
    \$\begingroup\$ You can't use a literal null byte, but \0 is shorter. \$\endgroup\$
    – xnor
    Commented Jun 10, 2017 at 6:26
1
\$\begingroup\$

PowerShell, 69 bytes

param($f,$s)@(gc $f -en by)+,[byte]0*($s-(gi $f).length)|sc $f -en by
#     ^ filename
#        ^desired size
#                 ^ get content as byte stream
#           ^force it to an array even if there's 0 or 1 byte
#                          ^append a byte array of nulls..
#                                       ^..desired size - file size
#                            write to file with -encoding byte ^

$f for the file, $s for the destination size, save as .ps1 and run

.\Add-NullBytesToFile.ps1 .\test.txt 10

It's a shell, so there should be a really small loop adding 1 byte with >> output redirection and append, right? Well, no, because >> only outputs UCS2-LE multibyte encoding so there's no way to add a single byte to a file with it .. unless you're using PSv5.1 and you can change that but that makes it too long to be competitive:

$PSDefaultParameterValues['Out-File:Encoding']='utf8';while((gi $f).length-lt$c){[byte]0>>$f}

Maybe there's a .Net Framework approach? There should be, but I can't make it actually write any bytes, or error. But it's longer anyway:

param($f,$s)[io.file]::WriteAllBytes($f,[byte[]](,0)*($c-(gi $f).length), $True)
\$\endgroup\$
1
\$\begingroup\$

Mathematica 50 Bytes

Import/Export

Export[#,Import[#,c="Byte"]~Join~Table[0,{#2}],c]&

Usage

%["test1", 5]
\$\endgroup\$
1
\$\begingroup\$

q, 29 bytes

Function which takes file name in format :/foo/bar.baz and length as an integer.

{hopen[x](0|y-hcount x)#0x00}

Example:

{hopen[x](0|y-hcount x)#0x00}[`:test.txt;100]
\$\endgroup\$
1
\$\begingroup\$

C, 56 bytes

fseek(f,0,2);int i;for(;ftell(f)<b;)putc(0,f);fclose(f);

The program finds the file's size, and how many bytes to append. The file then adds fs - b extra bytes to the end.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Welcom to PPCG! This is a code-golf challenge, so your objective is to make your program as small as possible. You should start by removing unnecesary whitespace. \$\endgroup\$
    – Pavel
    Commented Jun 10, 2017 at 5:39
  • 4
    \$\begingroup\$ In addition, your program seems to assume that the inputs are already stored in the values f and b, which isn't allowed. You must include i/o into your program, which can be from ARGV, console input, or arguments to a function. \$\endgroup\$
    – Pavel
    Commented Jun 10, 2017 at 5:41
  • \$\begingroup\$ Thank you, I thought that the variables were assumed to be set already. My bad. \$\endgroup\$
    – Garhoogin
    Commented Jun 10, 2017 at 6:06
1
\$\begingroup\$

C#, 90 bytes

using System.IO;s=>n=>File.AppendAllText(s,new string('\0',(int)new FileInfo(s).Length-n))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.