import java.io.File; public class TestFile { public static void main(String[] args) { String filename = "hello.txt"; // 创建File对象 File file = new File(filename); // 得到文件名 String name = file.getName(); System.out.println("name=" + name); // 得到目录 String dir = file.getParent(); System.out.println("dir=" + dir); } }?
[root@jfht params]# javac TestFile.java && java TestFile
name=hello.txt
dir=null
问题来了,第二行打印null,无法得到文件所在目录。
?
import java.io.File; import java.io.IOException; public class TestFile { public static void main(String[] args) throws IOException { String filename = "hello.txt"; // 创建File对象 File file = new File(filename); // 得到路径 String path = file.getPath(); System.out.println("path=" + path); // 得到文件名 String name = file.getName(); System.out.println("name=" + name); // 得到目录 String dir = file.getParent(); System.out.println("dir=" + dir); // 得到绝对路径 String apath = file.getAbsolutePath(); System.out.println("apath=" + apath); // 得到规范路径 String cpath = file.getCanonicalPath(); System.out.println("cpath=" + cpath); // 得到绝对文件对象 File file2 = file.getAbsoluteFile(); String dir2 = file2.getParent(); System.out.println("dir2=" + dir2); // 得到规范文件对象 File file3 = file.getCanonicalFile(); String dir3 = file3.getParent(); System.out.println("dir3=" + dir3); } }
?
[root@jfht params]# javac TestFile.java && java TestFile
path=hello.txt
name=hello.txt
dir=null
apath=/opt/shtools/params/hello.txt
cpath=/opt/shtools/params/hello.txt
dir2=/opt/shtools/params
dir3=/opt/shtools/params
[root@jfht params]#
?
如果把filename改成 "./hello.txt",执行结果如下:
[root@jfht params]# javac TestFile.java && java TestFile
path=./hello.txt
name=hello.txt
dir=.
apath=/opt/shtools/params/./hello.txt
cpath=/opt/shtools/params/hello.txt
dir2=/opt/shtools/params/.
dir3=/opt/shtools/params
[root@jfht params]#
?
如果把filename改成 "../hello.txt",执行结果如下:
[root@jfht params]# javac TestFile.java && java TestFile
path=../hello.txt
name=hello.txt
dir=..
apath=/opt/shtools/params/../hello.txt
cpath=/opt/shtools/hello.txt
dir2=/opt/shtools/params/..
dir3=/opt/shtools
[root@jfht params]#
?
现在,总结一下:
得到文件所在目录的有效方法是:
file.getCanonicalFile().getParent();
?
javadoc File.getCanonicalPath() & File.getCanonicalFile() 写道 getCanonicalPath在bash中,位置参数$0就是调用脚本时的文件名。
?
Bash脚本 dollar0.sh
#!/bin/sh echo "$0" # END.?
[root@jfht params]# ./dollar0.sh
./dollar0.sh
[root@jfht params]# $(pwd)/dollar0.sh
/opt/shtools/params/dollar0.sh
[root@jfht params]# ../params/dollar0.sh
../params/dollar0.sh
[root@jfht params]# sh dollar0.sh
dollar0.sh
[root@jfht params]# PATH=.:$PATH dollar0.sh
./dollar0.sh
[root@jfht params]# PATH=$(pwd):$PATH dollar0.sh?
/opt/shtools/params/dollar0.sh
[root@jfht params]#
?
注意:网上有文章如下所说,显然是不太正确的。
http://songzhangzhang.blog.163.com/blog/static/6940198120116201641361/ 写道 在bash脚本中$0是该脚本文件的全路径文件名,不管脚本的调用方式是直接指定具体文件路径还是把脚本文件所在目录放在PATH环境变量中。 ?dirname命令可以得到指定文件的目录部分。
info dirname 写道 18.2 `dirname': Strip non-directory suffix from a file name?
对前面的脚本进行修改,增加对执行脚本文件所在目录的打印输出。
#!/bin/sh echo "$0" echo "$(dirname "$0")" # END.
?
[root@jfht params]# ./dollar0.sh
./dollar0.sh
.
[root@jfht params]# $(pwd)/dollar0.sh
/opt/shtools/params/dollar0.sh
/opt/shtools/params
[root@jfht params]# ../params/dollar0.sh
../params/dollar0.sh
../params
[root@jfht params]# sh dollar0.sh
dollar0.sh
.
[root@jfht params]# PATH=.:$PATH dollar0.sh
./dollar0.sh
.
[root@jfht params]# PATH=$(pwd):$PATH dollar0.sh?
/opt/shtools/params/dollar0.sh
/opt/shtools/params
[root@jfht params]#
?
从上面的例子看出,dirname不一定得到全路径目录,随着调用方式的不同会有不同的结果。
?
对前面的dollar0脚本进行改进,增加realdir函数,用于打印指定目录的全路径。
#!/bin/sh echo "$0" echo "$(dirname "$0")" fulldir() { (cd "$1" && pwd) } echo "$(fulldir "$(dirname "$0")")" # END.?
[root@jfht params]# ./dollar0.sh
./dollar0.sh
.
/opt/shtools/params
[root@jfht params]# $(pwd)/dollar0.sh?
/opt/shtools/params/dollar0.sh
/opt/shtools/params
/opt/shtools/params
[root@jfht params]# ../params/dollar0.sh??????
../params/dollar0.sh
../params
/opt/shtools/params
[root@jfht params]# sh dollar0.sh??????????
dollar0.sh
.
/opt/shtools/params
[root@jfht params]# PATH=.:$PATH dollar0.sh
./dollar0.sh
.
/opt/shtools/params
[root@jfht params]# PATH=$(pwd):$PATH dollar0.sh?
/opt/shtools/params/dollar0.sh
/opt/shtools/params
/opt/shtools/params
[root@jfht params]#
?
basename命令可以得到指定文件的文件名称部分。
info basename 写道 18.1 `basename': Strip directory and suffix from a file name?
继续对上面的脚本进行改进,增加fullname函数来得到指定文件的全路径。
#!/bin/sh echo "$0" echo "$(dirname "$0")" # usage: fulldir <dir> fulldir() { (cd "$1" && pwd) } echo "$(fulldir "$(dirname "$0")")" # usage: fullname <dirname_ro_filename> fullname() { local dir=$(dirname "$0") local name=$(basename "$0") echo "$(cd "$dir" && pwd)/$name" } echo "$(fullname "$0")" # END.
?
[root@jfht params]# ./dollar0.sh?
./dollar0.sh
.
/opt/shtools/params
/opt/shtools/params/dollar0.sh
[root@jfht params]# $(pwd)/dollar0.sh
/opt/shtools/params/dollar0.sh
/opt/shtools/params
/opt/shtools/params
/opt/shtools/params/dollar0.sh
[root@jfht params]# ../params/dollar0.sh
../params/dollar0.sh
../params
/opt/shtools/params
/opt/shtools/params/dollar0.sh
[root@jfht params]# sh dollar0.sh
dollar0.sh
.
/opt/shtools/params
/opt/shtools/params/dollar0.sh
[root@jfht params]# PATH=.:$PATH dollar0.sh
./dollar0.sh
.
/opt/shtools/params
/opt/shtools/params/dollar0.sh
[root@jfht params]# PATH=$(pwd):$PATH dollar0.sh ?
/opt/shtools/params/dollar0.sh
/opt/shtools/params
/opt/shtools/params
/opt/shtools/params/dollar0.sh
[root@jfht params]#
?
在bash中,pwd命令与echo $PWD得到的结果是一样的,因此上面的脚本也可以如下编写。
#!/bin/sh echo "$0" echo "$(dirname "$0")" # usage: fulldir <dir> fulldir() { (cd "$1" && echo "$PWD") } echo "$(fulldir "$(dirname "$0")")" # usage: fullname <dirname_ro_filename> fullname() { local dir=$(dirname "$0") local name=$(basename "$0") echo "$(cd "$dir" && echo "$PWD")/$name" } echo "$(fullname "$0")" # END.?
?
本文链接:http://codingstandards.iteye.com/blog/1164909 ? (转载请注明出处)
返回目录:Java程序员的Bash实用指南系列之字符串处理(目录)?
上节内容:Bash字符串处理(与Java对照) - 23.字符串替换、子串删除、子串截取
下节内容:Bash字符串处理(与Java对照) - 25.字符串分割(成数组)
?