android: determining a symbolic link
Asked Answered
M

1

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..

Missymist answered 2/9, 2011 at 9:35 Comment(2)
You can check here: #814210. It might help you!Heteroecious
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 muchMissymist
D
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());
}
Dugaid answered 2/9, 2011 at 9:51 Comment(7)
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) ."?Unmoved
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.Unmoved
@Dugaid in containsSymLink(), Shouldn't there be a boolean not operator in the return value? (ie. return !file.getCanonical....)Chico
Example: Google Nexus 4 (API 21)Graze
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!Graze
The updated answer actually returns if the file does not contain a symlink. It should be: return !file.getCanonicalFile().equals(file.getAbsoluteFile()); (note the !)Pressroom
@isabsent, Same scenario as yours. I am getting containsSymlink as false for both the file paths.Crabstick

© 2022 - 2024 — McMap. All rights reserved.