...
| 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 |
...