Add
org.apache.commons.io.FilenameUtils.isIllegalWindowsFileName(char).
MODIFY
src/changes/changes.xml
src/changes/changes.xml
@@ -47,8 +47,8 @@ The <action> type attribute can be add,update,fix,remove.
<body>
<!-- The release date is the date RC is cut -->
<release version="2.7" date="tba" description="tba">
- <action issue="IO-553" dev="ggregory" type="update">
- Add org.apache.commons.io.FilenameUtils.WINDOWS_ILLEGAL_FILE_NAME_CHARS.
+ <action issue="IO-553" dev="ggregory" type="add">
+ Add org.apache.commons.io.FilenameUtils.isIllegalWindowsFileName(char).
</action>
</release>

MODIFY
src/main/java/org/apache/commons/io/FilenameUtils.java
src/main/java/org/apache/commons/io/FilenameUtils.java
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Stack;
* @see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx">Naming Files,
* Paths, and Namespaces</a>
*/
- public static final char[] WINDOWS_ILLEGAL_FILE_NAME_CHARS = {
+ private static final char[] WINDOWS_ILLEGAL_FILE_NAME_CHARS = {
+ // KEEP THIS ARRAY SORTED!
// @formatter:off
// ASCII NULL
0,
// 1-31 may be allowed in file streams
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31,
- '<', '>', ':', '"', '/', '\\', '|', '?', '*'
+ '"', '*', '/', ':', '<', '>', '?', '\\', '|'
// @formatter:on
};
@@ -1290,6 +1292,35 @@ public static boolean isExtension(final String filename, final Collection<String
return false;
}
+ /**
+ * Checks whether the given character is illegal in a Windows file names.
+ * <p>
+ * The illegal character are:
+ * </p>
+ * <ul>
+ * <li>< (less than</li>
+ * <li>> (greater than</li>
+ * <li>: (colon</li>
+ * <li>" (double quote</li>
+ * <li>/ (forward slash</li>
+ * <li>\ (backslash</li>
+ * <li>| (vertical bar or pipe</li>
+ * <li>? (question mark</li>
+ * <li>* (asterisk</li>
+ * <li>ASCII NUL (0)</li>
+ * <li>Integer characters 1 through 31</li>
+ * </ul>
+ *
+ * @see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx">Naming Files,
+ * Paths, and Namespaces</a>
+ * @param c the character to check
+ * @return whether the give character is legal
+ * @since 2.7
+ */
+ public static boolean isIllegalWindowsFileName(final char c) {
+ return Arrays.binarySearch(WINDOWS_ILLEGAL_FILE_NAME_CHARS, c) >= 0;
+ }
+
//-----------------------------------------------------------------------
/**
* Checks a filename to see if it matches the specified wildcard matcher,

MODIFY
src/test/java/org/apache/commons/io/FilenameUtilsTestCase.java
src/test/java/org/apache/commons/io/FilenameUtilsTestCase.java
@@ -246,6 +246,28 @@ public void testNormalize() throws Exception {
assertEquals(SEP + SEP + "server" + SEP + "", FilenameUtils.normalize("//server/"));
}
+ @Test
+ public void testIsIllegalWindowsFileName() {
+ for (char i = 0; i < 32; i++) {
+ assertTrue(FilenameUtils.isIllegalWindowsFileName(i));
+ }
+ char[] illegal = new char[] { '<', '>', ':', '"', '/', '\\', '|', '?', '*' };
+ Arrays.sort(illegal);
+ System.out.println(Arrays.toString(illegal));
+ for (char i = 0; i < illegal.length; i++) {
+ assertTrue(FilenameUtils.isIllegalWindowsFileName(illegal[i]));
+ }
+ for (char i = 'a'; i < 'z'; i++) {
+ assertFalse("i = " + (int) i, FilenameUtils.isIllegalWindowsFileName(i));
+ }
+ for (char i = 'A'; i < 'Z'; i++) {
+ assertFalse("i = " + (int) i, FilenameUtils.isIllegalWindowsFileName(i));
+ }
+ for (char i = '0'; i < '9'; i++) {
+ assertFalse("i = " + (int) i, FilenameUtils.isIllegalWindowsFileName(i));
+ }
+ }
+
@Test
public void testNormalize_with_nullbytes() throws Exception {
try {

[IO-553] Add
org.apache.commons.io.FilenameUtils.isIllegalWindowsFileName(char).