views:

5288

answers:

25

Personally, I always forget this stuff. So I figured this is a useful thing to have as a reference.

  1. Read an ascii file into a string
  2. Write an ascii file from a string
  3. Read a binary file into something appropriate. If possible, store in a string, too.
  4. Write a binary file from something appropriate. If possible, write from a string, too.

Current Answers (sorted alphabetically):

  • Ada
  • Bash
  • C
  • C++
  • C#/.Net
  • Delphi
  • Groovy
  • Java
  • Lua
  • PHP
  • Perl
  • Python
  • R6RS Scheme
  • Rebol
  • Ruby
  • VB

Missing Answers:

  • Common Lisp
+1  A: 

I'll start. For Python:

#1/3.
filehandle = open('filename', 'r')
filetext = filehandle.read()
filehandle.close()

#2/4
filehandle = open('filename', 'w') #use 'a' to append
filehandle.write('string')
filehandle.close()
Brian
Alexander Kojevnikov's is probably more elegant.
Brian
A: 

Why would you blindly want to place an entire file in a string? Exspecialy binary files which have almost no use in that context?

Your better off reading/writing the files into an appropiate datastructure. eg for an ini file into a (for c++) "std::map >" which then stores all the sections, with there keys and vaules for easy access (eg "IniMap['mysection']['mykey'] = 'some string';")

Simerler things can be done for other files (althouh much more complex structure than a simple set of maps).

Fire Lancer
The main reason this is useful is because sometimes people write utilities which are useful both for strings and for files but only provide support for one of the two. A way to move between the two is useful.
Brian
Well then the utility is implemented badly. Under c++ theres the std::ostream and std::istream classes which can be basicly any output/input. For languages that don't have such a class implementing one isn't hard (eg just inherit from an IO class with a Read and Write method).
Fire Lancer
That's not always practical, especially if the utility is not open source and the language doesn't support that. Your suggestion seems overly idealistic and more time-consuming than necessary. Sure, it might be *better*, but often that really doesn't matter. This is simple and easy to understand.
Brian
For ASCII files, parsing special formats from a single string is a lot easier if a logical records in the file is stored in multiple lines.
alexandrul
*slurps* ... there are many reasons to work with a text file by reading it into memory as a string. much of the work i do with XML file works by reading the file into a string and then feeding that string into an xml parser method. In many cases it's a quick and easy solution.
stephenbayer
http://en.wikipedia.org/wiki/Worse_is_better
Brian
+2  A: 

Ruby:

#1, 3
IO.readlines("file.ext").to_s;

#2, 4
File.open("file.ext", "w") do |out|
  out << 'string'
end
Jonathan Lonowski
1,3: File.read("file.ext")
John Douthat
+3  A: 

R6RS Scheme:

(call-with-input-file "filename" get-string-all)

(call-with-output-file "filename" 
  (lambda (p) (put-string p "text")))

(call-with-port (open-input-file "filename") get-bytevector-all)

(call-with-port 
  (open-output-file "filename") 
  (lambda (p) (put-bytevector p bytes)))
leppie
looks like your missing the writes, but IDK.
Unkwntech
Oops, I think I got side tracked :)
leppie
+5  A: 

c#:

1: 
    string s = System.IO.File.ReadAllText(fileName);
2:
    System.IO.File.WriteAllText(fileName, s);
3:
    byte[] data = System.IO.File.ReadAllBytes(fileName);
4:
    System.IO.File.WriteAllBytes(fileName, data);
Loris
A: 

C:

1:

FILE *f = fopen ("filename", "rt");
struct _stat s;
_fstat (f->_file, &s);
char *str = (char *)malloc (s.st_size + 1);
fread (str, 1, s.st_size, f);
str[s.st_size - 1] = 0;
fclose (f);

2:

char *str = "something";
FILE *f = fopen ("filename", "wt");
fwrite (str, 1, strlen (str), f);
fclose (f);

3:

