Fixed length records: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
 
(45 intermediate revisions by 23 users not shown)
Line 1:
{{task}}Fixed length read/write
Fixed length read/write
 
Before terminals, computers commonly used [https://en.wikipedia.org/wiki/Punched_card_reader punch card readers] or paper tape input.
Line 46 ⟶ 47:
The COBOL example uses forth.txt and forth.blk filenames.
<br /><br />
 
=={{header|Ada}}==
Ada string type is a fixed-length string.
<syntaxhighlight lang="ada">
with Ada.Text_IO; use Ada.Text_IO;
 
procedure Main is
subtype Block is String (1 .. 80);
Infile_Name : String := "infile.dat";
outfile_Name : String := "outfile.dat";
Infile : File_Type;
outfile : File_Type;
 
Line : Block := (Others => ' ');
begin
Open (File => Infile, Mode => In_File, Name => Infile_Name);
Create (File => outfile, Mode => Out_File, Name => outfile_Name);
 
Put_Line("Input data:");
New_Line;
while not End_Of_File (Infile) loop
Get (File => Infile, Item => Line);
Put(Line);
New_Line;
for I in reverse Line'Range loop
Put (File => outfile, Item => Line (I));
end loop;
end loop;
Close (Infile);
Close (outfile);
 
Open(File => infile,
Mode => In_File,
Name => outfile_name);
New_Line;
Put_Line("Output data:");
New_Line;
while not End_Of_File(Infile) loop
Get(File => Infile,
Item => Line);
Put(Line);
New_Line;
end loop;
end Main;
</syntaxhighlight>
{{Output}}
<pre>
Input data:
 
Line 1...1.........2.........3.........4.........5.........6.........7.........8
Line 2
Line 3
Line 4
Line 6
Line 7
Indented line 8............................................................
Line 9 RT MARGIN
 
Output data:
 
8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL
</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f FIXED_LENGTH_RECORDS.AWK
BEGIN {
vlr_fn = "FIXED_LENGTH_RECORDS.TXT"
flr_fn = "FIXED_LENGTH_RECORDS.TMP"
print("bef:")
while (getline rec <vlr_fn > 0) { # read variable length records
printf("%-80.80s",rec) >flr_fn # write fixed length records without CR/LF
printf("%s\n",rec)
}
close(vlr_fn)
close(flr_fn)
print("aft:")
getline rec <flr_fn # read entire file
while (length(rec) > 0) {
printf("%s\n",revstr(substr(rec,1,80),80))
rec = substr(rec,81)
}
exit(0)
}
function revstr(str,start) {
if (start == 0) {
return("")
}
return( substr(str,start,1) revstr(str,start-1) )
}
</syntaxhighlight>
{{out}}
<pre>
bef:
Line 1...1.........2.........3.........4.........5.........6.........7.........8
Line 2
Line 3
Line 4
 
Line 6
Line 7
Indented line 8............................................................
Line 9 RT MARGIN
aft:
8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
 
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL
</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <iostream>
 
void reverse(std::istream& in, std::ostream& out) {
constexpr size_t record_length = 80;
char record[record_length];
while (in.read(record, record_length)) {
std::reverse(std::begin(record), std::end(record));
out.write(record, record_length);
}
out.flush();
}
 
int main(int argc, char** argv) {
std::ifstream in("infile.dat", std::ios_base::binary);
if (!in) {
std::cerr << "Cannot open input file\n";
return EXIT_FAILURE;
}
std::ofstream out("outfile.dat", std::ios_base::binary);
if (!out) {
std::cerr << "Cannot open output file\n";
return EXIT_FAILURE;
}
try {
in.exceptions(std::ios_base::badbit);
out.exceptions(std::ios_base::badbit);
reverse(in, out);
} catch (const std::exception& ex) {
std::cerr << "I/O error: " << ex.what() << '\n';
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}</syntaxhighlight>
 
{{out}}
After converting with dd:
<pre>
8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
 
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL
</pre>
 
=={{header|COBOL}}==
 
<langsyntaxhighlight lang="cobol"> *> Rosetta Code, fixed length records
*> Tectonics:
*> cobc -xj lrecl80.cob
Line 137 ⟶ 314:
 
goback.
end program lrecl80.</langsyntaxhighlight>
 
Given a starting file sample.txt of
Line 174 ⟶ 351:
Demonstrate text to Forth source block form.
 
<langsyntaxhighlight lang="cobol"> *> Rosetta Code fixed length records, text to Forth block
identification division.
program-id. blocking.
Line 263 ⟶ 440:
 
goback.
end program blocking.</langsyntaxhighlight>
 
Demonstrate Forth source block to text form.
 
<langsyntaxhighlight lang="cobol"> *> Rosetta Code fixed length records, Forth blocks to text.
identification division.
program-id. unblocking.
Line 338 ⟶ 515:
 
goback.
end program unblocking.</langsyntaxhighlight>
 
=={{header|JuliaDelphi}}==
''See [[#Pascal|Pascal]]''
The program reads from an "infile.dat" file created with dd, as described in the task instructions.
 
<lang julia>
=={{header|Free Pascal}}==
function processfixedlengthrecords(infname, blocksize, outfname)
''See [[#Pascal|Pascal]]''
inf = open(infname)
 
outf = open(outfname, "w")
 
filedata = [ read(inf, blocksize) for _ in 1:10 ]
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">
for line in filedata
Const As Byte longRegistro = 80
s = join([Char(c) for c in line], "")
Const archivoEntrada As String = "infile.dat"
@assert(length(s) == blocksize)
Const archivoSalida As String = "outfile.dat"
write(outf, s)
 
end
Dim As String linea
end
 
'Abre el archivo origen para lectura
processfixedlengthrecords("infile.dat", 80, "outfile.dat")
Open archivoEntrada For Input As #1
</lang>
'Abre el archivo destino para escritura
Open archivoSalida For Output As #2
 
Print !"Datos de entrada:\n"
Do While Not Eof(1)
Line Input #1, linea 'lee una linea
Print linea 'imprime por pantalla esa linea
For i As Integer = longRegistro To 1 Step -1
Print #2, Chr(Asc(linea, i)); 'escribe el inverso de la linea
Next i
Print #2, Chr(13);
Loop
Close #1, #2
 
Dim As Integer a
Open archivoSalida For Input As #2
 
Print !"\nDatos de salida:\n"
Do While Not Eof(2)
Line Input #2, linea
For j As Integer = 0 To Len(linea)-1
Print Chr(linea[j]);
a += 1: If a = longRegistro Then a = 0 : Print Chr(13)
Next j
Loop
Close
Sleep
</syntaxhighlight>
 
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 413 ⟶ 618:
check(err)
fmt.Println(string(bytes))
}</langsyntaxhighlight>
 
{{out}}
Line 430 ⟶ 635:
'''Bonus round'''
 
<langsyntaxhighlight lang="go">package main
 
import (
Line 504 ⟶ 709:
block2text("block.dat", "block.txt")
text2block("block.txt", "block2.dat")
}</langsyntaxhighlight>
 
=={{header|J}}==
'''Solution:'''
 
Using the 720 byte input file linked to in the Raku entry.
<syntaxhighlight lang="j"> _80 ]\ fread 'flr-infile.dat' NB. reads the file into a n by 80 array
_80 |.\ fread 'flr-infile.dat' NB. as above but reverses each 80 byte chunk
'flr-outfile.dat' fwrite~ , _80 |.\ fread 'flr-infile.dat' NB. as above but writes result to file (720 bytes)
processFixLenFile=: fwrite~ [: , _80 |.\ fread NB. represent operation as a verb/function</syntaxhighlight>
 
'''Example Usage:'''
 
<syntaxhighlight lang="j"> 'flr-outfile.dat' processFixLenFile 'flr-infile.dat' NB. returns number of bytes written
720</syntaxhighlight>
 
=={{header|jq}}==
 
To read the raw input and write out raw strings, the command-line options -R (raw input), -r (raw output) and -j options are necessary:
 
jq -Rrj -f program.jq infile.dat
 
program.jq:
 
Currently gojq does not include the `_nwise/1` filter provided by jq, and in any case jq's implementation is suboptimal,
so we define `nwise` here so that it can be used for both array and string inputs. Notice that the inner helper function, `n`, has arity 0, allowing jq's tail-call optimization to work.
<syntaxhighlight lang="jq">def cut($n):
def nwise($n):
def n: if length <= $n then . else .[0:$n] , (.[$n:] | n) end;
n;
nwise(80) | explode | reverse | implode
</syntaxhighlight>
To show that this does indeed work, the output of `/bin/dd cbs=80 conv=unblock` is shown:
{{output}}
<pre>
8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
 
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL
1+1 records in
1+1 records out
644 bytes transferred in 0.030319 secs (21241 bytes/sec)
</pre>
 
=={{header|Julia}}==
The program reads from an "infile.dat" file created with dd, as described in the task instructions.
<syntaxhighlight lang="julia">
function processfixedlengthrecords(infname, blocksize, outfname)
inf = open(infname)
outf = open(outfname, "w")
filedata = [ read(inf, blocksize) for _ in 1:10 ]
for line in filedata
s = join([Char(c) for c in line], "")
@assert(length(s) == blocksize)
write(outf, s)
end
end
processfixedlengthrecords("infile.dat", 80, "outfile.dat")
</syntaxhighlight>
 
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">-- prep: convert given sample text to fixed length "infile.dat"
local sample = [[
Line 1...1.........2.........3.........4.........5.........6.........7.........8
Line 2
Line 3
Line 4
Line 6
Line 7
Indented line 8............................................................
Line 9 RT MARGIN]]
local txtfile = io.open("sample.txt", "w")
txtfile:write(sample)
txtfile:close()
os.execute("dd if=sample.txt of=infile.dat cbs=80 conv=block > /dev/null 2>&1")
 
-- task: convert fixed length "infile.dat" to fixed length "outfile.dat" (reversed lines)
local infile = io.open("infile.dat", "rb")
local outfile = io.open("outfile.dat", "wb")
while true do
local line = infile:read(80)
if not line then break end
outfile:write(string.reverse(line))
end
infile:close()
outfile:close()
 
-- output:
os.execute("dd if=outfile.dat cbs=80 conv=unblock")</syntaxhighlight>
{{out}}
<pre>8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
 
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL
1+1 records in
1+1 records out</pre>
 
=={{header|M2000 Interpreter}}==
===Fixed length Record===
Form Buffer object (hold a memory block) we can read a byte at offset. So Print Eval(Line80,3) return the 4th byte, and Return Line80, 2:=255,5:=0 set two bytes (unsigned, we place any number and interpreter convert it to byte).
 
<syntaxhighlight lang="m2000 interpreter">
Module FixedFile {
Read fixed$
OldLocale=Locale
\\ chr$(string_argument$)
\\ use Locale to convert from Ansi to Utf-16LE
\\ Read Ansi form files also use Locale
Locale 1032
Try ok {
\\ Make the file first
Const Center=2
Font "Courier New"
Bold 0
Italic 0
Def long m, z=1, f
Def text2read$,test3write$
Form 100, 50 ' 100 by 60 characters
Document txt$={Line 1...1.........2.........3.........4.........5.........6.........7.........8
Line 2
Line 3
Line 4
Line 6
Line 7
Indented line 8............................................................
Line 9 RT MARGIN
}
\\ use Help Open in M2000 console for details
\\ Method one
Report Center, "Make file"
\\ for WIDE Random \\ for Utf-16
Open fixed$ for Random Exclusive as #f len=80
m=Paragraph(txt$, 0)
z=1
If forward(txt$, m) then
while m, z<10
text2write$=Paragraph$(txt$,(m))
Print format$("Len:{0}, Data: {1}",Len(text2write$),text2write$)
Put #f, text2write$ , z
\\ record number from 1
\\ if number is total records plus one
\\ we append a record
z++
End while
End If
Print "Press any key"
Push Key$ : Drop
Form 80, 40
Report Center, "Method1"
For z=1 to 9
Get #f, text2read$, z
text2read$=StrRev$(text2read$)
Put #f, text2read$, z
Print text2read$
Next z
Close #f
Report Center, "Method2"
\\ Method2
\\ Buffer Clear Line80 ... \\ to clear memory
\\ here we write all bytes so not needed
Buffer Line80 as byte*80
m=filelen(fixed$)
If m mod 80=0 Then
m=1
\\ now Get/Put read write at byte position
\\ we have to use seek to move to byte position
\\ This way used for Binary files
Open fixed$ for Input as #f1
Open fixed$ for Append as #f2
while not eof(#f1)
seek #f1, m
Rem Print seek(#f)
Get #f1, Line80
Return line80,0:=Str$(StrRev$(Chr$(Eval$(line80,0,80))))
seek #f2, m
Put #f2, Line80
seek #f1, m
Get #f1, Line80
Print Chr$(Eval$(line80,0,80))
m+=80
End While
Close #f1
Close #f2
End if
}
\\ use Close with no parameters for close all files if something happen
If error then Close: Print Error$
Locale OldLocale
}
FixedFile "fixed.random"
 
</syntaxhighlight>
===Forth Blocks===
<syntaxhighlight lang="m2000 interpreter">
Form 80,50
Print "Forth's Blocks"
\\ Forth Blocks
Structure Line16 {
a`Line as byte*64
}
NewBlock=lambda Line16 -> {
Buffer a`Block as Line16*16
\\ fill spaces
Return a`Block, 0:=str$(string$(" ",1024))
=a`Block
}
\\ Events are value types, but for closures and groups are reference types
Event Doit {
Read something$
}
Header=Doit
DisplayBlock= Lambda NewBlock, Line16, Doit, Header (Blocks`File$,Block`Number, UseLocale=1033)->{
Page1=NewBlock()
Open Blocks`File$ for input as #f
Seek #f, 1024*(Block`Number-1)+1
Get #f,Page1
Close #f
Document NewDoc$
\\ need to convert from Ansi
Call Event Header, "Block:"+Str$(Block`Number)
oldlocale=locale
locale UseLocale
For i=0 to 15
lineAny$=chr$(Eval$(Page1,i, Len(Line16)))
Call Event Doit, format$("{0::-2} {1}",i,chr$(Eval$(Page1,i, Len(Line16))))
Next i
locale oldlocale
}
Document ForthCode$={( Large letter F)
: STAR [CHAR] * EMIT ;
: STARS 0 DO STAR LOOP ;
: MARGIN CR 30 SPACES ;
: BLIP MARGIN STAR ;
: BAR MARGIN 5 STARS ;
: F BAR BLIP BAR BLIP BLIP CR ;
}
\\ Make Document bigger than 16 lines
\\ doc.par(ForthCode$) return paragraphs (here we have no wrap)
\\ actuall lines per layer can be found from Report (the renderer)
\\ using Reportlines. layer can be the printer page.
ForthCode$=string$(ForthCode$,5)
Print "Make Block"
Page1=NewBlock()
Locale 1033
Blocks`File$="Forth Blocks"
Block`Number=1
\\ Apppend three times same blocks
For Pass=1 to 3
If Doc.Len(ForthCode$)>0 then
For i=1 to Doc.par(ForthCode$)-1
\\ we give order number but Paragraph$ use unique number for paragraphs
\\ if we didn't delete or insert lines, then these two are the same
Print Paragraph$(ForthCode$, Paragraph(ForthCode$,i))
\\ convert to Ansi using Locale
\\ offset from 0, so minus 1
\\ offset 1 is at len(Line16)
\\ Page1(0) is the real address, but here doesn't matter
Return Page1, (i-1) mod 16:=Str$(Paragraph$(ForthCode$, Paragraph(ForthCode$,i)))
if i mod 16=0 then Gosub SaveBlock
Next i
i--
if Not i mod 16=0 then Gosub SaveBlock
End if
Next Pass
\\ now we read from disk
Class DocumentKeeper {
Document Text$
Function AppendLine(aline$) {
\\ right trim$
.Text$<=Mid$(Trim$("*"+aline$),2)+{
}
}
}
Function Disp(aline$) {
Print aline$
}
DocumentKeeper=DocumentKeeper()
Event Doit New Disp()
Event Header New Disp()
For i=1 to Block`Number-1
Call DisplayBlock(Blocks`File$, i)
Print "Press any key"
Push key$ : Drop
Next i
Event Doit Drop Disp()
Event Doit New DocumentKeeper.AppendLine()
Event Header Hold
For i=1 to Block`Number-1
Call DisplayBlock(Blocks`File$, i)
Next i
Report DocumentKeeper.Text$
 
End
SaveBlock:
Print "Save as Number ";Block`Number
If Exist(Blocks`File$) then
\\ check if there is space for this block
If Not filelen(Blocks`File$) div 1024>=Block`Number-1 Then
Error "Wrong Block Number"
End if
Else
Print "not exist"
Open Blocks`File$ for output as #f
Close #f
Wait 100
\\ or Error "Empty File" if we wish only read
If Block`Number<>1 then Error "Wrong Block Number"
End if
Open Blocks`File$ for append as #f
Seek #f, Block`Number*1024-1023 ' so we seek to first byte
Put #f, Page1
Close #f
Block`Number++
Page1=NewBlock()
Return
</syntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
 
<syntaxhighlight lang="mathematica">
FixedRecordReverse[inFile_File, outFile_File, length_ : 80] :=
Module[{inStream, outStream, line, byte},
WithCleanup[
inStream = OpenRead[inFile, BinaryFormat -> True];
outStream = OpenWrite[outFile, BinaryFormat -> True];
,
While[True,
line = {};
Do[
byte = BinaryRead[inStream, "Byte"];
AppendTo[line, byte]
,
length
];
If[byte === EndOfFile, Break[]];
line = Reverse[line];
BinaryWrite[outStream, line]
]
,
Close[outStream];
Close[inStream];
];
(* Verify the result *)
RunProcess[{"dd", "if=" <> outFile[[1]], "cbs=" <> ToString[length], "conv=unblock"}, "StandardOutput"]
];
</syntaxhighlight>
 
This function will both return the reversed string in the notebook AND write the record to outfile.dat:
{{in}}
<pre>
In[]:= FixedRecordReverse[File["infile.dat"], File["outfile.dat"]]
</pre>
{{out}}
<pre>
 
Out[]= "\
8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
 
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL
"
</pre>
 
=={{header|Neko}}==
<syntaxhighlight lang="actionscript">/**
<lang ActionScript>/**
fixed length records, in Neko
*/
Line 545 ⟶ 1,131:
}
file_close(input)
file_close(output)</langsyntaxhighlight>
 
{{out}}
Line 564 ⟶ 1,150:
</pre>
 
=={{header|Perl 6Nim}}==
===Task: fixed length records===
 
<syntaxhighlight lang="nim">import algorithm
 
proc reverse(infile, outfile: string) =
 
let input = infile.open(fmRead)
defer: input.close()
let output = outfile.open(fmWrite)
defer: output.close()
 
var buffer: array[80, byte]
while not input.endOfFile:
let countRead = input.readBytes(buffer, 0, 80)
if countRead < 80:
raise newException(IOError, "truncated data when reading")
buffer.reverse()
let countWrite = output.writeBytes(buffer, 0, 80)
if countWrite < 80:
raise newException(IOError, "truncated data when writing")
 
reverse("infile.dat", "outfile.dat")</syntaxhighlight>
 
{{out}}
Contents of file “result.txt" created by command <code>dd if=outfile.dat of=result.txt cbs=80 conv=unblock</code>:
<pre>8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
 
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL</pre>
 
===Bonus: Forth blocks===
<syntaxhighlight lang="nim">import strutils
 
const EmptyRecord = repeat(' ', 64)
 
#---------------------------------------------------------------------------------------------------
 
proc textToBlock(infile, outfile: string) =
## Read lines of a text file and write them as 64 bytes records.
 
let input = infile.open(fmRead)
defer: input.close()
let output = outfile.open(fmWrite)
defer: output.close()
 
var count = 0
while not input.endOfFile:
var record = input.readLine()
if record.len > 64:
record.setLen(64) # Truncate to 64 bytes.
elif record.len < 64:
record &= repeat(' ', 64 - record.len) # Pad to 64 bytes.
if output.writeChars(record, 0, 64) != 64:
raise newException(IOError, "error while writing block file")
inc count
 
# Complete block with empty records.
let rem = count mod 16
if rem != 0:
for _ in 1..(16 - rem):
if output.writeChars(EmptyRecord, 0, 64) != 64:
raise newException(IOError, "error while writing block file")
 
#---------------------------------------------------------------------------------------------------
 
proc blockToText(infile, outfile: string) =
## Read 64 bytes records and write them as lines trimming spaces.
 
let input = infile.open(fmRead)
defer: input.close()
let output = outfile.open(fmWrite)
defer: output.close()
 
var line: string
while not input.endOfFile:
line.setLen(64) # Allocate space for the 64 bytes to read.
if input.readChars(line, 0, 64) != 64:
raise newException(IOError, "error while reading block file")
line = line.strip(leading = false, trailing = true) & '\n'
output.write(line)
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
when isMainModule:
textToBlock("block1.txt", "block.dat")
blockToText("block.dat", "block2.txt")</syntaxhighlight>
 
=={{header|Pascal}}==
<syntaxhighlight lang="pascal">program reverseFixedLines(input, output, stdErr);
const
lineLength = 80;
var
// in Pascal, `string[n]` is virtually an alias for `array[1..n] of char`
line: string[lineLength];
i: integer;
begin
while not eof() do
begin
for i := 1 to lineLength do
begin
read(line[i]);
end;
for i := lineLength downto 1 do
begin
write(line[i]);
end;
writeLn();
end;
end.</syntaxhighlight>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">open $in, '<', 'flr-infile.dat';
open $out, '>', 'flr-outfile.dat';
 
while ($n=sysread($in, $record, 80)) { # read in fixed sized binary chunks
syswrite $out, reverse $record; # write reversed records to file
print reverse($record)."\n" # display reversed records, line-by-line
}
close $out;</syntaxhighlight>
{{out}}
<pre>8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL</pre>
[https://github.com/SqrtNegInf/Rosettacode-Perl5-Smoke/blob/master/ref/flr-infile.dat input file]
and
[https://github.com/SqrtNegInf/Rosettacode-Perl5-Smoke/blob/master/ref/flr-outfile.dat output file]
===There Is More Than One Way To Do It===
Read with standard <> using $/ set to a ref-to-int to read a fixed block size.
<syntaxhighlight lang="perl">{
local ($/, @ARGV) = (\80, 'infile.dat');
open my $out, '>', 'outfile.dat' or die $!;
print $out scalar reverse while <>; # can read fixed length too :)
close $out;
}</syntaxhighlight>
Slurp and reverse each line in place.
<syntaxhighlight lang="perl">use Path::Tiny;
path('outfile.dat')->spew(path('infile.dat')->slurp =~ s/.{80}/reverse $&/gesr);</syntaxhighlight>
Double reverse.
<syntaxhighlight lang="perl">use Path::Tiny;
path('outfile.dat')->spew(reverse unpack '(a80)*', reverse path('infile.dat')->slurp);
</syntaxhighlight>
Bonus round: convert the sample file to Forth Block format.
<syntaxhighlight lang="perl">use Path::Tiny;
path('outfile.dat')->spew(pack '(A64)16', split /\n/, path('sample.txt')->slurp);</syntaxhighlight>
Bonus Round: convert Forth Block format to plain text format.
<syntaxhighlight lang="perl">use Path::Tiny;
path('sample2.txt')->spew(map "$_\n", unpack '(A64)16', path('outfile.dat')->slurp);</syntaxhighlight>
 
=={{header|Phix}}==
You might want to investigate using builtins such as get_text() and read_lines(), but they were
never really designed for fixed length record handling and for me, for this task, their limits
outweight any advantages. To simplify matters, this creates any files needed on the fly.
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- file i/o</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">sample_text</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
Line 1...1.........2.........3.........4.........5.........6.........7.........8
Line 2
Line 3
Line 4
Line 6
Line 7
Indented line 8............................................................
Line 9 RT MARGIN"""</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">indat</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"infile.dat"</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">outdat</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"outfile.dat"</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">file_exists</span><span style="color: #0000FF;">(</span><span style="color: #000000;">indat</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">text</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">get_text</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"sample.txt"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">text</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #000000;">text</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sample_text</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">text</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #000000;">indat</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"wb"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]&</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">80</span><span style="color: #0000FF;">-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s created (%d bytes)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">indat</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">get_file_size</span><span style="color: #0000FF;">(</span><span style="color: #000000;">indat</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">get_block</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">size</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">size</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">getc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #000000;">indat</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"rb"</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">isize</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">get_file_size</span><span style="color: #0000FF;">(</span><span style="color: #000000;">indat</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"reversed:\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">isize</span> <span style="color: #008080;">by</span> <span style="color: #000000;">80</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">get_block</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">80</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- Bonus part, 16*64 (=1024) block handling:</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">put_block</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">lines</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">li</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">)></span><span style="color: #000000;">64</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">li</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">li</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">64</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">li</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">64</span><span style="color: #0000FF;">-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">li</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #000000;">outdat</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"wb"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">put_block</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sample_text</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">osize</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">get_file_size</span><span style="color: #0000FF;">(</span><span style="color: #000000;">outdat</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n%s created (%d bytes):\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">outdat</span><span style="color: #0000FF;">,</span><span style="color: #000000;">osize</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #000000;">outdat</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"rb"</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">osize</span> <span style="color: #008080;">by</span> <span style="color: #000000;">64</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">line</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_block</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">64</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">line</span>
<span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">trim_tail</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">,</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim_tail</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">""</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\ntrimmed:\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,{</span><span style="color: #004600;">pp_Nest</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">delete_file</span><span style="color: #0000FF;">(</span><span style="color: #000000;">indat</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (for consistent 2nd run)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
infile.dat created (720 bytes)
reversed:
"8.........7.........6.........5.........4.........3.........2.........1...1 eniL"
" 2 eniL"
" 3 eniL"
" 4 eniL"
" "
" 6 eniL"
" 7 eniL"
"............................................................8 enil detnednI "
"NIGRAM TR 9 eniL"
 
outfile.dat created (1024 bytes):
"Line 1...1.........2.........3.........4.........5.........6...."
"Line 2 "
"Line 3 "
"Line 4 "
" "
"Line 6 "
"Line 7 "
" Indented line 8............................................"
"Line 9 "
" "
" "
" "
" "
" "
" "
" "
 
trimmed:
{"Line 1...1.........2.........3.........4.........5.........6....",
"Line 2",
"Line 3",
"Line 4",
{},
"Line 6",
"Line 7",
" Indented line 8............................................",
"Line 9"}
</pre>
 
=={{header|Python}}==
<syntaxhighlight lang="python">
infile = open('infile.dat', 'rb')
outfile = open('outfile.dat', 'wb')
 
while True:
onerecord = infile.read(80)
if len(onerecord) < 80:
break
onerecordreversed = bytes(reversed(onerecord))
outfile.write(onerecordreversed)
 
infile.close()
outfile.close()
</syntaxhighlight>
 
Output:
<pre>
dd if=outfile.dat cbs=80 conv=unblock
8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL
1+1 records in
1+1 records out
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
Link to a copy of the input file used: [https://github.com/thundergnat/rc/blob/master/resouces/flr-infile.dat flr-infile.dat]
 
Essentially the same as task [[Selective_File_Copy]] except more boring.
 
<syntaxhighlight lang="raku" perl6line>$*OUT = './flr-outfile.dat'.IO.open(:w, :bin) ororelse .die $!; # open a file in binary mode for writing
while my $record = $*IN.read(80) { # read in fixed sized binary chunks
$*OUT.write: $record.=reverse; # write reversed records out to $outfile
$*ERR.say: $record.decode('ASCII'); # display decoded records on STDERR
}
close $*OUT;</langsyntaxhighlight>
{{out}}
<pre>8.........7.........6.........5.........4.........3.........2.........1...1 eniL
Line 585 ⟶ 1,489:
............................................................8 enil detnednI
NIGRAM TR 9 eniL</pre>
 
=={{header|REBOL}}==
<syntaxhighlight lang="rebol">
inp: open %infile.dat
out: open/new %outfile.dat
 
while [ not empty? line: copy/part inp 80 ][ write out reverse line ]
 
close inp
close out
</syntaxhighlight>
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX pgm reads fixed-lengthfixed─length 80 byte records; reverses each record, displays to term. */
iFID= 'FIXEDLEN.TXT' /*the file's filename (used for input).*/
call charin iFID, 1, 0 /*open the file, point rec pointer to 1*/
/* [+] just to be safe, position file.*/
do j=1 while chars(iFID) >= 80 /*read data records of LRECL ≡ eighty. */
@.j= charin(iFID, , 80) /*read a data record of eighty bytes. */
end /*j*/
#= j - 1 /*adjust # of records (J is 1 too high)*/
do k=1 for # /* [+] process all the records read. */
say reverse(@.k) /* reverse a record and write to term. */
end /*k*/ /*stick a fork in it, we're all done. */</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input file:}}
{{out}}
Line 609 ⟶ 1,524:
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL
</pre>
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">open("outfile.dat", "w") do |out_f|
open("infile.dat") do |in_f|
while record = in_f.read(80)
out_f << record.reverse
end
end
end # both files automatically closed
</syntaxhighlight>
=={{header|Rust}}==
<syntaxhighlight lang="rust">use std::fs::File;
use std::io::prelude::*;
use std::io::{BufReader, BufWriter};
 
fn reverse_file(
input_filename: &str,
output_filename: &str,
record_len: usize,
) -> std::io::Result<()> {
let mut input = BufReader::new(File::open(input_filename)?);
let mut output = BufWriter::new(File::create(output_filename)?);
let mut buffer = vec![0; record_len];
while input.read(&mut buffer)? == record_len {
buffer.reverse();
output.write_all(&buffer)?;
}
output.flush()?;
Ok(())
}
 
fn main() {
match reverse_file("infile.dat", "outfile.dat", 80) {
Ok(()) => {}
Err(error) => eprintln!("I/O error: {}", error),
}
}</syntaxhighlight>
 
{{out}}
After converting with dd:
<pre>
8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
 
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL
</pre>
 
=={{header|Tcl}}==
<syntaxhighlight lang="tcl">chan configure stdin -translation binary
chan configure stdout -translation binary
 
set lines [regexp -inline -all {.{80}} [read stdin]]
puts -nonewline [join [lmap line $lines {string reverse $line}] ""]
 
# More "traditional" way
 
# while {[set line [read stdin 80]] ne ""} {
# puts -nonewline [string reverse $line]
# }</syntaxhighlight>
 
{{out}}
<pre>$ exec 2>/dev/null
$ dd if=sample.txt cbs=80 conv=block | tclsh flr.tcl | dd cbs=80 conv=unblock
8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
 
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL</pre>
 
=={{header|TXR}}==
 
===80 Column Task===
 
At the shell prompt:
 
<pre>
$ txr -e '(let ((buf (make-buf 80))
(nread 80))
(while (eql nread 80)
(set nread (fill-buf-adjust buf))
(buf-set-length buf 80)
(put-buf (nreverse buf))))' < infile80.bin > outfile80.bin
$ dd if=outfile80.bin cbs=80 conv=unblock
8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
 
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL
 
1+1 records in
1+1 records out
725 bytes copied, 8.658e-05 s, 8.4 MB/s
</pre>
 
This handles a final bit that is shorter than 80. When <code>buf-set-length</code> sets the buffer size back to 80, zero padding is applied. The zero-padded record is reversed.
 
===Forth Blocks Task===
 
====Encoding====
 
The following program is called <code>forth-enblock.tl</code>:
 
<syntaxhighlight lang="txrlisp">(typedef forth-line (array 64 bchar))
 
(let ((lno 0)
(blanks (make-buf 64 #\space)))
(whilet ((line (get-line)))
(put-obj (fmt "~-64,64a" line) (ffi forth-line))
(inc lno))
(while (plusp (mod (pinc lno) 16))
(put-buf blanks)))</syntaxhighlight>
 
{{out}}
 
<pre>$ txr forth-enblock.tl < forth-enblock.tl > forth-enblock.blk
$ xxd forth-enblock.blk
00000000: 2874 7970 6564 6566 2066 6f72 7468 2d6c (typedef forth-l
00000010: 696e 6520 2861 7272 6179 2036 3420 6263 ine (array 64 bc
00000020: 6861 7229 2920 2020 2020 2020 2020 2020 har))
00000030: 2020 2020 2020 2020 2020 2020 2020 2020
00000040: 2020 2020 2020 2020 2020 2020 2020 2020
00000050: 2020 2020 2020 2020 2020 2020 2020 2020
00000060: 2020 2020 2020 2020 2020 2020 2020 2020
00000070: 2020 2020 2020 2020 2020 2020 2020 2020
00000080: 286c 6574 2028 286c 6e6f 2030 2920 2020 (let ((lno 0)
[... snip ...]
000003e0: 2020 2020 2020 2020 2020 2020 2020 2020
000003f0: 2020 2020 2020 2020 2020 2020 2020 2020</pre>
 
====Decoding====
 
This is <code>forth-deblock.tl</code>
 
<syntaxhighlight lang="txrlisp">(typedef forth-block (array 16 (array 64 bchar)))
 
(defsymacro fbsz (sizeof forth-block))
 
(let* ((buf (make-buf fbsz))
(block-view (carray-buf buf (ffi forth-block)))
(nread fbsz))
(while (eql fbsz nread)
(set nread (fill-buf-adjust buf))
(when (plusp nread)
(buf-set-length buf fbsz #\space)
(each ((row [block-view 0]))
(put-line (trim-right #/ +/ row))))))</syntaxhighlight>
 
{{out}}
 
<pre>$ txr forth-deblock.tl < forth-enblock.blk
(typedef forth-line (array 64 bchar))
 
(let ((lno 0)
(blanks (make-buf 64 #\space)))
(whilet ((line (get-line)))
(put-obj (fmt "~-64,64a" line) (ffi forth-line))
(inc lno))
(while (plusp (mod (pinc lno) 16))
(put-buf blanks)))
 
 
 
 
 
 
 
</pre>
 
=={{header|Wren}}==
{{libheader|Wren-str}}
<syntaxhighlight lang="wren">import "io" for File
import "./str" for Str
 
var records = File.read("infile.dat")
File.create("outfile.dat") { |f|
for (record in Str.chunks(records, 80)) {
record = record[-1..0]
f.writeBytes(record)
}
}
records = File.read("outfile.dat")
for (record in Str.chunks(records, 80)) System.print(record)</syntaxhighlight>
 
{{out}}
<pre>
8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL
</pre>
 
===Bonus round===
{{libheader|Wren-ioutil}}
<syntaxhighlight lang="wren">import "./ioutil" for File, FileUtil
import "./str" for Str
 
var blockToText = Fn.new { |blockFileName, textFileName|
var block = File.read(blockFileName)
var lb = FileUtil.lineBreak
File.create(textFileName) { |f|
for (chunk in Str.chunks(block, 64)) {
f.writeBytes(chunk.trimEnd() + lb)
}
}
}
 
var textToBlock = Fn.new { |textFileName, blockFileName|
var lines = FileUtil.readLines(textFileName).where { |l| l != "" }.toList
var text = lines.map { |l| (l.count < 64) ? l + (" " * (64-l.count)) : l[0..63] }.join()
var rem = text.count % 1024
if (rem > 0) text = text + (" " * (1024 - rem))
File.create(blockFileName) { |f| f.writeBytes(text) }
}
 
// create a block file
File.create("data.blk") { |f|
f.writeBytes("a" * 1024)
f.writeBytes("b" * 1024)
f.writeBytes("c" * 1024)
f.writeBytes("d" * 1024)
}
 
blockToText.call("data.blk", "data.txt")
textToBlock.call("data.txt", "data2.blk")
System.print(FileUtil.areDuplicates("data.blk", "data2.blk"))</syntaxhighlight>
 
{{out}}
<pre>
true
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">include xpllib;
int N, I;
char A(80);
[OpenInFile("infile.dat");
OpenOutFile("outfile.dat");
for N:= 1 to 9 do
[for I:= 0 to 80-1 do A(I):= ChIn(3);
for I:= 80-1 downto 0 do ChOut(3, A(I));
];
OpenInFile("outfile.dat");
for N:= 1 to 9 do
[for I:= 0 to 80-1 do ChOut(0, ChIn(3)); CrLf(0)];
]</syntaxhighlight>
{{out}}
<pre>
8.........7.........6.........5.........4.........3.........2.........1...1 eniL
2 eniL
3 eniL
4 eniL
6 eniL
7 eniL
............................................................8 enil detnednI
NIGRAM TR 9 eniL
</pre>
Line 617 ⟶ 1,807:
Line 1...1.........2.........3.........4.........5.........6.........7.........8Line 2 Line 3 Line 4 Line 6 Line 7 Indented line 8............................................................Line 9 RT MARGIN
</pre>
<langsyntaxhighlight lang="zkl">File("infile.dat","rb") // could contain nulls and newlines
// Since we are writing to a ASCII terminal, ignore nulls
.walker(3).chunk(80,String).pump(Console.println,"reverse"); // 3-->read chars</langsyntaxhighlight>
{{out}}
<pre>
Line 633 ⟶ 1,823:
</pre>
To write to a file (as one big line), preserving nulls:
<langsyntaxhighlight lang="zkl">in,out := File("infile.dat","rb"), File("outfile.dat","wb");
in.walker(0).chunk(80).pump(out,"reverse"); // may contain nulls and newlines
// 0-->read bytes, chunk to list of bytes, reverse and write the bytes
in.close(); out.close();</langsyntaxhighlight>
outfile.dat:
{{out}}
Line 643 ⟶ 1,833:
</pre>
<b>Bonus Round</b>
<langsyntaxhighlight lang="zkl">// read block file (as in read a file of blocks) to text
fcn readFourthBlock(inFileNm){
out,f,buf := Sink(String), File(inFileNm,"rb"), Data(1024);
Line 651 ⟶ 1,841:
}
f.close(); out.close();
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">// read text file and write as block to file
fcn formatToFourthBlock(inFileNm,outFileNm){
n,blk,in,out := 0, Data(), File(inFileNm,"r"), File(outFileNm,"wb");
Line 662 ⟶ 1,852:
if(blk) out.write(blk, " "*(1024 - blk.len()));
f.close(); out.close();
}</langsyntaxhighlight>
9,488

edits