Remplir un fichier avec des zéros

12

Votre tâche aujourd'hui sera de prendre un fichier existant et d'y ajouter des zéros jusqu'à ce qu'il atteigne une certaine taille.

Vous devez écrire un programme ou une fonction qui prend le nom d'un fichier dans le répertoire courant fet un certain nombre d'octets b. Tout en conservant le contenu d'origine de f, vous devez écrire des zéros (octets nuls, pas ascii 0s) à la fin pour que sa nouvelle taille soit en boctets.

Vous pouvez supposer que le nom fne contient que des caractères alphanumériques ascii, que vous disposez de toutes les autorisations sur celui-ci, qu'il n'est pas initialement plus grand que b, mais peut être aussi grand que b, et qu'il y a un espace disque libre infini.

Vous ne pouvez pas supposer fqu'il n'est pas vide ou qu'il ne contient pas déjà des octets nuls.

Les autres fichiers existants ne doivent pas être modifiés et de nouveaux fichiers ne doivent plus exister après la fin de l'exécution.

Cas de test

Contenu de f | b | Contenu résultant de f
12345 | 10 | 1234500000
0 | 3 | 000
[vide] | 2 | 00
[vide] | 0 | [vide]
123 | 3 | 123
Pavel
la source
@totallyhuman il n'est initialement pas plus grand queb
Adám
Peut-on prendre le contenu du fichier en entrée et sortir le contenu modifié?
Shaggy
Pouvons-nous utiliser des bibliothèques?
Adám
1
@Phoenix Le problème est que Dennis a mis la bibliothèque dans un dossier éloigné (pas mon choix). Puis-je compter comme s'il était disponible dans le chemin de recherche?
Adám
Pouvons-nous supposer que le fichier ne contiendra pas déjà des octets nuls?
Dom Hastings

Réponses:

20

Bash + coreutils, 13

truncate -s$@

Entrée depuis la ligne de commande - le premier paramètre est la taille du fichier et le second est le nom du fichier.

De man truncate:

Si un FICHIER est plus court, il est étendu et la partie étendue (trou) se lit comme zéro octet.

Essayez-le en ligne .

Traumatisme numérique
la source
1
Peut-on tronquer aussi?
Adám
11
Un homme qui connaît ses hommes en un homme viril en effet.
Magic Octopus Urn
Je me demande si cela fonctionne sur une partition FAT, où l' truncateappel système échoue.
Matteo Italia
1
Mon implémentation de la même idée aurait été dd bs=1 of=$1 seek=$2<&-(qui affiche un message d'erreur qui peut être ignoré). Le vôtre est beaucoup plus court. Agréable.
hvd
@hvd yep je pensais que dd pourrait probablement faire ça
Digital Trauma
4

Groovy, 54 47 43 41 octets

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

-6 grâce à l'idée de manatwork de supprimer la boucle; c'était mon idée originale, je ne sais pas pourquoi je pensais que ça ne marcherait pas et j'ai opté pour une boucle ... Ça marche vraiment, viens de la tester.

Non golfé:

{
    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.
Urne de poulpe magique
la source
1
Ne serait pas plus court sans boucle? {a,b->c=new File(a);c<<('\0'*(b-c.size()))}
manatwork
@manatwork ouais! Et cela peut même être encore mieux que ça.
Magic Octopus Urn
@manatwork nevermind, même octet en (c=new File(a))raison des parenthèses requises.
Magic Octopus Urn
1
Aucune idée pourquoi j'ai mis des parenthèses autour de la valeur entière à ajouter. Pas besoin.
manatwork
@manatwork Groovy est assez capricieux à propos des parenthèses, je ne peux pas vous en vouloir haha.
Urne de poulpe magique le
3

Python 2 , 59 57 54 octets

-5 octets grâce à chepner

def g(n,b):f=open(n,'a');f.write('\0'*b);f.truncate(b)
Barre
la source
1
@totallyhuman \x00est un octet nul.
Pavel
1
@totallyhuman non, cela ressemble plus à un drapeau (pour interdire l'interaction avec des fichiers fermés)
Rod
1
@Rod J'adore interactino! Meilleur jeu interactif adapté aux enfants de tous les temps
caird coinheringaahing
Vous pouvez utiliser \0à la place de \x00.
chepner
Vous pouvez enregistrer trois autres octets par faire trop, puis tronquer: def g(n,b):f=open(n,'a');f.write('\0'*b);f.truncate(b).
chepner
3

PHP, 66 octets

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

Prend l'entrée des arguments de ligne de commande; courir avec -nr.


Ces 55 octets pourraient, mais ne fonctionneront probablement pas, fonctionner:

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

Java (Oracle JRE), 55 octets

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

La spécification de setLength(int)dit que les octets ajoutés ne sont pas définis, mais pratiquement Oracle JRE n'ajoute que l' 0octet (c'est pourquoi je l'ai spécifié).

La ressource est automatiquement fermée par la JVM, nous n'avons donc pas besoin de le faire nous-mêmes.

Tester

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);
  }
}
Olivier Grégoire
la source
1

