8

I am scanning all directories starting from "/" to find some particular directories like "MYFOLDER". However, the folder is that I get double instances of the same folder. This occurs because one folder is located in "/mnt/sdcard/MYFOLDER" and the same folder has a symbolic link in "/sdcard/MYFOLDER"..

My Question is, "Is there any way to determine whether the folder is a symbolic link or not?". Please give me some suggestions..

rds
  • 26,253
  • 19
  • 107
  • 134
Farhan
  • 3,206
  • 14
  • 49
  • 62
  • You can check here: http://stackoverflow.com/questions/813710/java-1-6-determine-symbolic-links. It might help you! – Dimitris Makris Sep 02 '11 at 09:49
  • Sir, there is nothing specific about the code.. I have a very simple question. you scan directories using listFiles() function. However, there are two directories with the same name i.e., /mnt/scard and /sdcard. One is the symbolic link to the other. I just want to know if there is any way of distinguishing between these two.. Is there any way to know that the folder is a symbolic link.. Thank you so much – Farhan Sep 02 '11 at 09:50

1 Answers1

14

This is essentially how they do in Apache Commons (subject to their license):

public static boolean isSymlink(File file) throws IOException {
  File canon;
  if (file.getParent() == null) {
    canon = file;
  } else {
    File canonDir = file.getParentFile().getCanonicalFile();
    canon = new File(canonDir, file.getName());
  }
  return !canon.getCanonicalFile().equals(canon.getAbsoluteFile());
}

Edit thanks to @LarsH comment. The above code only checks whether the children file is a symlink.

In order to answer the OP question, it's even easier:

public static boolean containsSymlink(File file) {
  return !file.getCanonicalFile().equals(file.getAbsoluteFile());
}
rds
  • 26,253
  • 19
  • 107
  • 134
  • A helpful answer, +1. Any idea why they check for a parent file and use the parent's getCanonicalFile() instead of always just using canon = file? Does it have to do with "If a path element does not exist (or is not searchable), there is a conflict between interpreting canonicalization as a textual operation (where "a/../b" is "b" even if "a" does not exist) ."? – LarsH Jun 29 '15 at 21:55
  • 1
    Oh, I get it ... this is to determine only whether the *last component* in the `file`'s path is a symbolic link ... not whether *any component* in the file's path is a symbolic link. I think in the OP's case, we would want the latter, in which case we would drop the `else` clause of this function. – LarsH Jul 05 '15 at 09:51
  • 1
    @rds in containsSymLink(), Shouldn't there be a boolean not operator in the return value? (ie. return !file.getCanonical....) – hopia Aug 21 '15 at 21:42
  • Example: Google Nexus 4 (API 21) – isabsent Sep 01 '15 at 16:54
  • 1
    Example: Google Nexus 4 (API 21) has two dirs /storage/emulated/0 and /storage/emulated/legacy, each of them has containsSymlink = false (I mean "not" operator in containsSymlink as user "hopia" said above). Both dirs have the same content inside of them and therefore one of them should be a symlink of other, but your approach does not find it! – isabsent Sep 01 '15 at 17:08
  • 1
    The updated answer actually returns if the file _does not_ contain a symlink. It should be: `return !file.getCanonicalFile().equals(file.getAbsoluteFile());` (note the !) – Eric Lange Jan 24 '17 at 13:28
  • @isabsent, Same scenario as yours. I am getting containsSymlink as false for both the file paths. – AndroidDev Dec 17 '19 at 12:47