Прокладіть файл з нулями


12

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

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

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

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

Інші існуючі файли не повинні змінюватися, а нові файли не повинні існувати після закінчення виконання.

Випробування

Зміст f | б | Отриманий вміст f
12345 | 10 | 1234500000
0 | 3 | 000
[порожній] | 2 | 00
[порожній] | 0 | [порожньо]
123 | 3 | 123

@totallyhuman спочатку не єb
великим,

Чи можемо ми взяти вміст файлу як вхід і вивести змінений вміст?
Shaggy

Чи можемо ми використовувати бібліотеки?
Adám

1
@Phoenix Проблема полягає в тому, що Денніс помістив бібліотеку в далеку папку (не мій вибір). Чи можу я рахувати так, ніби він був доступний у шляху пошуку?
Адам

Чи можемо ми припустити, що файл вже не містить нульових байтів?
Дом Гастінгс

Відповіді:


20

Bash + coreutils, 13

truncate -s$@

Введення з командного рядка - перший параметр - це розмір файлу, а другий - ім'я файлу.

Від man truncate:

Якщо ФАЙЛ коротший, він розширюється, а розширена частина (отвір) читається як нульовий байт.

Спробуйте в Інтернеті .


1
Чи може також усікання подовжуватися?
Adám

11
Людина, яка справді знає свою людину по-чоловічому.
Чарівний восьминога Урна

Цікаво, чи працює він на розділі FAT, де не працює truncateсистемний виклик.
Маттео Італія

1
Моя реалізація тієї самої ідеї була б dd bs=1 of=$1 seek=$2<&-(яка друкує повідомлення про помилку, яке можна ігнорувати). Ваше набагато коротше. Приємно.
hvd

@hvd yep Я подумав, що DD, можливо, може це зробити
Digital Trauma

4

Groovy, 54 47 43 41 байт

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

-6 завдяки ідеї манатурки зняти петлю; це була моя оригінальна ідея, не знаю, чому я думав, що це не спрацює, і вибрав цикл ... Це, безумовно, працює, просто перевірив його.

Безголівки:

{
    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 так! І це насправді може бути навіть краще за це.
Magic Octopus Urn

@manatwork nevermind, той самий номер рахунку (c=new File(a))через необхідні дужки.
Magic Octopus Urn

1
Поняття не маю, чому я додаю дужки навколо цілого значення для додавання. Не потрібно.
манатура

@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 ні, це більше нагадує річ із прапором (заборонити взаємодію із закритими файлами)
стрижень

1
@Rod Я люблю interactino! Найкраща дитяча інтерактивна гра коли-небудь
caird coinheringaahing

Ви можете використовувати \0замість \x00.
чепнер

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

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 у рядку (а не послідовність виходу)?
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, тому немає ніякого способу додати один байт до файлу за допомогою нього. :

$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

Математика 50 байт

Імпорт-експорт

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

Використання

%["test1", 5]

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введення- виводу, який може бути з введення консолі або аргументів функції.
Павло

Дякую, я подумав, що змінні вважали вже встановленими. Моє ліжко.
Garhoogin

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.