AHK, 48 octets

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

1et 2sont les deux premiers paramètres d'un script AHK.
FileGetSizefonctionne en octets par défaut.
Ce n'est pas excitant, mais c'est simple: obtenez la taille, soustrayez-la de la taille souhaitée et ajoutez autant de zéros.

Ingénieur Toast
la source
1

Perl 6 , 40 octets

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

$^aet $^bsont les paramètres de la fonction - le nom de fichier et la longueur, respectivement.

Sean
la source
1

Python 2 , 68 octets

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

Essayez-le en ligne! (Lors de l'impression du contenu du fichier, le code remplace les octets nuls par des ASCII 0 pour la visibilité.)

totalement humain
la source
1
Je pense que cela écrit des zéros ASCII et non des octets nuls
Pavel
Ah ... le mot zéros était trompeur ...
totalement humain
Eh bien, c'est écrit en grosses lettres dans le défi lui-même.
Pavel
Pouvez-vous utiliser un littéral \ x00 dans la chaîne (pas une séquence d'échappement)?
CalculatorFeline
2
Vous ne pouvez pas utiliser un octet nul littéral, mais il \0est plus court.
xnor
1

PowerShell, 69 octets

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 ^

$fpour le fichier, $spour la taille de destination, enregistrez sous .ps1 et exécutez

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

C'est un shell, donc il devrait y avoir une très petite boucle ajoutant 1 octet avec >>redirection de sortie et ajout, non? Eh bien, non, car >>ne sort que le codage multi-octets UCS2-LE, donc il n'y a aucun moyen d'ajouter un seul octet à un fichier avec lui .. sauf si vous utilisez PSv5.1 et vous pouvez changer cela, mais cela rend trop long pour être compétitif :

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

Peut-être existe-t-il une approche .Net Framework? Il devrait y en avoir, mais je ne peux pas faire en sorte qu'il écrive des octets ou une erreur. Mais c'est quand même plus long:

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

Mathematica 50 octets

Importer / Exporter

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

Usage

%["test1", 5]
Kelly Lowder
la source
1

q, 29 octets

Fonction qui prend le nom de fichier au format :/foo/bar.bazet en longueur sous forme d'entier.

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

Exemple:

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

C, 56 octets

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

Le programme trouve la taille du fichier et le nombre d'octets à ajouter. Le fichier ajoute ensuite fs - bdes octets supplémentaires à la fin.

Garhoogin
la source
1
Bienvenue à PPCG! Il s'agit d'un défi de code-golf , donc votre objectif est de rendre votre programme aussi petit que possible. Vous devez commencer par supprimer les espaces inutiles.
Pavel
4
De plus, votre programme semble supposer que les entrées sont déjà stockées dans les valeurs fet b, ce qui n'est pas autorisé. Vous devez inclure des E / S dans votre programme, qui peuvent provenir d'une ARGVentrée de console ou d'arguments d'une fonction.
Pavel
Merci, je pensais que les variables étaient supposées être déjà définies. Ma faute.
Garhoogin
1

C #, 90 octets

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