Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
def fos= new FileOutputStream('TestFile.txt')

//These methods are available for all output streams, not just for FileOutputStream:
[ 21, 34, 43, 79 ].each{ fos.write(it) }
    //write out the lowest-order 8 bits of the supplied integer
fos.flush()
fos.write([69, 32, 22] as byte[])
fos.write([10, 11, 12, 13, 88, 89] as byte[], 3, 2)
    //write 2 bytes from array starting at index 3
fos.close()
try{ fos.write(77); assert 0 }catch(e){ assert e instanceof IOException }
    //no writing after file closed


//check the byte contents of the file with a File utility method:
assert new File('TestFile.txt').readBytes().toList() ==
    [ 21, 34, 43, 79, 69, 32, 22, 13, 88 ]


def fis= new FileInputStream('TestFile.txt')

//These methods are available for all input streams, not just for FileInputStream:
assert fis.available() == 9
    //an estimate of the num of bytes left for reading or skipping in the input stream
assert fis.read() == 21 //actually, the next byte is returned as an integer
fis.skip(2) //skip over, here, 2 bytes of data from the stream
assert fis.available() == 6
def ba2= new byte[3]
fis.read(ba2)
assert ba2.toList() == [79, 69, 32]
def ba3= new byte[6]
assert fis.read(ba3, 3, 2) == 2 //fill ba3 with 2 elements from index 3,
                                //return num of elements copied, here, 2