FILE *f = fopen ("filename", "rb");
struct _stat s;
_fstat (f->_file, &s);
unsigned char *data = (unsigned char *)malloc (s.st_size);
fread (data, 1, s.st_size, f);
fclose (f);

4:

unsigned char *data = pointer_to_data;
int dataSize = 1337;
FILE *f = fopen ("filename", "wb");
fwrite (data, 1, dataSize, f);
fclose (f);
korona
The standard C fopen() does not recognize the 't' as part of the mode parameter. I'd get rid of it ... http://www.opengroup.org/onlinepubs/009695399/functions/fopen.html
pmg
ephemient
A: 

PHP:
1&3

<?php
     $file = implode('', file('filename')); //I imploded the file because file() returns an array with the file split at \n
?>

2&4 (a bit more work, but not much)

<?php
    $handle = fopen('filename', 'w+b'); //b can be removed if not in windows
    fwrite($handle, $data);
    fclose($handle);
?>
Unkwntech
Why go to that effort?file_put_contentsfile_get_contents
Fire Lancer
+1  A: 

Perl:

# 1, 3
open(R, "<", "file.ext");
#binmode R; # uncomment as needed
$contents = join('', <R>);
close(R);

# 2, 4
open(W, ">", "file.ext");
#binmode W; # uncomment as needed
print W "string";
close(W);

Further reading: binmode

Jonathan Lonowski
$contents = do { local $/; <R> }; # more efficient
xdg
A: 

Bash.

1:

VAR=$(< file)

Or:

read -d $'\0' VAR < file

2:

echo "$VAR" > file
Bruno De Fraine
Even shorter syntax, which doesn't require forking `cat` (and yes, it looks funny but it really works): VAR=$(<file) or VAR=`<file`
ephemient
Thanks, I had forgotten about that!
Bruno De Fraine
A: 

Delphi

1/3:

memo.lines.loadfromfile('filename');
s := memo.lines.text;

2/4:

memo.lines.text := s;
memo.lines.savetofile('filename');

This assumes that there is a tmemo component on the screen. Alternatively one could just create a TStringList and call loadfromfile or savetofile as the lines property is just that, a Tstringlist.

TStringlist has a property text that is of type string.

Ralph Rickenbach
+5  A: 

Python 2.6+ or 2.5 with from __future__ import with_statement

1/3:

with open('filename') as f:
    s = f.read()

2/4:

with open('filename', 'w') as f:
    f.write('data')
Alexander Kojevnikov
A: 

Groovy:

  1. result = new File(filename).text

  2. new File(filename).text = source

  3. result = new File(filename).readBytes()

  4. new File(filename).withOutputStream{ it<<source }

Randy Hudson
A: 

rebol:

1) data: read %file

2) write %file data

3) bin: read/binary %file

4) write/binary %file bin

A: 

Lua

local input = io.open("input", "r")
local output = io.open("output", "w")

local content = input:read("*a")
output:write(content)

input:close()
output:close()

For binary mode, just add "b" to the flag in open(file, flag)

Kknd
+1  A: 

Lazy Perl:

open FH, '<', 'input.txt';
undef $/;  # don't split on newlines, just read the whole thing
# binmode FH;
$contents = <FH>;
close FH;
open FH, '>', 'output.txt';
# binmode FH;
print FH $contents;
close FH;

Even lazier (and hackish) Perl:

$contents = do { local (@ARGV, $/) = 'input.txt'; <> };  # binmode ARGV; before <>
print {do {open my $fh, '>output.txt'; $fh}} $contents;  # binmode $fh; before }

Very lazy Perl (reuse of code is good!):

use File::Slurp;
$contents = read_file('input.txt');  # or read_file(..., binmode => ':raw')
write_file('output.txt', $contents);  # or write_file(..., binmode => ':raw')
ephemient
A: 

C on UNIX, ASCII and binary is all the same:

#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

struct stat info;
int fd, length;
void *contents;

