Rename a file extensionTag(s): IO


The first version
public static boolean renameFileExtension
     (String source, String newExtension)
{
   String target;
   String currentExtension = getFileExtension(source);

   if (currentExtension.equals("")){
      target = source + "." + newExtension;
   }
   else {
      target = source.replaceAll("." + currentExtension, newExtension);
   }
   return new File(source).renameTo(new File(target));
 }

 public static String getFileExtension(String f) {
   String ext = "";
   int i = f.lastIndexOf('.');
   if (i > 0 &&  i < f.length() - 1) {
      ext = f.substring(i + 1).toLowerCase();
   }
   return ext;
}

Comments from R.Millington (thanks to him!)

This code very very seriously flawed (the first version -ed.).

  • The toLowerCase() can cause this to fail on OS that have case sensitive file names. It should be removed.
  • The replaceAll() call is flawed since
    • the '.' in the pattern is not taken literally but is interpreted as any character.
    • the regex has no end-of-line anchor so if the extracted extension occurs more than once in the filename then all occurrences will be changed.
    • if the extracted extension contains any regex meta characters then they will be interpreted as part of the regex and the replaceAll() will probably fail. This can even cause an exception.
    • If the replacement extension contains any of the replacement meta characters then at best one will get the wrong extension and it can cause an exception.
This is fixed by changing the replaceAll() line to

target = source.replaceFirst(Pattern.quote("." +
currentExtension) + "$", Matcher.quoteReplacement("." + newExtension));

A revised version

import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FileUtils {

  public static boolean renameFileExtension
  (String source, String newExtension)
  {
    String target;
    String currentExtension = getFileExtension(source);

    if (currentExtension.equals("")){
      target = source + "." + newExtension;
    }
    else {
      target = source.replaceFirst(Pattern.quote("." +
          currentExtension) + "$", Matcher.quoteReplacement("." + newExtension));

    }
    return new File(source).renameTo(new File(target));
  }

  public static String getFileExtension(String f) {
    String ext = "";
    int i = f.lastIndexOf('.');
    if (i > 0 &&  i < f.length() - 1) {
      ext = f.substring(i + 1);
    }
    return ext;
  }

  public static void main(String args[]) throws Exception {
    System.out.println(
         FileUtils.renameFileExtension("C:/temp/capture.pdf", "pdfa")
         );
  }
}
To simply remove an extension, see this HowTo
blog comments powered by Disqus