Create a file on magnetic tape

Revision as of 16:12, 11 August 2014 by rosettacode>Kentros (Adds Clojure solution)

The task is to create a new file called "TAPE.FILE" of any size on Magnetic Tape

Task
Create a file on magnetic tape
You are encouraged to solve this task according to the task description, using any language you may know.

Applesoft BASIC

<lang ApplesoftBasic>SAVE</lang>

Clojure

<lang clojure>(spit "/dev/tape" "Hello, World!")</lang>

COBOL

Works with: OpenCOBOL

<lang COBOL> >>SOURCE FORMAT IS FREE IDENTIFICATION DIVISION. PROGRAM-ID. MAKE-TAPE-FILE.

ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL.

   SELECT TAPE-FILE
       ASSIGN "/TAPE.FILE"
       ORGANIZATION IS LINE SEQUENTIAL.

DATA DIVISION. FILE SECTION. FD TAPE-FILE. 01 TAPE-FILE-RECORD PIC X(51).

PROCEDURE DIVISION.

   OPEN OUTPUT SHARING WITH ALL OTHER TAPE-FILE
   WRITE TAPE-FILE-RECORD 
       FROM "COBOL treats tape files and text files identically."
   END-WRITE
   STOP RUN.</lang>

Go

Taking a cue from the discussion page, this creates an optionally compressed tar (tape archive) file on stdout (or written to a file or a device such as /dev/tape). The tar archive will contain a single file, called TAPE.FILE by default, with the contents of the command line -data option or stdin. <lang go>package main

import (

       "archive/tar"
       "compress/gzip"
       "flag"
       "io"
       "io/ioutil"
       "log"
       "os"
       "os/user"
       "time"

)

func main() {

       filename := flag.String("file", "TAPE.FILE", "filename within TAR")
       dataStr := flag.String("data", "", "data for file, or stdin if empty")
       outfile := flag.String("out", "", "output file or device (e.g. /dev/tape)")
       gzipFlag := flag.Bool("gzip", false, "use gzip compression")
       flag.Parse()
       userinfo, err := user.Current()
       if err != nil {
               log.Fatal(err)
       }
       data := []byte(*dataStr)
       if len(data) == 0 {
               data, err = ioutil.ReadAll(os.Stdin)
               if err != nil {
                       log.Fatal(err)
               }
               os.Stdin.Close()
       }
       var w io.Writer = os.Stdout
       if *outfile != "" {
               f, err := os.Create(*outfile)
               if err != nil {
                       log.Fatalf("opening/creating %q: %v", *outfile, err)
               }
               defer f.Close()
               w = f
       }
       if *gzipFlag {
               zw := gzip.NewWriter(w)
               defer zw.Close()
               w = zw
       }
       tw := tar.NewWriter(w)
       defer tw.Close()
       hdr := &tar.Header{
               Name:     *filename,
               Mode:     0660,
               Size:     int64(len(data)),
               ModTime:  time.Now(),
               Typeflag: tar.TypeReg,
               Uname:    userinfo.Username,
               Gname:    userinfo.Gid,
       }
       tw.WriteHeader(hdr)
       _, err = tw.Write(data)
       if err != nil {
               log.Fatal("writing data:", err)
       }

}</lang>

Output:
% go run tapefile.go -h
Usage of tapefile:
  -data="": data for file, or stdin if empty
  -file="TAPE.FILE": filename within TAR
  -gzip=false: use gzip compression
  -out="": output file or device (e.g. /dev/tape)

% go run tapefile.go -data "Hello World" -gzip | tar -tvzf -
-rw-rw----  0 guest guest       11  6 Aug 12:42 TAPE.FILE

Icon and Unicon

This solution mimics the solution used in many other languages here and works in both Icon and Unicon. <lang unicon>procedure main()

   write(open("/dev/tape","w"),"Hi")

end</lang>

JCL

<lang JCL>// EXEC PGM=IEBGENER //* Create a file named "TAPE.FILE" on magnetic tape; "UNIT=TAPE" //* may vary depending on site-specific esoteric name assignment //SYSPRINT DD SYSOUT=* //SYSIN DD DUMMY //SYSUT2 DD UNIT=TAPE,DSN=TAPE.FILE,DISP=(,CATLG) //SYSUT1 DD * DATA TO BE WRITTEN TO TAPE /* </lang>

Nimrod

<lang nimrod>var t = open("/dev/tape", fmWrite) t.writeln "Hi Tape!" t.close</lang>

Perl 6

<lang perl6>my $tape = open "/dev/tape", :w or die "Can't open tape: $!"; $tape.say: "I am a tape file now, or hope to be soon."; $tape.close;</lang>

PicoLisp

<lang PicoLisp>(out "/dev/tape"

  (prin "Hello World!") )</lang>

Python

<lang python>>>> with open('/dev/tape', 'w') as t: t.write('Hi Tape!\n') ... >>> </lang>

Racket

<lang Racket>

  1. lang racket

(with-output-to-file "/dev/tape" #:exists 'append

 (λ() (displayln "I am a cheap imitation of the Perl code for a boring problem")))

</lang>

REXX

<lang rexx>/*REXX pgm demonstrates writing records to an attached magnetic tape.*/ /* The actual mounting & attaching would be performed by the appropriate*/ /* operating system (and/or user) commands. DSNAME (below) would be */ /* the REXX variable that is associated with a dataset that is assigned */ /* to a magnetic tape device. The association would be different, */ /* depending on upon the operating system being used. VM/CMS would use */ /* a CP ATTACH command, coupled with a CMS FILEDEF command which*/ /* associates a DSNAME (dataset name) that will be written to on the */ /* attached (and mounted) magnetic tape device. */

dsName = 'TAPE.FILE' /*dsName of "file" being written.*/

         do j=1  for 100              /*write 100 records to mag tape. */
         call lineout  dsName,  'this is record'   j   ||   "."
         end   /*j*/
                                      /*stick a fork in it, we're done.*/</lang>

Scala

Unix

Assuming device is attached to "tape" <lang Scala>object LinePrinter extends App {

 import java.io.{ FileWriter, IOException }
 {
   val lp0 = new FileWriter("/dev/tape")
   lp0.write("Hello, world!")
   lp0.close()
 }

}</lang>

Tcl

Tcl does not have built-in special support for tape devices, so it relies on the OS to handle most of the details for it. Assuming a relatively modern Unix:

Translation of: UNIX Shell

<lang tcl>cd /tmp

  1. Create the file

set f [open hello.jnk w] puts $f "Hello World!" close $f

  1. Archive to tape

set fin [open "|tar cf - hello.jnk" rb] set fout [open /dev/tape wb] fcopy $fin $fout close $fin close $fout</lang>

TUSCRIPT

<lang tuscript>$$ MODE TUSCRIPT STATUS = CREATE ("tape.file",tape-o,-std-) PRINT STATUS</lang> Output:

OK

UNIX Shell

<lang bash>#!/bin/sh cd # Make our home directory current echo "Hello World!" > hello.jnk # Create a junk file

  1. tape rewind # Uncomment this to rewind the tape

tar c hello.jnk # Traditional archivers use magnetic tape by default

  1. tar c hello.jnk > /dev/tape # With newer archivers redirection is needed</lang>

ZX Spectrum Basic

The ZX Spectrum does not have file type extensions, so we save as TAPEFILE, rather than TAPE.FILE. We can use any start address, depending on where we want the data to come from. Here we dump the contents of the screen: <lang zxbasic>SAVE "TAPEFILE" CODE 16384,6912</lang>