fd = open("input.txt", O_RDONLY);
fstat(fd, &info);
length = info.st_size;
if (sane) {
    contents = malloc(length);
    read(fd, contents, length);
}
else  // because UNIX is awesome!
    contents = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);

fd = open("output.txt", O_RDONLY | O_CREAT | O_TRUNC);
if (sane)
    write(fd, contents, length);
else {  // because UNIX is awesome!
    void *output;
    ftruncate(fd, length);
    output = mmap(NULL, length, PROT_WRITE, MAP_SHARED, fd, 0);
    memcpy(output, input, length);
    munmap(output);
}
close(fd);

if (sane)
    free(contents);
else
    munmap(contents, length);

Caution, complete lack of error checking.

ephemient
+1  A: 

Haskell, 1/2:

main = do
    contents <- readFile "input.txt"
    writeFile "output.txt" contents

Haskell, 3/4:

import qualified Data.ByteString.Lazy as B
main = do
    contents <- B.readFile "input.txt"
    B.writeFile "output.txt" contents
ephemient
Elegant as always.
Hai
+9  A: 

C++

There are many ways, you pick which is the most elegant for you.

Reading into char*:

ifstream file ("file.txt", ios::in|ios::binary|ios::ate);
if (file.is_open())
{
    size = file.tellg();
    char *contents = new char [size];
    file.seekg (0, ios::beg);
    file.read (contents, size);
    file.close();
}

Into std::string:

std::ifstream in("file.txt");
std::string contents((std::istreambuf_iterator<char>(in)), 
    std::istreambuf_iterator<char>());

Into vector<char>:

std::ifstream in("file.txt");
std::vector<char> contents((std::istreambuf_iterator<char>(in)),
    std::istreambuf_iterator<char>());

Into std::string, using std::stringstream:

std::ifstream in("file.txt");
std::stringstream buffer;
buffer << in.rdbuf();
std::string contents(buffer.str());

file.txt is just an example, everything works fine for binary files as well, just make sure you use ios::binary in ifstream constructor.

Writing goes the other way around and uses ofstream instead.

Milan Babuškov
+1  A: 

VB6

'1/3
Private Function ReadFile(Filename As String) As String
    Dim fileHandle As Long
    fileHandle = FreeFile
    Open Filename For Binary As #fileHandle
    ReadFile = Space(LOF(fileHandle))
    Get #fileHandle, 1, ReadFile
    Close #fileHandle
End Function


'2/4
Private Sub WriteFile(InputData As String, Filename As String)
    Dim fileHandle As Long
    fileHandle = FreeFile
    Open Filename For Binary As #fileHandle
    Put #fileHandle, 1, InputData
    Close #fileHandle
End Sub

Note that this won't work quite right for VB-formatted files made using standard VB i/o for strings, since VB adds quote and the like (well, it'll work but have the quotes and whatnot). However, really long strings tend to be much faster with this method. Also note that this is probably not a good idea with unicode (see here instead).

Edit: The following test may fail:

WriteFile tmpo, "c:\tmp\jox.dat"
jjj = ReadFile("c:\tmp\jox.dat")
if tmpo = jjj then 
    'pass
    else
    'fail
end if
Brian
A: 

Standard ML, 1/2:

val contents =
  let val fh = TextIO.openIn "input.txt"
  in TextIO.inputAll fh before TextIO.closeIn fh end

let val fh = TextIO.openOut "output.txt"
in TextIO.output (fh, contents); TextIO.closeOut fh end

Replace TextIO with BinIO for 3/4.

ephemient
+1  A: 

Java

Here is the simplest I cat get. I'm not that sure for efficient.

Anyone has a sample using nio?

