Skip to content

Commit 0031a91

Browse files
committed
IO-305: New copyLarge() method in IOUtils that takes additional offset, length arguments
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/io/trunk@1301851 13f79535-47bb-0310-9956-ffa450edef68
1 parent 6dbc1b3 commit 0031a91

4 files changed

Lines changed: 364 additions & 0 deletions

File tree

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ $release.description.replaceAll(" ", "
2424
Changes in this version include:
2525

2626
New features:
27+
o IO-305: New copyLarge() method in IOUtils that takes additional offset, length arguments Thanks to Manoj Mokashi.
2728
o IO-287: Use terabyte (TB) , petabyte (PB) and exabyte (EB) in FileUtils.byteCountToDisplaySize(long size) Thanks to Ron Kuris, Gary Gregory.
2829
o IO-173: FileUtils.listFiles() doesn't return directories Thanks to Marcos Vin�cius da Silva.
2930
o IO-297: CharSequenceInputStream to efficiently stream content of a CharSequence Thanks to Oleg Kalnichevski.

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ The <action> type attribute can be add,update,fix,remove.
4040

4141
<body>
4242
<release version="2.2" date="TBA">
43+
<action issue="IO-305" dev="sebb" type="add" due-to="Manoj Mokashi">
44+
New copyLarge() method in IOUtils that takes additional offset, length arguments
45+
</action>
4346
<action issue="IO-300" dev="sebb" type="fix">
4447
FileUtils.moveDirectoryToDirectory removes source directory if destination is a subdirectory
4548
</action>

src/main/java/org/apache/commons/io/IOUtils.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,51 @@ public static long copyLarge(InputStream input, OutputStream output)
14571457
return count;
14581458
}
14591459

1460+
/**
1461+
* Copy some or all bytes from a large (over 2GB) <code>InputStream</code> to an
1462+
* <code>OutputStream</code>, optionally skipping input bytes.
1463+
* <p>
1464+
* This method buffers the input internally, so there is no need to use a
1465+
* <code>BufferedInputStream</code>.
1466+
* <p>
1467+
* The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1468+
*
1469+
* @param input the <code>InputStream</code> to read from
1470+
* @param output the <code>OutputStream</code> to write to
1471+
* @param offset : number of bytes to skip from input before copying
1472+
* -ve values are ignored
1473+
* @param length : number of bytes to copy. -ve means all
1474+
* @return the number of bytes copied
1475+
* @throws NullPointerException if the input or output is null
1476+
* @throws IOException if an I/O error occurs
1477+
* @since Commons IO 2.2
1478+
*/
1479+
public static long copyLarge(InputStream input, OutputStream output, final long offset, final long length)
1480+
throws IOException {
1481+
if( offset > 0){
1482+
skipFully( input, offset);
1483+
}
1484+
if (length == 0) {
1485+
return 0;
1486+
}
1487+
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
1488+
int bytesToRead = buffer.length;
1489+
if (length > 0 && length < buffer.length) {
1490+
bytesToRead = (int) length;
1491+
}
1492+
int read;
1493+
long totalRead = 0;
1494+
while(bytesToRead > 0 && -1 != (read=input.read(buffer, 0, bytesToRead))) {
1495+
output.write( buffer, 0, read);
1496+
totalRead += read;
1497+
if (length > 0) { // only adjust length if not reading to the end
1498+
// Note the cast must work because buffer.length is an integer
1499+
bytesToRead = (int) Math.min(length - totalRead, buffer.length);
1500+
}
1501+
}
1502+
return totalRead;
1503+
}
1504+
14601505
/**
14611506
* Copy bytes from an <code>InputStream</code> to chars on a
14621507
* <code>Writer</code> using the default character encoding of the platform.
@@ -1561,6 +1606,51 @@ public static long copyLarge(Reader input, Writer output) throws IOException {
15611606
return count;
15621607
}
15631608

1609+
/**
1610+
* Copy some or all chars from a large (over 2GB) <code>InputStream</code> to an
1611+
* <code>OutputStream</code>, optionally skipping input chars.
1612+
* <p>
1613+
* This method buffers the input internally, so there is no need to use a
1614+
* <code>BufferedReader</code>.
1615+
* <p>
1616+
* The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1617+
*
1618+
* @param input the <code>Reader</code> to read from
1619+
* @param output the <code>Writer</code> to write to
1620+
* @param offset : number of chars to skip from input before copying
1621+
* -ve values are ignored
1622+
* @param length : number of chars to copy. -ve means all
1623+
* @return the number of chars copied
1624+
* @throws NullPointerException if the input or output is null
1625+
* @throws IOException if an I/O error occurs
1626+
* @since Commons IO 2.2
1627+
*/
1628+
public static long copyLarge(Reader input, Writer output, final long offset, final long length)
1629+
throws IOException {
1630+
if( offset > 0){
1631+
skipFully( input, offset);
1632+
}
1633+
if (length == 0) {
1634+
return 0;
1635+
}
1636+
char[] buffer = new char[DEFAULT_BUFFER_SIZE];
1637+
int bytesToRead = buffer.length;
1638+
if (length > 0 && length < buffer.length) {
1639+
bytesToRead = (int) length;
1640+
}
1641+
int read;
1642+
long totalRead = 0;
1643+
while(bytesToRead > 0 && -1 != (read=input.read(buffer, 0, bytesToRead))) {
1644+
output.write( buffer, 0, read);
1645+
totalRead += read;
1646+
if (length > 0) { // only adjust length if not reading to the end
1647+
// Note the cast must work because buffer.length is an integer
1648+
bytesToRead = (int) Math.min(length - totalRead, buffer.length);
1649+
}
1650+
}
1651+
return totalRead;
1652+
}
1653+
15641654
/**
15651655
* Copy chars from a <code>Reader</code> to bytes on an
15661656
* <code>OutputStream</code> using the default character encoding of the

0 commit comments

Comments
 (0)