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\$
  • \$\begingroup\$ @totallyhuman it initially is not larget than b \$\endgroup\$ – Adám Jun 9 '17 at 17:56
  • \$\begingroup\$ Can we take the contents of the file as input and output the modified contents? \$\endgroup\$ – Shaggy Jun 9 '17 at 18:21
  • \$\begingroup\$ May we use libraries? \$\endgroup\$ – Adám Jun 9 '17 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 Jun 9 '17 at 18:40
  • \$\begingroup\$ Can we assume the file will not already contain null bytes? \$\endgroup\$ – Dom Hastings Jun 9 '17 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\$
  • 1
    \$\begingroup\$ Can truncate extend too? \$\endgroup\$ – Adám Jun 9 '17 at 18:19
  • 11
    \$\begingroup\$ A man who knows his mans in a manly man indeed. \$\endgroup\$ – Magic Octopus Urn Jun 9 '17 at 18:25
  • \$\begingroup\$ I wonder if it works on a FAT partition, where the truncate syscall fails. \$\endgroup\$ – Matteo Italia Jun 10 '17 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 Jun 10 '17 at 18:08
  • \$\begingroup\$ @hvd yep I figured dd could probably do this \$\endgroup\$ – Digital Trauma Jun 11 '17 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\$
  • 1
    \$\begingroup\$ Wouldn't be shorter loopless? {a,b->c=new File(a);c<<('\0'*(b-c.size()))} \$\endgroup\$ – manatwork Jun 9 '17 at 18:18
  • \$\begingroup\$ @manatwork yeah! And it can actually be even better than that. \$\endgroup\$ – Magic Octopus Urn Jun 9 '17 at 18:19
  • \$\begingroup\$ @manatwork nevermind, same bytecount for (c=new File(a)) due to required parenthesis. \$\endgroup\$ – Magic Octopus Urn Jun 9 '17 at 18:23
  • 1
    \$\begingroup\$ No idea why I put parenthesis around the entire value to append. Not needed. \$\endgroup\$ – manatwork Jun 9 '17 at 18:25
  • \$\begingroup\$ @manatwork Groovy is pretty temperamental about the parenthesis, can't blame you haha. \$\endgroup\$ – Magic Octopus Urn Jun 9 '17 at 18:30
3
\$\begingroup\$

APL (Dyalog), 33 17 bytes

⎕⎕NRESIZE⍞⎕NTIE¯1

Try it online!

\$\endgroup\$
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\$
  • 1
    \$\begingroup\$ @totallyhuman \x00 is a null byte. \$\endgroup\$ – Pavel Jun 9 '17 at 18:19
  • 1
    \$\begingroup\$ @totallyhuman no, it is more like a flag thing (to disallow interactino with closed files) \$\endgroup\$ – Rod Jun 9 '17 at 18:19
  • 1
    \$\begingroup\$ @Rod I love interactino! Best child-friendly interactive game ever \$\endgroup\$ – caird coinheringaahing Jun 9 '17 at 18:25
  • \$\begingroup\$ You can use \0 in place of \x00. \$\endgroup\$ – chepner Jun 9 '17 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 Jun 9 '17 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\$
  • 1
    \$\begingroup\$ I think this writes ASCII zeroes and not null bytes \$\endgroup\$ – Pavel Jun 9 '17 at 18:18
  • \$\begingroup\$ Ah... the word zeroes was misleading... \$\endgroup\$ – totallyhuman Jun 9 '17 at 18:20
  • \$\begingroup\$ Well, it does say in large letters in the challenge itself. \$\endgroup\$ – Pavel Jun 9 '17 at 18:20
  • \$\begingroup\$ Can you use a literal \x00 in the string (not an escape sequence)? \$\endgroup\$ – CalculatorFeline Jun 9 '17 at 19:09
  • 2
    \$\begingroup\$ You can't use a literal null byte, but \0 is shorter. \$\endgroup\$ – xnor Jun 10 '17 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\$
  • 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 Jun 10 '17 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 Jun 10 '17 at 5:41
  • \$\begingroup\$ Thank you, I thought that the variables were assumed to be set already. My bad. \$\endgroup\$ – Garhoogin Jun 10 '17 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, privacy policy and cookie policy

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