Java程序設計-個人月報-2023-08月
背景
在本月,給負責的項目做了一次文件存儲的遷移工作。
歷史原因,開發階段由於圖簡便,使用了本地文件存儲。
後面經過容器化上雲,導致應用出現上傳文件分發的多節點的問題。
本項工作的經驗,受益於Java基礎Path的一些API,頗有收穫。
複雜的系統應當構建於通用的,穩定的,有共識的,成熟API之上。 ----沃茲基索德
路徑計算
代碼中,不要使用路徑拼接的原始寫法,非常容易出錯。例如:
String path = '/bucket/' + projectId + '/v' + version + fileName;
甚至後面直接使用了subString,正則表達式。
這種寫法非常不好,當項目內多次使用路徑計算的時候,代碼複雜性增加。
java.nio.Path
Path path = Paths.get('parent','child');
Path toAbsolutePath()
Returns a Path object representing the absolute path of this path.
File toFile()
Returns a File object representing this path.
Path toRealPath(LinkOption... options)
Returns the real path of an existing file.
這些API非常簡單且實用,且不要在代碼中試圖使用 split("/")
,split(File.pathSeparator)
這類比較初級的寫法。
使用Name獲取Path中的分片
Path getName(int index)
Returns a name element of this path as a Path object.
int getNameCount()
Returns the number of name elements in the path.
上一級或者下一級
Path getParent()
Returns the parent path, or null if this path does not have a parent.
Path resolve(Path other)
Resolve the given path against this path.
Path resolve(String other)
Converts a given path string to a Path and resolves it against this Path in exactly the manner specified by the resolve method.
其中 resolve 非常實用:
不用擔心,這些路徑可以不用存在於本地文件系統上
//你的代碼:
path = "a" + "/b";
path = "a/" + "b";
//無法跨平臺,且埋下BUG的可能性。
//Path API的代碼:
Paths.get("a").resolve("b"); //在Windows上,得出 a\b,在Linux,MacOS上得到 a/b。
從整個路徑中獲取文件名和後綴
Path getFileName()
Returns the name of the file or directory denoted by this path as a Path object.
//你的old class代碼:
String path= "foo/bar/some.pdf";
path.subString(path, path.lastIndexOf("/"));
//搞不好還整出來一個"/some.pdf",需要試試。
//Path API的代碼
Paths.get(path).getFileName(); //some.pdf
URI
URI的組成部分是 Schema:// + 剩餘部分地址,在某些情況下,例如ClassPath的表示,就非常重要。
URI toUri()
Returns a URI to represent this path.
String path = "/root/foo/bar/slankka.md"
URI uri = Paths.get(path).toUri(); //得到 file:///root/foo/bar/slankka.md
//未經驗證,但意思對就行。
理解了上述 java API,org.apache.hadoop.fs.Path 同理。這樣在編寫大數據相關的Path就不容易出錯。
一些例子
file:///root/foo/bar/slankka.md
hdfs://dc1/user/hdfs/foo/bar/slankka.md
viewfs://cluster123/foo/bar/slankka.md