java、android 对比两个目录或文件是否是同一个目录或文件的方法
由于软链接及android的外部卡mount方式存在,导致一个文件夹可能同时有两个路径,如: /mnt/sdcard1 /storage/ext_sdcard ,如果通过某种方式(如mount命令)得到了这两个路径,但是现在要给路径去重,可以采用如下方法:
一、首先,要判断目录是否是同一个目录,可能会用到判断一个文件是否是同一个文件的方法,如果已经得到文件的路径 filePath1 和 filePath2,则可以这样来对比是否是同一个物理文件:
1、先检查这两个文件是否是符号链接,若是符号链接,通过采用File.getCanonicalPath() 的方法得到文件的正规路径(Canonical是规范的、正规的、正则的意思):
检查文件是否是符号链接:
// 自己补上: 先检查文件是否存在,不存在则直接返回 false
public static boolean isSymlink(File file) throws IOException {
if (file == null)
throw new NullPointerException("File must not be null");
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());
}
如果是符号链接,采用File.getCanonicalPath()的方法得到文件的规范路径:
// 自己加上:先检查文件是否存在,不存在则直接返回 file.getAbsolutePath() 或者 a.getPath()
if (isSymlink(file)) {
return file.getCanonicalFile();
}
关于canonical pathname的解释:
A canonical pathname is both absolute and unique. The precise definition of canonical form is system-dependent. This method first converts this pathname to absolute form if necessary, as if by invoking the getAbsolutePath() method, and then maps it to its unique form in a system-dependent way. This typically involves removing redundant names such as "." and ".." from the pathname, resolving symbolic links (on UNIX platforms), and converting drive letters to a standard case (on Microsoft Windows platforms).
2、得到文件的canonical path之后,对比文件的inode是否相等:
Runtime.getRuntime().exec("ls -i" + " " + file_canonical_path);
然后得到输出后先trim,再split(" "),再判断获得的第一个元素是否全是数字,如果全是数字则是其inode。
二、判断两个目录(A和B)是否是同一个目录:
1、先通过查找某个文件夹目录(如A)里的第一个文件,找到其相对路径:
public void listFilesForFolder(final File folder) {
if (!folder.exists()) return;
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
System.out.println(fileEntry.getName());
}
}
}
上面的程序可以找到某文件夹里的所有文件,自己取某些文件即可。
得到该文件夹(A)的某些文件之后,通过获得这些文件的 AbsolutePath 字符串,然后再从 这些 AbsolutePath 字符串里去掉 文件夹A的 AbsolutePath 字符串,就得到了这些文件的相对路径。注意,建议别用网上找到的方法来获取相对路径(因为有些时候 toURI() 会改变文件的路径,由于某些符号映射机制,如我的 android手机(华为荣耀7) 里的 /storage/sdcard1 就被映射成了 /storage/0123-4567,所有/storage/sdcard1目录下的文件,调用 toURI()之后都被改变了根目录为 /storage/0123-4567 ):
ring path = "/var/data/stuff/xyz.dat";
String base = "/var/data";
String relative = new File(base).toURI().relativize(new File(path).toURI()).getPath(); # 不要用这种方法获取相对路径
除了上面得到相对路径的方法外,还有一种更好的方法得到第一个文件的相对路径,建议用下面这种方法得到相对路径:
public void listFilesForFolder(final File folder) {
if (!folder.exists()) return;
String relativePath = "";
String fileName = "";
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
relativePath += fileEntry.getName() + "/";
listFilesForFolder(fileEntry);
} else {
fileNmae = fileEntry.getName();
System.out.println(fileEntry.getName());
break;
}
}
}
2、得到文件夹A里某些文件的相对路径之后,在B文件夹里创建这些文件,即new File(B, fileRelativePath), 将这些文件与文件夹A的相应的文件进行对比,看看他们的inode是否相同。相同则表明A和B是同一个文件夹,如果不同,则不是同一个文件夹。方法如下:
假如从文件夹A得到里一个文件 dir/file1.txt,通过字串方式去掉前面A的路径,自然语言描述如下:
File file1A = new File("A", "dir/file1.txt");
File file1B = new File("B", file1RelativePath);
if (!file1B.exists()) 则A和B不是同一个目录;
if (file1B的inode等于file1A的inode)则是同一个目录,否则不是。获取inode的时候不用将符号链接变成Canonical Path,即不推荐将两个文件都调用 getCanonicalFile(),因为如果A和B是同一个文件夹,则它里面的文件(哪怕是符号链接文件)也应该是同一个文件。
java、android 对比两个目录或文件是否是同一个目录或文件的方法的更多相关文章
- c语言头文件和源文件不在同一个目录
http://www.cnblogs.com/ShaneZhang/archive/2013/05/20/3088688.html 从工程上讲,头文件的文件名应该与对应的源文件名相同便于维护,如果头文 ...
- java操作对比两个字符串,将差异数据提取出来
记录瞬间 在实际的工作中,需要解决生成两次字符串结果进行对比的问题,将存在差异的字符串直接给出来. 当然,前提是需要将对比的两次结果,进行前期处理 比如: a_str = "@com/ene ...
- Java中对比两个对象中属性值[反射、注解]
在Java中通常要比较两个对象在修改前与修改后的值是否相同,一般我们采用的是反射技术获取对象的get方法[或其他的方法]获取值并做比较.如果系统将修改的属性名称也显示出来,这样就能更直观的显示类中的哪 ...
- 如何对比两个Jar包
如果对比两个jar包呢?jar 都是class 文件,我对比jar,就是想知道,它增加了删除了哪些方法.增加了哪些类,删除了哪些类. 有很多方法,你可以,反编译,然后通过beyongCompair 去 ...
- shell对比两个目录中有哪些文件不同
参考:https://www.cnblogs.com/liyuchuan/p/10756066.html 目录结构: /data/dir1 subdir/ subfile /data/dir2 sub ...
- gen目录无法更新,或者gen目录下的R.JAVA文件无法生成
gen目录无法更新,或者gen目录下的R.JAVA文件无法生成 1.gen目录的用处 android gen目录下的R.java并不是由用户创建,而是android工程本身将android的资源进行自 ...
- IO复制多级目录 控制台输入文件目录然后把目录下java文件复制到 D: 并统计java个数
package cn.itcast_05; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; impor ...
- [转载]java在线比较两个word文件
一.项目背景 开发文档管理系统或OA办公系统的时候,实现在线处理word文档的功能比较容易,但是也经常会有客户提出文档版本管理的需求,这就需要同时在线打开两个word文件,对比两个不同版本的word文 ...
- java基础IO流 复制键盘录入的目录,复制其中的.java文件到指定目录,指定目录中有重名,则改名 对加密文件计算字母个数
package com.swift.jinji; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; im ...
随机推荐
- jboss jndi配置部分参数详解
使用的是jboss7.1.1, jndi的配置在$JBOSS_HOME/standalone/configuration/standalone.xml中进行配置.配置jndi时有很多参数,解释下用到的 ...
- SASS -- 基本认识
SASS 是一种 CSS 的开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得 CSS 的开发,变得简单和可维护. SASS 提供四个编译风格的选项: * nested:嵌套缩进的 css ...
- Enable test automation in Testlink
Enabling Test Automation in Testlink Step 1: Change config settings in testlink config file Edit c ...
- Asp.net Web Api进行Nunit测试
有两种方式 1.模拟Web请求. 2.直接本地调用Api接口 但是由于本地直接调用没有模拟请求环境,所以request为null public static HttpResponseMessage C ...
- HDU 1160 FatMouse's Speed
半个下午,总算A过去了 毕竟水题 好歹是自己独立思考,debug,然后2A过的 我为人人的dp算法 题意: 为了支持你的观点,你需要从给的数据中找出尽量多的数据,说明老鼠越重速度越慢这一论点 本着“指 ...
- HTML xmlns
xmlns 属性可以在文档中定义一个或多个可供选择的命名空间.该属性可以放置在文档内任何元素的开始标签中.该属性的值类似于 URL,它定义了一个命名空间,浏览器会将此命名空间用于该属性所在元素内的所有 ...
- AngularJS分页实现
基本思路 一开始页码为1,Service向服务器端获取对应信息:点击上/下一页/跳转,通过对应的页码向服务器端获取对应的信息. 由于后台暂时没弄好,我实现的过程中直接读取准备好的JSON文件,通过页码 ...
- toB的产品经理和toc产品经理区别
腾讯产品经理现身说法 曾经在UC做过2年to c的app,现在在腾讯做to b的产品. 做to c产品的时候,我很瞧不起做to b产品的同学,认为他们不过是做支撑的. 后来,我参与了一个to b平台级 ...
- 20160129.CCPP体系详解(0008天)
程序片段(01):函数.c+call.c+测试.cpp 内容概要:函数 ///函数.c #include <stdio.h> #include <stdlib.h> //01. ...
- HDU1495 非常可乐
解题思路:简单的宽搜,见代码: #include<cstdio> #include<cstring> #include<algorithm> #include< ...