Дополнить файл нулями


12

Ваша задача сегодня будет взять существующий файл и добавлять к нему нули, пока он не достигнет определенного размера.

Вы должны написать программу или функцию, которая берет имя файла в текущем каталоге fи количество байтов b. Сохраняя исходное содержимое f, вы должны записать нули (нулевые байты, а не ascii 0s) до конца, чтобы его новый размер был в bбайтах.

Вы можете предположить, что fв его имени есть только буквенно-цифровой ascii, что у вас есть полные права на него, что он изначально не больше b, но может быть таким же большим b, и что существует бесконечное свободное дисковое пространство.

Вы можете не предполагать f, что он не пустой или что он еще не содержит нулевых байтов.

Другие существующие файлы не должны быть изменены, а новые файлы не должны существовать после завершения выполнения.

Тестовые случаи

Содержание е | б | Результирующее содержание f
12345 | 10 | 1234500000
0 | 3 | 000
[пусто] | 2 | 00
[пусто] | 0 | [Пусто]
123 | 3 | 123

@totallyhuman это изначально не больше, чемb
Адам

Можем ли мы взять содержимое файла в качестве входных данных и вывести измененное содержимое?
Лохматый

Можем ли мы использовать библиотеки?
Адам

1
@ Phoenix Проблема в том, что Деннис поместил библиотеку в далекую папку (не мой выбор). Могу ли я считать, что он был доступен в пути поиска?
Адам

Можем ли мы предположить, что файл уже не будет содержать нулевые байты?
Дом Гастингс

Ответы:


20

Баш + coreutils, 13

truncate -s$@

Ввод из командной строки - первый параметр - это размер файла, а второй - имя файла.

От man truncate:

Если ФАЙЛ короче, он расширяется, и расширенная часть (отверстие) читается как нулевые байты.

Попробуйте онлайн .


1
Может ли усечение расширяться тоже?
Адам

11
Человек, который действительно знает своих мужчин в мужественном человеке.
Волшебная Урна Осьминога

Интересно, работает ли он на разделе FAT, где truncateсистемный вызов не выполняется.
Маттео Италия

1
Моя реализация той же идеи была бы dd bs=1 of=$1 seek=$2<&-(которая печатает сообщение об ошибке, которое можно игнорировать). Ваш намного короче. Ницца.
HVd

@hvd Да, я подумал, что dd может это сделать
Digital Trauma

4

Groovy, 54 47 43 41 байт

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

-6 благодаря идее manatwork по удалению петли; это была моя оригинальная идея, не знаю, почему я думал, что это не сработает, и выбрал цикл ... Он определенно работает, просто проверил его.

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.

1
Не будет короче без петель? {a,b->c=new File(a);c<<('\0'*(b-c.size()))}
manatwork

@ Manatwork да! И это может быть даже лучше, чем это.
Волшебная Урна Осьминога

@manatwork не имеет значения, тот же bytecount для (c=new File(a))из-за требуемой скобки.
Волшебная Урна Осьминога

1
Не знаю, почему я ставлю круглые скобки вокруг всего значения, чтобы добавить. Не нужно.
manatwork

@manatwork Groovy довольно темпераментный в скобках, не могу винить вас, ха-ха.
Волшебная Осьминог урна


3

Python 2 , 59 57 54 байта

-5 байт благодаря чепнеру

def g(n,b):f=open(n,'a');f.write('\0'*b);f.truncate(b)

1
@totallyhuman \x00- нулевой байт.
Павел

1
@totallyhuman нет, это больше похоже на флаг (чтобы не
Rod

1
@ Род Я люблю Интерактино! Лучшая в мире интерактивная игра для
детей

Вы можете использовать \0вместо \x00.
chepner

Вы можете сэкономить еще три байта на завышена, то усечения: def g(n,b):f=open(n,'a');f.write('\0'*b);f.truncate(b).
chepner

3

PHP, 66 байт

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

Принимает данные из аргументов командной строки; беги с -nr.


Эти 55 байтов могут, но, скорее всего, не будут работать:

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

2

Java (Oracle JRE), 55 байт

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

В спецификации setLength(int)говорится, что добавленные байты не определены, но практически Oracle JRE добавляет только 0байт (поэтому я и указал его).

Ресурс автоматически закрывается JVM, поэтому нам не нужно делать это самостоятельно.

Тестовое задание

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);
  }
}

1

AHK, 48 байтов

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

1и 2являются первыми двумя параметрами в скрипте AHK.
FileGetSizeработает в байтах по умолчанию.
Это не интересно, но просто: возьмите размер, вычтите его из желаемого размера и добавьте столько нулей.


1

Perl 6 , 40 байт

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

$^aи $^bявляются параметрами функции - имя файла и длина соответственно.


1

Python 2 , 68 байт

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

Попробуйте онлайн! (При печати содержимого файла код заменяет нулевые байты на ASCII 0 для наглядности.)


1
Я думаю, что это записывает нули ASCII, а не нулевые байты
Павел

Ах ... слово нули
вводило в

Ну, это сказано большими буквами в самом вызове.
Павел

Можете ли вы использовать литерал \ x00 в строке (не escape-последовательность)?
CalculatorFeline

2
Вы не можете использовать буквальный нулевой байт, но \0он короче.
xnor

1

PowerShell, 69 байт

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для файла, $sдля конечного размера, сохраните как .ps1 и запустите

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

Это оболочка, так что должен быть действительно маленький цикл, добавляющий 1 байт с >>перенаправлением вывода и добавлением, верно? Ну, нет, потому что >>выводит только многобайтовую кодировку UCS2-LE, так что нет никакого способа добавить один байт в файл с ним ... если вы не используете PSv5.1, и вы можете изменить это, но это делает его слишком длинным, чтобы быть конкурентоспособным :

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

Может быть, есть подход .Net Framework? Должно быть, но я не могу заставить его писать какие-либо байты или ошибки. Но это все равно больше

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


1

q, 29 байт

Функция, которая принимает имя файла в формате :/foo/bar.bazи длине как целое число.

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

Пример:

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

1

C, 56 байтов

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

Программа находит размер файла и количество байтов для добавления. Затем файл добавляет fs - bдополнительные байты в конец.


1
Добро пожаловать в PPCG! Это код-гольф задача , поэтому ваша цель - сделать вашу программу как можно меньше. Вы должны начать с удаления ненужных пробелов.
Павел

4
Кроме того, ваша программа, кажется, предполагает, что входные данные уже сохранены в значениях f и b, что недопустимо. Вы должны включить ARGVввод / вывод в вашу программу, которая может быть из , ввода с консоли или аргументов функции.
Павел

Спасибо, я думал, что переменные, как предполагалось, уже установлены. Виноват.
Гархогин

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.