C:\oreyes\samples\java\reading>type Read.java
 import java.io.*;

 public class Read{

     private byte[] readBin( String file ) throws IOException {
         FileInputStream fis = new FileInputStream( file );
         byte[] data = new byte[fis.available()];
         fis.read( data );
         fis.close();
         return data;
     }
     private void writeBin( String file, byte[] data ) throws IOException {
         FileOutputStream fos = new FileOutputStream( file );
         fos.write( data, 0, data.length );
         fos.close();
     }

     private void writeToFile( String file, String content ) throws IOException {
         PrintWriter out = new PrintWriter( new File( file ) );
         out.print( content );
         out.close();
     }
     private String readFile( String file ) throws IOException {
        BufferedReader reader = new BufferedReader( new FileReader (file));
        String line  = null;
        StringBuilder stringBuilder = new StringBuilder();
        String ls = System.getProperty("line.separator");
        while( ( line = reader.readLine() ) != null ) {
            stringBuilder.append( line );
            stringBuilder.append( ls );
        }
        return stringBuilder.toString();
     }

     public static void main( String [] args )  throws IOException {
         Read r = new Read();
         r.writeToFile("x.java", r.readFile("Read.java"));
         r.writeBin("x.class", r.readBin("Read.class"));
         assert new File("x.java").exists();
         assert new File("x.class").exists();
         assert new File("Read.java").length() == new File("x.java").length();
         assert new File("Read.class").length() == new File("x.class").length();
         System.out.println("finish");
     }

}

C:\oreyes\samples\java\reading>java -ea Read
finish
OscarRyz
Bugs here: for the string reading/writing, the `"US-ASCII"` charset should be used or you're using the platform encoding. `FileXXXputStream.close()` should be in a finally block to avoid leaking file handles on error. `FileInputStream.read(byte[])` does not guarantee to fill the buffer - check the return value.
McDowell
A: 

Ruby take 2: reading File.read("filename.ext")

writing File.open("filename.ext") do |f| f.write "stuff" end

rogerdpack
+1  A: 

PL/I:

READFILE: PROCEDURE OPTIONS(MAIN, REORDER);
    DECLARE INFILE FILE RECORD INPUT ENVIRONMENT(RECORD_SIZE(80));
    DECLARE EOF BIT(1) INIT('1'B);
    DECLARE LINE_BUF CHARACTER(80);
    DECLARE FILE_BUF CHARACTER(*);

    OPEN FILE(INFILE) TITLE('file.txt');
    ON ENDFILE(INFILE) EOF = '1'B;

    READ FILE(INFILE) INTO(LINE_BUF);
    DO WHILE(^EOF)
        FILE_BUF = FILE_BUF || LINE_BUF;
        READ FILE(INFILE) INTO(LINE_BUF);
    END;

    CLOSE FILE(INFILE);
END READFILE;
TMN
+2  A: 

PHP:

  1. $str = file_get_contents('filename.txt');

  2. file_put_contents('filename.txt', $str);

  3. $bin = file_get_contents('filename.bin');

  4. file_put_contents('filename.bin', $bin);

Jon Benedicto
A: 

That's pretty easy in Ada, although it can get a bit more complex if you want to do something like pre-size the string properly.

For ASCII (actually LATIN1):

Input, Output : Text_IO.File_Type;
String_Read   : String (1..256);

Text_IO.Open (Input, Text_IO.In_File, "infile.txt");
Text_IO.Open (Output, Text_IO.Out_File, "outfile.txt");

Text_IO.Get (Input, String_Read);
Text_IO.Get (Output, String_Read);

For an arbitrary data type its pretty much the same code, but using an instantiation of the generic Sequential_IO:

package My_Type_IO is new Sequential_IO(My_Type);

Input, Output : My_Type_IO_IO.File_Type;
My_Type_Read  : My_Type;

My_Type_IO.Open (Input, My_Type_IO.In_File, "infile.txt");
My_Type_IO.Open (Output, My_Type_IO.Out_File, "outfile.txt");

My_Type_IO.Get (Input, My_Type_Read);
My_Type_IO.Get (Output, My_Type_Read);
T.E.D.