Skip to content

Commit 31c0d3a

Browse files
committed
[IO-513] Add convenience methods for reading class path resources.
Apply and evlove patch from Behrang Saeedzadeh.
1 parent b1ee00d commit 31c0d3a

4 files changed

Lines changed: 343 additions & 1 deletion

File tree

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ The <action> type attribute can be add,update,fix,remove.
8686
<action issue="IO-519" dev="jochen" type="add">
8787
Add MessageDigestCalculatingInputStream
8888
</action>
89+
<action issue="IO-513" dev="ggregory" type="add" due-to="Behrang Saeedzadeh">
90+
Add convenience methods for reading class path resources.
91+
</action>
8992
<action issue="IO-514" dev="pschumacher" type="remove">
9093
Remove org.apache.commons.io.Java7Support
9194
</action>

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

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public class IOUtils {
134134

135135
static {
136136
// avoid security issues
137-
try (final StringBuilderWriter buf = new StringBuilderWriter(4);
137+
try (final StringBuilderWriter buf = new StringBuilderWriter(4);
138138
final PrintWriter out = new PrintWriter(buf)) {
139139
out.println();
140140
LINE_SEPARATOR = buf.toString();
@@ -1249,6 +1249,132 @@ public static String toString(final byte[] input, final String encoding) throws
12491249
return new String(input, Charsets.toCharset(encoding));
12501250
}
12511251

1252+
// resources
1253+
//-----------------------------------------------------------------------
1254+
1255+
/**
1256+
* Gets the contents of a classpath resource as a String using the
1257+
* specified character encoding.
1258+
*
1259+
* <p>
1260+
* It is expected the given <code>name</code> to be absolute. The
1261+
* behavior is not well-defined otherwise.
1262+
* </p>
1263+
*
1264+
* @param name name of the desired resource
1265+
* @param encoding the encoding to use, null means platform default
1266+
* @return the requested String
1267+
* @throws IOException if an I/O error occurs
1268+
*
1269+
* @since 2.6
1270+
*/
1271+
public static String resourceToString(final String name, final Charset encoding) throws IOException {
1272+
return resourceToString(name, encoding, null);
1273+
}
1274+
1275+
/**
1276+
* Gets the contents of a classpath resource as a String using the
1277+
* specified character encoding.
1278+
*
1279+
* <p>
1280+
* It is expected the given <code>name</code> to be absolute. The
1281+
* behavior is not well-defined otherwise.
1282+
* </p>
1283+
*
1284+
* @param name name of the desired resource
1285+
* @param encoding the encoding to use, null means platform default
1286+
* @param classLoader the class loader that the resolution of the resource is delegated to
1287+
* @return the requested String
1288+
* @throws IOException if an I/O error occurs
1289+
*
1290+
* @since 2.6
1291+
*/
1292+
public static String resourceToString(final String name, final Charset encoding, ClassLoader classLoader) throws IOException {
1293+
return toString(resourceToURL(name, classLoader), encoding);
1294+
}
1295+
1296+
/**
1297+
* Gets the contents of a classpath resource as a byte array.
1298+
*
1299+
* <p>
1300+
* It is expected the given <code>name</code> to be absolute. The
1301+
* behavior is not well-defined otherwise.
1302+
* </p>
1303+
*
1304+
* @param name name of the desired resource
1305+
* @return the requested byte array
1306+
* @throws IOException if an I/O error occurs
1307+
*
1308+
* @since 2.6
1309+
*/
1310+
public static byte[] resourceToByteArray(final String name) throws IOException {
1311+
return resourceToByteArray(name, null);
1312+
}
1313+
1314+
/**
1315+
* Gets the contents of a classpath resource as a byte array.
1316+
*
1317+
* <p>
1318+
* It is expected the given <code>name</code> to be absolute. The
1319+
* behavior is not well-defined otherwise.
1320+
* </p>
1321+
*
1322+
* @param name name of the desired resource
1323+
* @param classLoader the class loader that the resolution of the resource is delegated to
1324+
* @return the requested byte array
1325+
* @throws IOException if an I/O error occurs
1326+
*
1327+
* @since 2.6
1328+
*/
1329+
public static byte[] resourceToByteArray(final String name, final ClassLoader classLoader) throws IOException {
1330+
return toByteArray(resourceToURL(name, classLoader));
1331+
}
1332+
1333+
/**
1334+
* Gets a URL pointing to the given classpath resource.
1335+
*
1336+
* <p>
1337+
* It is expected the given <code>name</code> to be absolute. The
1338+
* behavior is not well-defined otherwise.
1339+
* </p>
1340+
*
1341+
* @param name name of the desired resource
1342+
* @return the requested URL
1343+
* @throws IOException if an I/O error occurs
1344+
*
1345+
* @since 2.6
1346+
*/
1347+
public static URL resourceToURL(final String name) throws IOException {
1348+
return resourceToURL(name, null);
1349+
}
1350+
1351+
/**
1352+
* Gets a URL pointing to the given classpath resource.
1353+
*
1354+
* <p>
1355+
* It is expected the given <code>name</code> to be absolute. The
1356+
* behavior is not well-defined otherwise.
1357+
* </p>
1358+
*
1359+
* @param name name of the desired resource
1360+
* @param classLoader the class loader that the resolution of the resource is delegated to
1361+
* @return the requested URL
1362+
* @throws IOException if an I/O error occurs
1363+
*
1364+
* @since 2.6
1365+
*/
1366+
public static URL resourceToURL(final String name, final ClassLoader classLoader) throws IOException {
1367+
// What about the thread context class loader?
1368+
// What about the system class loader?
1369+
final URL resource = classLoader == null ? IOUtils.class.getResource(name) : classLoader.getResource(name);
1370+
1371+
if (resource == null) {
1372+
throw new IOException("Resource not found: " + name);
1373+
}
1374+
1375+
return resource;
1376+
}
1377+
12521378
// readLines
12531379
//-----------------------------------------------------------------------
12541380

src/test/java/org/apache/commons/io/IOUtilsTestCase.java

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,218 @@ private void testToString_URL(final String encoding) throws Exception {
11401140
testToString_URL(null);
11411141
}
11421142

1143+
@Test public void testResourceToString_ExistingResourceAtRootPackage() throws Exception {
1144+
final long fileSize = new File(getClass().getResource("/test-file-simple-utf8.bin").getFile()).length();
1145+
final String content = IOUtils.resourceToString("/test-file-simple-utf8.bin", StandardCharsets.UTF_8);
1146+
1147+
assertNotNull(content);
1148+
assertEquals(fileSize, content.getBytes().length);
1149+
}
1150+
1151+
@Test public void testResourceToString_ExistingResourceAtRootPackage_WithClassLoader() throws Exception {
1152+
final long fileSize = new File(getClass().getResource("/test-file-simple-utf8.bin").getFile()).length();
1153+
final String content = IOUtils.resourceToString(
1154+
"test-file-simple-utf8.bin",
1155+
StandardCharsets.UTF_8,
1156+
ClassLoader.getSystemClassLoader()
1157+
);
1158+
1159+
assertNotNull(content);
1160+
assertEquals(fileSize, content.getBytes().length);
1161+
}
1162+
1163+
@Test public void testResourceToString_ExistingResourceAtSubPackage() throws Exception {
1164+
final long fileSize = new File(getClass().getResource("/org/apache/commons/io/FileUtilsTestDataCR.dat").getFile()).length();
1165+
final String content = IOUtils.resourceToString("/org/apache/commons/io/FileUtilsTestDataCR.dat", StandardCharsets.UTF_8);
1166+
1167+
assertNotNull(content);
1168+
assertEquals(fileSize, content.getBytes().length);
1169+
}
1170+
1171+
@Test public void testResourceToString_ExistingResourceAtSubPackage_WithClassLoader() throws Exception {
1172+
final long fileSize = new File(getClass().getResource("/org/apache/commons/io/FileUtilsTestDataCR.dat").getFile()).length();
1173+
final String content = IOUtils.resourceToString(
1174+
"org/apache/commons/io/FileUtilsTestDataCR.dat",
1175+
StandardCharsets.UTF_8,
1176+
ClassLoader.getSystemClassLoader()
1177+
);
1178+
1179+
assertNotNull(content);
1180+
assertEquals(fileSize, content.getBytes().length);
1181+
}
1182+
1183+
@Test(expected = IOException.class) public void testResourceToString_NonExistingResource() throws Exception {
1184+
IOUtils.resourceToString("/non-existing-file.bin", StandardCharsets.UTF_8);
1185+
}
1186+
1187+
@Test(expected = IOException.class) public void testResourceToString_NonExistingResource_WithClassLoader() throws Exception {
1188+
IOUtils.resourceToString("non-existing-file.bin", StandardCharsets.UTF_8, ClassLoader.getSystemClassLoader());
1189+
}
1190+
1191+
@Test public void testResourceToString_NullResource() throws Exception {
1192+
boolean exceptionOccurred = false;
1193+
1194+
try {
1195+
IOUtils.resourceToString(null, StandardCharsets.UTF_8);
1196+
fail();
1197+
} catch (NullPointerException npe) {
1198+
exceptionOccurred = true;
1199+
assertNotNull(npe);
1200+
}
1201+
1202+
assertTrue(exceptionOccurred);
1203+
}
1204+
1205+
@Test public void testResourceToString_NullResource_WithClassLoader() throws Exception {
1206+
boolean exceptionOccurred = false;
1207+
1208+
try {
1209+
IOUtils.resourceToString(null, StandardCharsets.UTF_8, ClassLoader.getSystemClassLoader());
1210+
fail();
1211+
} catch (NullPointerException npe) {
1212+
exceptionOccurred = true;
1213+
assertNotNull(npe);
1214+
}
1215+
1216+
assertTrue(exceptionOccurred);
1217+
}
1218+
1219+
@Test public void testResourceToString_NullCharset() throws Exception {
1220+
IOUtils.resourceToString("/test-file-utf8.bin", null);
1221+
}
1222+
1223+
@Test public void testResourceToString_NullCharset_WithClassLoader() throws Exception {
1224+
IOUtils.resourceToString("test-file-utf8.bin", null, ClassLoader.getSystemClassLoader());
1225+
}
1226+
1227+
@Test public void testResourceToByteArray_ExistingResourceAtRootPackage() throws Exception {
1228+
final long fileSize = new File(getClass().getResource("/test-file-utf8.bin").getFile()).length();
1229+
final byte[] bytes = IOUtils.resourceToByteArray("/test-file-utf8.bin");
1230+
assertNotNull(bytes);
1231+
assertEquals(fileSize, bytes.length);
1232+
}
1233+
1234+
@Test public void testResourceToByteArray_ExistingResourceAtRootPackage_WithClassLoader() throws Exception {
1235+
final long fileSize = new File(getClass().getResource("/test-file-utf8.bin").getFile()).length();
1236+
final byte[] bytes = IOUtils.resourceToByteArray("test-file-utf8.bin", ClassLoader.getSystemClassLoader());
1237+
assertNotNull(bytes);
1238+
assertEquals(fileSize, bytes.length);
1239+
}
1240+
1241+
@Test public void testResourceToByteArray_ExistingResourceAtSubPackage() throws Exception {
1242+
final long fileSize = new File(getClass().getResource("/org/apache/commons/io/FileUtilsTestDataCR.dat").getFile()).length();
1243+
final byte[] bytes = IOUtils.resourceToByteArray("/org/apache/commons/io/FileUtilsTestDataCR.dat");
1244+
assertNotNull(bytes);
1245+
assertEquals(fileSize, bytes.length);
1246+
}
1247+
1248+
@Test public void testResourceToByteArray_ExistingResourceAtSubPackage_WithClassLoader() throws Exception {
1249+
final long fileSize = new File(getClass().getResource("/org/apache/commons/io/FileUtilsTestDataCR.dat").getFile()).length();
1250+
final byte[] bytes = IOUtils.resourceToByteArray("org/apache/commons/io/FileUtilsTestDataCR.dat", ClassLoader.getSystemClassLoader());
1251+
assertNotNull(bytes);
1252+
assertEquals(fileSize, bytes.length);
1253+
}
1254+
1255+
@Test(expected = IOException.class) public void testResourceToByteArray_NonExistingResource() throws Exception {
1256+
IOUtils.resourceToByteArray("/non-existing-file.bin");
1257+
}
1258+
1259+
@Test(expected = IOException.class) public void testResourceToByteArray_NonExistingResource_WithClassLoader() throws Exception {
1260+
IOUtils.resourceToByteArray("non-existing-file.bin", ClassLoader.getSystemClassLoader());
1261+
}
1262+
1263+
@Test public void testResourceToByteArray_Null() throws Exception {
1264+
boolean exceptionOccurred = false;
1265+
1266+
try {
1267+
IOUtils.resourceToByteArray(null);
1268+
fail();
1269+
} catch (NullPointerException npe) {
1270+
exceptionOccurred = true;
1271+
assertNotNull(npe);
1272+
}
1273+
1274+
assertTrue(exceptionOccurred);
1275+
}
1276+
1277+
@Test public void testResourceToByteArray_Null_WithClassLoader() throws Exception {
1278+
boolean exceptionOccurred = false;
1279+
1280+
try {
1281+
IOUtils.resourceToByteArray(null, ClassLoader.getSystemClassLoader());
1282+
fail();
1283+
} catch (NullPointerException npe) {
1284+
exceptionOccurred = true;
1285+
assertNotNull(npe);
1286+
}
1287+
1288+
assertTrue(exceptionOccurred);
1289+
}
1290+
1291+
@Test public void testResourceToURL_ExistingResourceAtRootPackage() throws Exception {
1292+
final URL url = IOUtils.resourceToURL("/test-file-utf8.bin");
1293+
assertNotNull(url);
1294+
assertTrue(url.getFile().endsWith("/test-file-utf8.bin"));
1295+
}
1296+
1297+
@Test public void testResourceToURL_ExistingResourceAtRootPackage_WithClassLoader() throws Exception {
1298+
final URL url = IOUtils.resourceToURL("test-file-utf8.bin", ClassLoader.getSystemClassLoader());
1299+
assertNotNull(url);
1300+
assertTrue(url.getFile().endsWith("/test-file-utf8.bin"));
1301+
}
1302+
1303+
@Test public void testResourceToURL_ExistingResourceAtSubPackage() throws Exception {
1304+
final URL url = IOUtils.resourceToURL("/org/apache/commons/io/FileUtilsTestDataCR.dat");
1305+
assertNotNull(url);
1306+
assertTrue(url.getFile().endsWith("/org/apache/commons/io/FileUtilsTestDataCR.dat"));
1307+
}
1308+
1309+
@Test public void testResourceToURL_ExistingResourceAtSubPackage_WithClassLoader() throws Exception {
1310+
final URL url = IOUtils.resourceToURL(
1311+
"org/apache/commons/io/FileUtilsTestDataCR.dat",
1312+
ClassLoader.getSystemClassLoader()
1313+
);
1314+
1315+
assertNotNull(url);
1316+
assertTrue(url.getFile().endsWith("/org/apache/commons/io/FileUtilsTestDataCR.dat"));
1317+
}
1318+
1319+
@Test(expected = IOException.class) public void testResourceToURL_NonExistingResource() throws Exception {
1320+
IOUtils.resourceToURL("/non-existing-file.bin");
1321+
}
1322+
1323+
@Test(expected = IOException.class) public void testResourceToURL_NonExistingResource_WithClassLoader() throws Exception {
1324+
IOUtils.resourceToURL("non-existing-file.bin", ClassLoader.getSystemClassLoader());
1325+
}
1326+
1327+
@Test public void testResourceToURL_Null() throws Exception {
1328+
boolean exceptionOccurred = false;
1329+
1330+
try {
1331+
IOUtils.resourceToURL(null);
1332+
fail();
1333+
} catch (NullPointerException npe) {
1334+
exceptionOccurred = true;
1335+
assertNotNull(npe);
1336+
}
1337+
1338+
assertTrue(exceptionOccurred);
1339+
}
1340+
1341+
@Test public void testResourceToURL_Null_WithClassLoader() throws Exception {
1342+
boolean exceptionOccurred = false;
1343+
1344+
try {
1345+
IOUtils.resourceToURL(null, ClassLoader.getSystemClassLoader());
1346+
fail();
1347+
} catch (NullPointerException npe) {
1348+
exceptionOccurred = true;
1349+
assertNotNull(npe);
1350+
}
1351+
1352+
assertTrue(exceptionOccurred);
1353+
}
1354+
11431355
@Test public void testAsBufferedNull() {
11441356
try {
11451357
IOUtils.buffer((InputStream) null);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ABC

0 commit comments

Comments
 (0)