Android - 在应用中创建符号链接

时间:2016-01-05 09:32:10

标签: java android android-ndk filesystems symlink

我想在我的应用中以编程方式创建符号链接。是否有可能在Android(4.4 +)?

在Java中我们可以使用:

SELECT 
  RowCount1,
  RowCount2,
  CASE WHEN RowCount1 <> RowCount2 
  THEN 'Data is not Identical'
  ELSE 'Date is identical'
  END AS RowCountResult
FROM
(
  SELECT 
  (select Count(*) From mslccard08.[carekey].dbo.EXTERNAL_MEMBER_DATA)
  +
  (select Count(*) from [vmslcsql11].[HSRTest].dbo.External_Member_data)
  As RowCount1,
  (
  Select count(*) From [mslccard08].[carekey].dbo.EXTERNAL_MEMBER_DATA
  )
  As RowCount2
) As SubTable

来自Path newLink = ...; Path target = ...; try { Files.createSymbolicLink(newLink, target); } catch (IOException x) { System.err.println(x); } catch (UnsupportedOperationException x) { // Some file systems do not support symbolic links. System.err.println(x); } ,但我应该在Android中使用什么?

https://docs.oracle.com/javase/tutorial/essential/io/links.html

编辑:

我使用java.nio.file进行了测试,但没有任何效果。我总是得到不允许操作(EPERM)。我认为你必须拥有创建符号链接的root权限。

问题可能在于reflection/native code/OS.symlink() method是一个包裹/mnt/sdcard的FUSE垫片。所以我开始使用/data/media/xxx,但我总是得到/data/media/xxx

我认为这是root权限的问题。

2 个答案:

答案 0 :(得分:0)

这是对我有用的解决方案,如果成功,则返回true:

public static boolean createSymLink(String symLinkFilePath, String originalFilePath) {
    try {
        if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
            Os.symlink(originalFilePath, symLinkFilePath);
            return true;
        }
        final Class<?> libcore = Class.forName("libcore.io.Libcore");
        final java.lang.reflect.Field fOs = libcore.getDeclaredField("os");
        fOs.setAccessible(true);
        final Object os = fOs.get(null);
        final java.lang.reflect.Method method = os.getClass().getMethod("symlink", String.class, String.class);
        method.invoke(os, originalFilePath, symLinkFilePath);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

或者在科特林:

companion object {
    @JvmStatic
    fun createSymLink(symLinkFilePath: String, originalFilePath: String): Boolean {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                Os.symlink(originalFilePath, symLinkFilePath)
                return true
            }
            val libcore = Class.forName("libcore.io.Libcore")
            val fOs = libcore.getDeclaredField("os")
            fOs.isAccessible = true
            val os = fOs.get(null)
            val method = os.javaClass.getMethod("symlink", String::class.java, String::class.java)
            method.invoke(os, originalFilePath, symLinkFilePath)
            return true
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return false
    }
}

答案 1 :(得分:0)