assert ba3.toList() == [0, 0, 0, 22, 13, 0]
assert fis.read(ba3) == 1 //return num of elements copied, here, 1
assert ba3.toList() == [88, 0, 0, 22, 13, 0]
assert fis.read(ba3) == -1 //return -1 if already at end-of-stream
if(
fis.markSupported() ){ //true if this input stream support the mark() and reset() methods...
 if( fis.markSupported() ){
  fis.reset()
      //reset reading to beginning of stream if mark() hasn't ever been called
   assert fis.read() == 21
   fis.mark(0) //mark this position in the stream; argument has no meaning here
   fis.read(new byte[4])
   fis.reset() //reset reading to where the last mark() method was called
   assert fis.read() == 34
}
fis.close()
try{ fis.read(); assert 0 }catch(e){ assert e instanceof IOException }


new File('TestFile.txt').delete() // delete the file used by this example

...

Code Block
def fw= new FileWriter('TestFile.txt')

//These methods are available for all writers, not just for FileWriter:
[ 'a', 'b' ].each{ fw.write(it as char) } //write out the supplied character
[ 'cd', 'efg' ].each{ fw.write(it) } //write out the supplied string
fw.flush()
fw.write(['h', 'i', 'j'] as char[])
fw.write(['h', 'i', 'j', 'k', 'l', 'm'] as char[], 3, 2)
    //write 2 chars from array starting at index 3
fw.write('klmnopq', 2, 4) //write 4 chars from string starting at index 2
fw.append('q' as char). //these Java 5.0 methods allow chaining
     append('rstuv').
     append('uvwxyz', 2, 6)
       //use subsequence from index 2 to index 6 of supplied string
fw.close()
try{ fw.write('z'); assert 0 }catch(e){ assert e instanceof IOException }
    //no writing after file closed


assert new File('TestFile.txt').readLines() == [ 'abcdefghijklmnopqrstuvwxyz' ]


def fr= new FileReader('TestFile.txt')

//These methods are available for all readers, not just for FileReader:
if(fr.ready()){
   assert fr.read() == 'a'
   fr.skip(2) //skip over, here, 2 chars
   def ca2= new char[3]
   fr.read(ca2)
   assert ca2.toList()*.toString() == ['d', 'e', 'f']
   def ca3= new char[6]
 
  assert fr.read(ca3, 3, 2) == 2 //fill ca3 with 2 elements from index 3,
                                 //return num of elements copied, here, 2
   assert ca3.toList()*.toString() == ['\0', '\0', '\0', 'g', 'h', '\0']
                                 //similar to InputStream method
   fr.skip(20)
   assert fr.read(ca3) == -1 //return -1 if already at end-of-stream
 
if( fr.markSupported() ){ //true if this input stream support the mark() and reset() methods...
     if( fr.markSupported() ){
    fr.reset()
        //reset reading to beginning of stream if mark() hasn't ever been called
       assert fr.read() == 'a' as char
       fr.mark(0) //mark this position in the stream; argument has no meaning here
       fr.read(new char[4])
       fr.reset() //reset reading to where the last mark() method was called
       assert fr.read() == 'b' as char
   }
   fr.close()
   try{ fr.read(); assert 0 }catch(e){ assert e instanceof IOException }
}


new File('TestFile.txt').delete() //delete the file used by this example

Closing Streams

When we write to an output stream or writer such as FileWriter, we should always close() it in some way:

Code Block
//here, because we don't close() the FileWriter, if there's an IOException,
//some written data may be lost...
def fw= new FileWriter('TestFile1.txt')
try{
   fw.write('abc\r\ndefg')
   throw new IOException('') //simulate error on write() in previous line
}catch(e){ }
assert new File('TestFile1.txt').readLines().toList() == []
    //nothing written because wasn't closed or flushed
new File('TestFile1.txt').delete()
assert new File('TestFile1.txt').exists() //not deleted because wasn't closed

//here, we close() the FileWriter in a 'finally' block, not losing any written
//data...
def fw2= new FileWriter('TestFile2.txt')
try{
   try{
       fw2.write('abc\r\ndefg')
       throw new IOException('') //simulate error on write() in previous line
   }finally{
       fw2.close() //or flush() file so no data will be lost when exception thrown
   }
}catch(e){ }
assert new File('TestFile2.txt').readLines() == ['abc', 'defg']
    //contents written OK
new File('TestFile2.txt').delete()
assert ! new File('TestFile2.txt').exists() //file deleted OK

//using withWriter() always closes the File, whatever is thrown inside
//closure...
try{
   new File('TestFile3.txt').withWriter(){ w->
       w.write('abc\r\ndefg')
       throw new IOException('') //simulate error on write() in previous line
   }
}catch(e){ }
new File('TestFile3.txt').delete()
assert ! new File('TestFile3.txt').exists()
    //deleted OK because withWriter() closed the file

...

Code Block
new File('TestFile1.txt').withWriter{ w->
   w<< 'abc' << 'def' //operator syntax
   w.leftShift('ghi').leftShift('jkl') //equivalent method name
}

//file overwritten because it already exists...
new File('TestFile1.txt').withWriter('unicode'){ w->
//file overwritten because it already exists
  w<< 'abcdefghij'
}

new File('TestFile1.txt').withWriterAppend('unicode'){ w->
   w<< 'klmnop' //although appending, unicode marker 0xFEFF also added
}

//here, we'll use concatenation format for string because it's easier to read
def fw= new FileWriter('TestFile1.txt')
fw.withWriter{ w->
   ['ab,cd\n' + 'efg\n' + 'hi,jk\n' + 'l', 'mn,op'].each{
//we use concatenation format forw<< string because it's
easier to read
    w<< it
  }
}

new File('TestFile1.txt').withReader{ r->
   assert r.read() == 'a'
}

def list= []
new File('TestFile1.txt').eachLine{
   list<< it
}
assert list == ['ab,cd', 'efg', 'hi,jk', 'lmn,op']

assert new File('TestFile1.txt').readLines() ==
    ['ab,cd', 'efg', 'hi,jk', 'lmn,op']

assert new File('TestFile1.txt').text ==
    'ab,cd\n' + 'efg\n' + 'hi,jk\n' + 'lmn,op' //property

//filter lines from file, and write to writer...
def fw2= new FileWriter('TestFile2.txt')
new File('TestFile1.txt').filterLine(fw2){ line->
//filter lines from file, and write to writer
  ! line.contains('g')
}
assert new File('TestFile2.txt').text ==
  'ab,cd\r\n' + 'hi,jk\r\n' + 'lmn,op\r\n'
    // \n was changed to \r\n for Windows
only
<<REMOVE

def fw2a= new FileWriter('TestFile2.txt')
new FileReader('TestFile1.txt').filterLine(fw2a){ line->
   ! line.contains('g')
}
assert new File('TestFile2.txt').text ==
    'ab,cd\r\n' + 'hi,jk\r\n' + 'lmn,op\r\n'


def fr2= new FileReader('TestFile2.txt')
assert [fr2.readLine(), fr2.readLine()] == ['ab,cd', null]
    //known bug: only returns correctly on first call
fr2.close()

new FileReader('TestFile2.txt').withReader{ r->
   def ca= new char[25]
   r.read(ca)
   assert ca.toList().join('').trim() == 'ab,cd\r\n' + 'hi,jk\r\n' + 'lmn,op'
}

def list2= []
new FileReader('TestFile2.txt').splitEachLine(','){ line->
   list2<< line
}
assert list2 == [ ['ab', 'cd'], ['hi', 'jk'], ['lmn', 'op'] ]

def fw2b= new FileWriter('TestFile2.txt')
new FileReader('TestFile1.txt').transformLine(fw2b){ line->
   if( line.contains(',') ) line += ',z'
   line
}
assert new File('TestFile2.txt').text ==
    'ab,cd,z\r\n' + 'efg\r\n' + 'hi,jk,z\r\n' + 'lmn,op,z\r\n'

def fw2c= new FileWriter('TestFile2.txt')
new FileReader('TestFile1.txt').transformLine(fw2c){ line->
   if( line.contains(',') ) line += ',z'
   line
}
assert new File('TestFile2.txt').text ==
    'ab,cd,z\r\n' + 'efg\r\n' + 'hi,jk,z\r\n' + 'lmn,op,z\r\n'

def fw2d= new FileWriter('TestFile2.txt')
new FileReader('TestFile1.txt').transformChar(fw2d){ ch->
   if(ch == ',') ch= '***'
   ch
}
assert new File('TestFile2.txt').text ==
    'ab***cd\n' + 'efg\n' + 'hi***jk\n' + 'lmn***op' // \n not converted

[new File('TestFile1.txt'), new File('TestFile2.txt')].each{ it.delete() }
    //delete files created by this example

...

Code Block
new File('TestFile1.txt').withOutputStream{ os->
   os<< ([95, 96] as byte[]) //operator syntax for byte arrays
   os.leftShift( [97, 98, 99] as byte[] ) //equivalent method name
}

assert new File('TestFile1.txt').readBytes().toList() == [95, 96, 97, 98, 99]

def list= []
new File('TestFile1.txt').eachByte(){ b->
   list<< b
}
assert list == [95, 96, 97, 98, 99]

new FileOutputStream('TestFile1.txt').withStream{ os->
   os.write([100, 101, 102, 103] as byte[])
}

def list2= []
new FileInputStream('TestFile1.txt').eachByte(){ b->
   list2<< b
}
assert list2 == [100, 101, 102, 103]

new File('TestFile1.txt').withInputStream{ is->
   def ba= new byte[5]
   is.read(ba)
   assert ba == [100, 101, 102, 103, 0]
}

new FileInputStream('TestFile1.txt').withStream{ s->
   def ba= new byte[5]
   s.read(ba)
   assert ba == [100, 101, 102, 103, 0]
}

assert new FileInputStream('TestFile1.txt').text == 'defg'

assert new FileInputStream('TestFile1.txt').getText('unicode') == '摥晧'

new FileInputStream('TestFile1.txt').withReader{ r->
   assert r.read() == 'd'
}

new FileOutputStream('TestFile2.txt').withWriter('unicode'){ w->
   w<< '我是法国人'
}
assert new FileInputStream('TestFile2.txt').getText('unicode') == '我是法国人'

new FileOutputStream('TestFile2.txt').withWriter{ w->
   w<< new FileInputStream('TestFile1.txt')
        //send contents of input stream directly to output stream
   w<< 2.495 << '\n' //send an object to output stream as string, returning 
                    //a writer, then send another object to that writer
   w<< [3,4,5]
        //send another object to output stream as string, returning a writer
}
assert new FileInputStream('TestFile2.txt').text == 'defg2.495\n' + '[3, 4, 5]'

def list3= []
new FileInputStream('TestFile2.txt').eachLine{ line->
   list3<< line
}
assert list3 == ['defg2.495', '[3, 4, 5]']

new FileInputStream('TestFile2.txt').readLine() == 'defg2.495'

new FileInputStream('TestFile2.txt').readLines() == ['defg2.495', '[3, 4, 5]']

def fw3= new FileWriter('TestFile3.txt')
new FileInputStream('TestFile2.txt').filterLine(fw3){ line->
   line.contains('g')
}
assert new File('TestFile3.txt').readLines() == ['defg2.495']

[ new File('TestFile1.txt'),
  new File('TestFile2.txt'),
  new File('TestFile3.txt')].each{ it.delete() }

Although the examples above are for files, they're all available for streams, readers, and writers around all other resources also.

Resource-specific Streams

When we met the FileInputStream, FileOutputStream, FileReader, and FileWriter in the above examples, we constructed them with a single String. We can also construct them with a file, and add an 'append' flag:

Code Block
def fos= new FileOutputStream(new File('TestFile.txt'), true)
                                                           //appends to the file
fos= new FileOutputStream(new File('TestFile.txt'), false) //overwrites the file
fos= new FileOutputStream(new File('TestFile.txt'))               //overwrites the file
fos= new FileOutputStream('TestFile.txt', true)   //appends to the file
fos= new FileOutputStream('TestFile.txt', false) //overwrites the file
fos= new FileOutputStream('TestFile.txt')               //overwrites the file

def fis= new FileInputStream(new File('TestFile.txt'))
fis= new FileInputStream('TestFile.txt')

def fw= new FileWriter(new File('TestFile.txt'), true) //appends to the file
fw= new FileWriter(new File('TestFile.txt'), true) //overwrites the file
fw= new FileWriter(new File('TestFile.txt'))             //overwrites the file
fw= new FileWriter('TestFile.txt',   true) //appends to the file
fw= new FileWriter('TestFile.txt', false) //overwrites the file
fw= new FileWriter('TestFile.txt')               //overwrites the file

def fr= new FileReader(new File('TestFile.txt'))
fr= new FileReader('TestFile.txt')

...

Code Block
def bais= new ByteArrayInputStream( [33, 34, 35] as byte[] )
[33, 34, 35, -1].each{ assert bais.read() == it }
def bais2=
      new ByteArrayInputStream( [33, 34, 35, 36, 37, 38, 39] as byte[], 2, 4 )
[35, 36, 37, 38, -1].each{ assert bais2.read() == it }

def baos= new ByteArrayOutputStream()
baos.write([100, 101, 102, 103] as byte[])
assert baos.size() == 4
assert baos.toByteArray().toList() == [100, 101, 102, 103]

def baos2= new ByteArrayOutputStream(10)
    //we can specify initial size of internal buffer
baos.writeTo( baos2 ) //we can writeTo any OutputStream
assert baos2.toByteArray().toList() == [100, 101, 102, 103]
assert baos2.toString() == 'defg'
assert baos2.toString('unicode') == '摥晧'
baos2.reset()
assert baos2.toByteArray().toList() == []

...

Code Block
def car= new CharArrayReader( ['a', 'b', 'c'] as char[] )
['a', 'b', 'c', -1].each{ assert car.read() == it }
def car2=
      new CharArrayReader( ['a', 'b', 'c', 'd', 'e', 'f', 'g'] as char[], 2, 4 )
['c', 'd', 'e', 'f', -1].each{ assert car2.read() == it }

def caw= new CharArrayWriter()
caw.write(['a', 'b', 'c', 'd'] as char[])
assert caw.size() == 4
assert caw.toCharArray().toList() == ['a', 'b', 'c', 'd'].collect{ it as char }

def caw2= new CharArrayWriter(10)
      //we can specify initial size of internal buffer
caw.writeTo( caw2 ) //we can writeTo any Writer
assert caw2.toCharArray().toList() == ['a', 'b', 'c', 'd'].collect{ it as char }
assert caw2.toString() == 'abcd'
caw2.reset()
assert caw2.toCharArray().toList() == []

...

Code Block
def wtr= new OutputStreamWriter(new FileOutputStream('TheOutput.txt'))
wtr<< 'abc'
wtr.close()

def rdr= new InputStreamReader(new FileInputStream('TheOutput.txt'))
def list= []
rdr.eachLine{ list<< it }
assert list == ['abc']

println System.getProperty("file.encoding")
    //to see the default file encoding used

wtr= new OutputStreamWriter(new FileOutputStream('TheOutput.txt'), 'unicode')
wtr<< 'def'
println wtr.encoding //perhaps, 'UTF-16', as 'unicode' above is an alias
wtr.close()

rdr= new InputStreamReader(new FileInputStream('TheOutput.txt'), 'unicode')
println rdr.encoding
list= []
rdr.eachLine{ list<< it }
assert list == ['def']

...

Code Block
def bos= new BufferedOutputStream(new FileOutputStream('TheOutput.txt'))
println bos.buf.size() //see the size of the default buffer
bos= new BufferedOutputStream(new FileOutputStream('TheOutput.txt'), 16384)
      //set the buffer size
assert bos.buf.size() == 16384
bos= new File('TheOutput.txt').newOutputStream()
      //returns a buffered output stream

def bis= new BufferedInputStream(new FileInputStream('TheOutput.txt'))
bis= new BufferedInputStream(new FileInputStream('TheOutput.txt'), 16384)
      //set the buffer size
bis= new File('TheOutput.txt').newInputStream()
      //returns a buffered input stream

def bwtr= new BufferedWriter(new FileWriter('TheOutput.txt'))
bwtr= new BufferedWriter(new FileWriter('TheOutput.txt'), 16384)
      //set the buffer size
bwtr= new File('TheOutput.txt').newWriter() //returns a buffered writer
bwtr= new File('TheOutput.txt').newWriter('unicode')
bwtr= new File('TheOutput.txt').newWriter(true) //appends to the file
bwtr= new File('TheOutput.txt').newWriter('unicode', true) //appends to the file

def brdr= new BufferedReader(new FileReader('TheOutput.txt'))
brdr= new BufferedReader(new FileReader('TheOutput.txt'), 16384)
      //set the buffer size
brdr= new File('TheOutput.txt').newReader() //returns a buffered reader
brdr= new File('TheOutput.txt').newReader('unicode')
brdr= new FileInputStream('TheOutput.txt').newReader()

def file= new File('TheOutput.txt')
def wtr= file.newWriter()
wtr.writeLine('abc')
wtr.writeLine('def')
wtr.newLine() //writes blank line
wtr.close()
def rdr= file.newReader()
assert rdr.readLine() == 'abc' //doesn't return end-of-line characters
assert rdr.text == 'def' + '\r\n' + '\r\n' //returns end-of-line characters

...

Code Block
def f1= new File('TheOutput1.txt'),
       f2= new File('TheOutput2.txt'),
       f3= new File('TheOutput3.txt')
f1<< 'abc'; f2<< 'def'; f3<< 'ghij'
def list=[ new FileInputStream(f1),
           new FileInputStream(f2),
           new FileInputStream(f3) ]
def sis= new SequenceInputStream(new Vector(list).elements())
assert sis.text == 'abcdefghij'

...

Code Block
def w= new File('TheOutput.txt').newWriter()
w.writeLine('abc'); w.writeLine('defg'); w.close()

def lnr= new LineNumberReader(new FileReader('TheOutput.txt'))
lnr= new LineNumberReader(new FileReader('TheOutput.txt'), 16384)
      //set the buffer size
assert lnr.lineNumber == 0
assert lnr.readLine() == 'abc'
assert lnr.lineNumber == 1
lnr.lineNumber= 4
assert lnr.readLine() == 'defg'
assert lnr.lineNumber == 5

...

Code Block
def ba= [7, 8, 9, 10, 11, 12, 13] as byte[]
def pis= new PushbackInputStream(new ByteArrayInputStream(ba))
pis= new PushbackInputStream(new ByteArrayInputStream(ba), 1024)
      //or specify buffer size
def ba2= new byte[3]
pis.read(ba2)
assert ba2.toList() == [7, 8, 9]

pis.unread(2)
pis.read(ba2)
assert ba2.toList() == [2, 10, 11]

pis.unread([3, 4, 5, 6] as byte[])
pis.read(ba2)
assert ba2.toList() == [3, 4, 5]
pis.read(ba2)
assert ba2.toList() == [6, 12, 13]

...

Code Block
def ca= ['g', 'h', 'i', 'j', 'k', 'l', 'm'] as char[]
def prdr= new PushbackReader(new CharArrayReader(ca))
prdr= new PushbackReader(new CharArrayReader(ca), 1024)
      //or specify buffer size
def ca2= new char[3]
prdr.read(ca2)
assert ca2.toList() == ['g', 'h', 'i'].collect{it as char}

prdr.unread('b' as int)
prdr.read(ca2)
assert ca2.toList() == ['b', 'j', 'k'].collect{it as char}

prdr.unread(['c', 'd', 'e', 'f'] as char[])
prdr.read(ca2)
assert ca2.toList() == ['c', 'd', 'e'].collect{it as char}
prdr.read(ca2)
assert ca2.toList() == ['f', 'l', 'm'].collect{it as char}

prdr.unread(['a', 'b', 'c', 'd', 'e', 'f', 'g'] as char[], 1, 4)
      //offset 1, length 4 of array
prdr.read(ca2)
assert ca2.toList() == ['b', 'c', 'd'].collect{it as char}

...

Code Block
def baos= new ByteArrayOutputStream(30)
def dos= new DataOutputStream(baos)
assert dos.size() == 0

def bais= new ByteArrayInputStream( baos.buf )
def dis= new DataInputStream(bais)

dos.writeBoolean( true )
assert baos.toByteArray().toList() == [1] //writes boolean as a 1-byte value
assert dis.readBoolean() == true

dos.writeByte( 200 ) //converted to -56, a 1-byte value
assert baos.toByteArray().toList() == [1, -56]
    //'true', followed by '200 as byte'
assert dis.readByte() == -56
dis.reset() //resets input stream
dis.skipBytes(1) //we can skip bytes
assert dis.readUnsignedByte() == 200
baos.reset() //flushes backing stream
dis.reset()

dos.writeBytes('abcdefg') //writes string as a sequence of bytes
assert baos.toByteArray() as List == [97, 98, 99, 100, 101, 102, 103]
dis.reset()
def ba= new byte[5]
dis.readFully(ba) //readFully() is converse of writeBytes()
assert ba as List == [97, 98, 99, 100, 101]
dis.reset()

ba= new byte[5]
dis.readFully(ba, 1, 2) //offset 1 and length 2 of ba
assert ba as List == [0, 97, 98, 0, 0]
baos.reset(); dis.reset()

dos.writeChar('a' as int) //writes char as 2-byte value, high byte first
assert baos.toByteArray() as List == [0, 97]
assert dis.readChar() == 'a'
baos.reset(); dis.reset()

dos.writeChars('ab') //writes string as a sequence of characters
assert baos.toByteArray() as List == [0, 97, 0, 98]
baos.reset(); dis.reset() //DataInputStream has no readChars() method

dos.writeShort(5000) //writes a short as two bytes, high byte first
assert baos.toByteArray() as List == [19, -120] && 20*256 - 120 == 5000
assert dis.readShort() == 5000
dis.reset()
dis.readUnsignedShort() == 5000 //similar to readUnsignedByte()
baos.reset(); dis.reset()

dos.writeInt(5000) //writes an integer as four bytes, high byte first
assert baos.toByteArray() as List == [0, 0, 19, -120]
assert dis.readInt() == 5000
baos.reset(); dis.reset()

dos.writeLong(5000) //writes a long as eight bytes, high byte first
assert baos.toByteArray() as List == [0, 0, 0, 0, 0, 0, 19, -120]
assert dis.readLong() == 5000
baos.reset(); dis.reset()

dos.writeDouble(123.456)
    //calls Double.doubleToLongBits(), writes as 8 bytes, high first
println baos.toByteArray() as List
assert dis.readDouble() == 123.456d
baos.reset(); dis.reset()

dos.writeFloat(123.456f)
    //calls Float.floatToIntBits(), writes as 4 bytes, high first
println baos.toByteArray() as List
assert dis.readFloat() == 123.456f
baos.reset(); dis.reset()

dos.writeUTF('abc')
    //writes using "modified UTF-8 encoding in a machine-independent manner"
assert baos.toByteArray() as List == [0, 3, 97, 98, 99]
    //UTF-8 adds 0, 3 at beginning
assert dis.readUTF() == 'abc'
dis.reset()
assert DataInputStream.readUTF(dis) == 'abc'
    //a static method to perform the same action

...