File input/output: Difference between revisions
No edit summary |
No edit summary |
||
Line 453: | Line 453: | ||
Using File |
Using File |
||
new File('output.txt').write(new File('input.txt').text) |
new File('output.txt').write(new File('input.txt').text) |
||
Using a writer |
|||
⚫ | |||
⚫ | |||
⚫ | |||
Using Ant |
Using Ant |
||
new AntBuilder().copy(file:'input.txt', toFile:'output.txt', overwrite:true) |
|||
Buffered |
|||
⚫ | |||
⚫ | |||
⚫ | |||
==[[Haskell]]== |
==[[Haskell]]== |
Revision as of 19:47, 19 September 2007
You are encouraged to solve this task according to the task description, using any language you may know.
In this task, the job is to create a file called "output.txt", and place in it the contents of the file "input.txt".
Ada
Compiler: GCC 4.1.2
The following example will work in most situations. If the file line size exceeds the size of the input string the output file will contain extra new-line characters.
with Ada.Text_IO; use Ada.Text_IO; procedure File_IO is Input, Output : File_Type; Line : String (1 .. 10_000); Last : Natural; begin Create (Output, Out_File, "output.txt"); Open (Input, In_File, "input.txt"); while not End_Of_File (Input) loop Get_Line (Input, Line, Last); Put_Line (Output, Line (1 .. Last)); end loop; Close (Input); Close (Output); end File_IO;
The following example reads and writes each file one character at a time. There is no new-line issue.
with Ada.Sequential_Io; procedure File_Io is package Char_Io is new Ada.Sequential_Io(Character); use Char_Io; Infile, Outfile : File_Type; Value : Character; begin Create(File => Outfile, Mode => Out_File, Name => "output.txt"); Open(File => Infile, Mode => In_File, Name => "input.txt"); while not End_Of_File(Infile) loop Read(File => Infile, Item => Value); Write(File => Outfile, Item => Value); end loop; Close(Infile); Close(Outfile); end File_IO;
AppleScript
on copyFile from src into dst set filedata to read file src set outfile to open for access dst with write permission write filedata to outfile close access outfile end copyFile copyFile from ":input.txt" into ":output.txt"
BASIC
Compiler: QuickBasic 4.5
OPEN "INPUT.TXT" FOR INPUT AS #1 OPEN "OUTPUT.TXT" FOR OUTPUT AS #2 DO UNTIL EOF(1) LINE INPUT #1, Data$ PRINT #2, Data$ LOOP CLOSE #1 CLOSE #2 SYSTEM
C
Compiler: GCC 4.1.2
<highlightSyntax language=C>
#include <stdio.h> int main(int argc, char **argv) { FILE *in, *out; int c; in = fopen("input.txt", "r"); if (!in) { fprintf(stderr, "Error opening input.txt for reading.\n"); return 1; } out = fopen("output.txt", "w"); if (!out) { fprintf(stderr, "Error opening output.txt for writing.\n"); fclose(in); return 1; } while ((c = fgetc(in)) != EOF) { fputc(c, out); } fclose(out); fclose(in); return 0; }
</highlightSyntax>
A couple of remarks on the preceding example:
It uses fgetc
to read one character at a time. Each character is
visited, even though there's nothing to do with it. Copying bigger
blocks of data is much more efficient.
It uses buffered IO to perform the move, which is overkill. This is not actually a weakness, but it invokes some overhead that you don't need.
It doesn't close the files afer it's done, relying on them being closed and their output flushed when the program exits. Not a problem in this particular case, but a bad habit to get into.
An example that addresses these:
<highlightSyntax language=C>
#include <stdio.h> #include <unistd.h> #include <fcntl.h> int main(int argc, char **argv) { int fi, fo; int len; char buf[1024]; /* a better choice is the FS block size, if you know it */ if ((fi = open("input.txt", O_RDONLY)) < 0) { perror("Can't read input.txt"); return 1; } if ((fo = open("output.txt", O_WRONLY|O_CREAT|O_TRUNC)) < 0) { perror("Can't write to output.txt"); return 1; } while ((len = read(fi, buf, 1024)) > 0) { if (write(fo, buf, len) < 0) { perror("write failed"); return 1; } } if (len < 0) { perror("read failed"); return 1; } close(fi); close(fo); return 0; }
</highlightSyntax>
C#
Platform: .NET
Language Version: 1.0+
using System; using System.IO; namespace FileIO { class Program { static void Main(string[] args) { if (File.Exists("input.txt")) { TextReader tr = File.OpenText("input.txt"); TextWriter tw = new StreamWriter(File.OpenWrite("output.txt")); while (tr.Peek() != -1) { string line = tr.ReadLine(); tw.WriteLine(line); } tw.Close(); tr.Close(); } else { Console.WriteLine("Input File Missing."); } } } }
C++
Compiler: GCC 3.4.2
#include <iostream> #include <fstream> #include <string> int main() { string line; ifstream input ( "input.txt" ); ofstream output ("output.txt"); if (output.is_open()) { if (input.is_open()){ while (! input.eof() ) { getline (input,line); output << line << endl; } input.close(); } else { cout << "input.txt cannot be opened!\n"; } output.close(); } else { cout << "output.txt cannot be written to!\n"; } return 0; }
Simpler version:
#include <iostream> #include <fstream> #include <cstdlib> int main() { std::ifstream input("input.txt"); if (!input.is_open()) { std::cerr << "could not open input.txt for reading.\n"; return EXIT_FAILURE; } std::ofstream output("output.txt"); if (!output.is_open()) { std::cerr << "could not open output.txt for writing.\n"; return EXIT_FAILURE; } output << input.rdbuf(); if (!output) { std::cerr << "error copying the data.\n"; return EXIT_FAILURE; } return EXIT_SUCCESS; }
Using istream- and ostream- iterators:
# include <algorithm> # include <fstream> int main() { std::ifstream ifile("input.txt"); std::ofstream ofile("output.txt"); std::copy(std::istreambuf_iterator<char>(ifile), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(ofile)); }
Clean
Define a function that copies the content from one file to another.
import StdEnv copyFile fromPath toPath world # (ok, fromFile, world) = fopen fromPath FReadData world | not ok = abort ("Cannot open " +++ fromPath +++ " for reading") # (ok, toFile, world) = fopen toPath FWriteData world | not ok = abort ("Cannot open " +++ toPath +++ " for writing") # (fromFile, toFile) = copyData 1024 fromFile toFile # (ok, world) = fclose fromFile world | not ok = abort ("Cannot close " +++ fromPath +++ " after reading") # (ok, world) = fclose toFile world | not ok = abort ("Cannot close " +++ toPath +++ " after writing") = world where copyData bufferSize fromFile toFile # (buffer, fromFile) = freads fromFile bufferSize # toFile = fwrites buffer toFile | size buffer < bufferSize = (fromFile, toFile) // we're done = copyData bufferSize fromFile toFile // continue recursively
Apply this function to the world to copy a file.
Start world = copyFile "input.txt" "output.txt" world
ColdFusion
<cfif fileExists(expandPath("input.txt"))> <cffile action="read" file="#expandPath('input.txt')#" variable="inputContents"> <cffile action="write" file="#expandPath('output.txt')#" output="#inputContents#"> </cfif>
Delphi
Delphi supports both typed and untyped as well as a textfile type for files. Delphi provides a default 128 byte buffer for text files. This may be enlarged via a call to SetTextBuff(Var F: Text; Var Buf [Size : integer]) procedure. All other files have no buffer at all and it is the programmers option to do buffering.
The following file I/O procedures have existed since Turbo Pascal V-3.
- Read(F,V1..Vn) - ReadLn(F,V1..Vn) - Write(F,V1[,V2..Vn]) - WriteLn(f,V1[,V2..Vn]) - BlockRead(F,Buff,BytesToRead[,BytesRead]) - BlockWrite(F,Buff,BytesToRead[,BytesWritten])
Files are opened using:
AssignFile(f,{fully qualified path and file name})
Assigns the file name to the file structure in preparation for opening.
Reset(f)
Opens and existing file. If it does not exist EIOError is raised.
Rewrite(f)
Creates a new file and opens it for I/O. If the files exists is is overwritten.
Delphi implemented Streams of which a varient is TFileStream and are vry closely related to the Windows API for file handling.
- Text File I/O -
var f : TextFile ; s : string ; begin AssignFile(f,[fully qualified file name); Reset(f); writeln(f,s); Reset(f); ReadLn(F,S); CloseFile( end;
- Untyped File I/O -
This is perhaps one of the most powerfull I/O functions built into Pascal. This will allow you to open and read a file of ANY type, regardless of structure, size or content. Note the usage of Reset(). This is using the optional size paramter that instructs the record size of file I/O. This could have been called with SizeOf(Buff) as the optional parameter but that would have limited flexibility. Calling it with a size of ONE byte allows you to adjust the buffer size on the fly, as conditions warrant. Also note the use of the BytesRead parameter. When included in the BlockRead() function it will return the number of bytes actualy read. If this is not included, then if your directive to read n bytes is greater then the size of the file, the EOF will be encountered unexpectedly and EIOError will be reaised.
var f : File ; buff : array[1.1024] of byte ; BytesRead : Integer ; begin AssignFile(f,fully qualified file name); Reset(f,1); Blockread(f,Buff,SizeOf(Buff),BytesRead); CloseFile(f); end;
- Typed File I/O -
Typed file I/O is very useful when reading and writing structures. An Address List is quiet easy to write when using this type of I/O. The same file procedures are used with some subtle differences. Bite below in the blockread and blockwrite procedures that the bytes to read or write are 1. Also note that the reset procedure is not called with a buffer size. When performing Typed File I/O the size of the type definition is the buffer size. In the BlockRead() and BlockWrite() procedures I elected to read one record. Had I declared a very large buffer of type tAddressBook of say 500 records, I could have set bytes to read as SizeOf(Buffer) thereby reading a minimum of 500 records.
type tAddressBook = Record FName : string[20]; LName : string[30]; Address : string[30]; City : string[30]; State : string[2]; Zip5 : string[5]; Zip4 : string[4]; Phone : string[14]; Deleted : boolean ; end; var f : file of tAddressBook ; v : tAddressBook ; bytes : integer ; begin AssignFile(f,fully qualified file name); Reset(f); Blockread(f,V,1,Bytes); Edit(v); Seek(F,FilePos(f)-1); BlockWrite(f,v,1,bytes); CloseFile(f); end;
E
Implementation: E-on-Java
<file:output.txt>.setText(<file:input.txt>.getText())
(This version holds the entire contents in memory.)
Forth
Forth traditionally has not had any file handling capabilities, prefering instead to operate on a disk image block by block. Most modern Forth systems however run under an existing operating system and provide methods for disk access.
\ <to> <from> copy-file : copy-file ( a1 n1 a2 n2 -- ) r/o open-file throw >r w/o create-file throw r> begin pad maxstring 2 pick read-file throw ?dup while pad swap 3 pick write-file throw repeat close-file throw close-file throw ;
\ Invoke it like this: s" output.txt" s" input.txt" copy-file
Note the use of "2 pick" to get the input file handle and "3 pick" to get the output file handle. Local or global variables could have been used, but in this implementation simple stack manipulation was chosen. Also, only maxstring bytes are copied at a time, and the global "pad" memory area is used to hold the data. For faster copies, allocating a larger buffer could be advantageous.
Also, abort" can be used instead of throw if desired.
Groovy
Using File
new File('output.txt').write(new File('input.txt').text)
Using Ant
new AntBuilder().copy(file:'input.txt', toFile:'output.txt', overwrite:true)
Buffered
new File('output.txt').withWriter( w -> new File('input.txt').withReader( r -> w << r } }
Haskell
Interpreter: GHCi
Note: this doesn't keep the file in memory. Buffering is provided by lazy evaluation.
copyFile from to = do filedata <- readFile from writeFile to filedata main = copyFile "input.txt" "output.txt"
IDL
; open two LUNs openw,unit1,'output.txt,/get openr,unit2,'input.txt',/get ; how many bytes to read fs = fstat(unit2) ; make buffer buff = bytarr(fs.size) ; transfer content readu,unit2,buff writeu,unit1,buff ; that's all close,/all
Java
Compiler: GCJ 4.1.2
Simple version; Files may be closed automatically by OS, on some systems. This example is broken: it needs a finally.
import java.io.*; public class FileIODemo { public static void main(String[] args) { try { FileInputStream in = new FileInputStream("input.txt"); FileOutputStream out = new FileOutputStream("ouput.txt"); int c; while ((c = in.read()) != -1) { out.write(c); } } catch (Exception e) { e.printStackTrace(); } } }
This version closes both files after without OS intervention
import java.io.*; public class FileIODemo2 { public static void main(String args[]) { try { // Probably should wrap with a BufferedInputStream final InputStream in = new FileInputStream("input.txt"); try { // Probably should wrap with a BufferedOutputStream final OutputStream out = new FileOutputStream("output.txt"); try { int c; while ((c = in.read()) != -1) { out.write(c); } } finally { out.close(); } } finally { in.close(); } } catch (Exception e) { System.err.println("Exception while trying to copy: "+e); e.printStackTrace(); // stack trace of place where it happened } } }
Language Version 1.4
Package nio
import java.io.*; import java.nio.channels.*; public class FileIODemo3 { public static void main(String args[]) { try { final FileChannel in = new FileInputStream("input.txt").getChannel(); try { final FileChannel out = new FileOutputStream("output.txt").getChannel(); try { out.transferFrom(in, 0, in.size()); } finally { out.close(); } } finally { in.close(); } } catch (Exception e) { System.err.println("Exception while trying to copy: "+e); e.printStackTrace(); // stack trace of place where it happened } } }
This version is more in line with the other languages' implementations: it assumes simple text files, and doesn't worry too much about errors (just throws them out to the caller, the console in this case). Its shorter and simpler and shows that simple programs can be simple to write, in Java as well.
import java.io.*; public class Test { public static void main (String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader("input.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt")); for (String line; (line = br.readLine()) != null; ) { bw.write(line); bw.newLine(); } br.close(); bw.close(); } }
mIRC Scripting Language
Interpreter: mIRC
alias Write2FileAndReadIt { .write myfilename.txt Goodbye Mike! .echo -a Myfilename.txt contains: $read(myfilename.txt,1) }
Objective-C
Compiler: gcc
Read the contents of input.txt and place it in output.txt, creating a file if needed:
NSData *input = [NSData dataWithContentsOfFlie:@"input.txt"]; [data writeToFile:@"output.txt" atomically:YES];
Displayed without error checking to make it more clear. In real code you will need to add lot of error checking code, and maybe use dataWithContentsOfFile:error: if you want to get error information on failure. However, this code will mostly work correctly even if input does not exists or not accessible. dataWithContentsOfFlie: will return nil, and sending nil the message writeTofile:atomically: does nothing :-)
The second argument "atomically:YES" write the content to a temporary file, and rename the temporary file to the destination file, replacing existing file.
Perl
Interpreter: Perl 5.8.8
#!/usr/bin/perl open my $fh_in, '<', 'input.txt' or die "could not open <input.txt> for reading: $!"; open my $fh_out, '>', 'output.txt' or die "could not open <output.txt> for writing: $!"; # '>' overwrites file, '>>' appends to file, just like in the shell binmode $fh_out; # marks filehandle for binary content on systems where that matters print $fh_out $_ while <$fh_in>; # prints current line to file associated with $fh_out filehandle # the same, less concise #while (<$fh_in>) { # print $fh_out $_; #}; close $fh_in; close $fh_out;
Perl has also a powerful mechanism in conjunction with opening files called IO disciplines. It allows you to automatically apply chainable transformations on the input and output. Mangling newlines, gzip (de)compression and character encoding are the most used examples.
PHP
Interpreter: PHP 4
<?php if (!$in=fopen('input.txt','r')) { die('Could not open input.txt!'); } if (!$out=fopen('output.txt','w')) { die('Could not open output.txt!'); } while(!feof($in)) { $data = fread($in,512); fwrite($out,$data); } fclose($out); fclose($in); ?>
Interpreter: PHP 5
<?php if( $contents = file_get_contents('input.txt') ){ if( !file_put_contents('output.txt') ) echo('could not write output file'); }else{ echo('could not open input file'); } ?>
Pop11
Char by char copy:
lvars i_stream = discin('input.txt'); lvars o_stream = discout('output.txt'); lvars c; while (i_stream() ->> c) /= termin do o_stream(c); endwhile;
Low level block copy:
lvars i_file = sysopen('input.txt', 0, true); lvars o_file = syscreate('output.txt', 1, true); lvars buff = inits(4096); lvars i; while (sysread(i_file, buff, length(buff)) ->> i) > 0 do syswrite(o_file, buff, i); endwhile;
Python
Interpreter: Python 2.4
In short form:
open("output.txt", "w").writelines(open("input.txt"))
With proper closing:
inputFile = open("input.txt","r") try: outputFile = open("output.txt", "w") try: outputFile.writelines(inputFile) finally: outputFile.close() finally: inputFile.close()
Interpreter: Python 2.5
Using the new with statement for automatic closing even in case of error:
from __future__ import with_statement from contextlib import nested try: with nested(file("input.txt"), file("output.txt", "w")) as ( input_file, output_file): output_file.writelines(input_file) except IOError, e: print e
Ruby
Interpreter: Ruby 1.8.4
begin File.open("output.txt","w") {|f| f << IO.read("input.txt")} rescue Exception => e $stderr.puts "Exception raised: #{e}" end
Standard ML
Interpreter: SML/NJ v110.59
fun copyFile (from, to) = let val instream = TextIO.openIn from val outstream = TextIO.openOut to val () = TextIO.output (outstream, TextIO.inputAll instream) val () = TextIO.closeIn instream val () = TextIO.closeOut outstream in true end handle _ => false;
Tcl
Interpreter: tclsh, eTcl, wish, tixwish
set in [open "input.txt" r] set out [open "output.txt" w] puts -nonewline $out [read $in] close $in close $out
or the minimal version if we don't need any processing of the data
file copy input.txt output.txt
Other File I/O:
#open file for writing set myfile [open "README.TXT" w] #write something to the file puts $myfile "This is line 1, so hello world...." #close the file close $myfile
#open file for reading set myfile [open "README.TXT" r] #read something from the file gets $myfile mydata #show what was read from the file #should print "This is line1, so hello world...." puts $mydata #close the file close $myfile
Toka
This is one method, which works with any type of file:
( source dest -- ) { value| source dest size buffer | { { [ "W" file.open to dest ] is open-dest [ "R" file.open to source ] is open-source [ open-dest open-source ] } is open-files { [ source file.size to size ] is obtain-size [ size malloc to buffer ] is allocate-buffer [ obtain-size allocate-buffer ] } is create-buffer [ source dest and 0 <> ] is check [ open-files create-buffer check ] } is prepare [ source buffer size file.read drop ] is read-source [ dest buffer size file.write drop ] is write-dest [ source file.close dest file.close ] is close-files [ prepare [ read-source write-dest close-files ] ifTrue ] } is copy-file
And a much simpler way for plain text files, making use of file.slurp:
[ ( source dest -- ) swap file.slurp dup 0 <> [ >r "W" file.open dup r> string.getLength file.write drop file.close ] ifTrue ] is copy-file
And a test:
" input.txt" " output.txt" copy-file
UNIX Shell
Bourne Shell
#!/bin/sh while read a; do echo "$a" done <input.txt >output.txt
Another way, using the 'cat' program
#!/bin/sh cat input.txt >output.txt
Yet another way, using the 'cp' utility
#!/bin/sh cp input.txt output.txt