免费国产精品自在自线-91精品国产色综合久久久浪潮-99热久久免费频精品-国产精品国模在线观看-久久亚洲国产精品成人?V秋霞-久久国产一级A片免费播放-亚洲国产欧洲综合97久久-久久国产白嫩美女呻吟高潮

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

Java文件操作對(duì)比:從File到NIO.2,遷移指南與踩坑總結(jié)

Java文件操作對(duì)比:從File到NIO.2,遷移指南與踩坑總結(jié) 先說(shuō)明一下我寫這篇對(duì)比的起因。雖然 Java 7 就把 NIO.2也就是 java.nio.file 這套 API帶進(jìn)來(lái)了但你去翻很多生產(chǎn)項(xiàng)目的代碼java.io.File依然隨處可見。不是老項(xiàng)目不敢動(dòng)而是很多同學(xué)入行時(shí)學(xué)的就是File后面項(xiàng)目里new File()、file.exists()、file.delete()一路寫下來(lái)沒人提醒的話很難跳出這個(gè)慣性。這篇是 Java 文件操作對(duì)比系列的第 4 篇也是收尾篇。前面幾篇拆了 IO 流的讀寫細(xì)節(jié)、字符編碼處理和二進(jìn)制操作這篇就專門把java.io.File和java.nio.file兩大體系做一次全方位對(duì)照。重點(diǎn)不放在“哪個(gè) API 更高級(jí)”這種口號(hào)上而是直接落到實(shí)際開發(fā)里你每天都會(huì)碰到的場(chǎng)景文件刪不掉怎么辦、目錄怎么遞歸遍歷、移動(dòng)文件是否原子、符號(hào)鏈接怎么處理、文件監(jiān)聽怎么做。每一條都會(huì)給出可跑的示例和我會(huì)踩的坑。1. API 設(shè)計(jì)與使用體驗(yàn)對(duì)比為什么 File 用著別扭1.1 設(shè)計(jì)哲學(xué)一坨類 vs 一條路徑加一個(gè)工具類java.io.File最大的問(wèn)題在于它既是“路徑的表示”又是“文件操作的入口”。你new File(a.txt)并沒有真正觸達(dá)文件系統(tǒng)它只包裝了一個(gè)路徑字符串但同一個(gè)對(duì)象上你又可以調(diào)用exists()、delete()、mkdirs()這些方法去修改真實(shí)文件系統(tǒng)。路徑表示和狀態(tài)操作混在一起職責(zé)非常散。而java.nio.file把這兩件事拆開了。Path只負(fù)責(zé)“描述一個(gè)路徑”不帶任何文件系統(tǒng)操作真正的讀寫、復(fù)制、移動(dòng)、刪除、屬性查詢?nèi)渴諗康紽iles這個(gè)工具類里。也就是說(shuō)你拿到一個(gè)Path對(duì)象它只是一個(gè)不可變的位置標(biāo)記想對(duì)它做什么再通過(guò)Files靜態(tài)方法傳入這個(gè)Path。類名上也容易踩坑。java.io.File叫“文件”但它其實(shí)也能代表目錄Path叫“路徑”聽上去好像是給文件用的實(shí)際指向文件或目錄都行。理解這個(gè)職責(zé)分離之后寫代碼的思路會(huì)清晰很多先構(gòu)造路徑再?zèng)Q定操作而不是在一個(gè)對(duì)象上調(diào)來(lái)調(diào)去。1.2 失敗模型靜默 boolean 與顯式異常這是兩套 API 使用體驗(yàn)差異最大的地方也是從File遷到 NIO 后最先感覺“舒服”的點(diǎn)。java.io.File的寫操作基本都是返回boolean比如File file new File(/tmp/data/report.txt); boolean deleted file.delete(); if (!deleted) { // 到底為什么失敗權(quán)限不存在目錄非空完全不知道 }delete()返回false的原因可能是不存在、沒有權(quán)限、文件被占用但老 API 不會(huì)告訴你具體是哪一種。排查問(wèn)題全靠猜。mkdir()、renameTo()同理。java.nio.file的做法完全不同刪除操作要么成功要么拋出帶具體類型的異常Path path Paths.get(/tmp/data/report.txt); Files.delete(path); // 文件不存在 - NoSuchFileExceptionNoSuchFileException是IOException的子類你能從異常類一眼看出問(wèn)題文件不存在。權(quán)限問(wèn)題拋AccessDeniedException目錄非空刪除失敗會(huì)得到DirectoryNotEmptyException路徑格式不對(duì)拋InvalidPathException。這些異常類本身就攜帶了足夠多的排查信息。所以我的建議很直接新代碼一律用Files老代碼如果還在寫boolean ok file.delete()這種邏輯至少加個(gè)日志把它為什么失敗打印出來(lái)否則線上出問(wèn)題沒法定位。下面給一個(gè)簡(jiǎn)單的語(yǔ)義對(duì)照表操作java.io.Filejava.nio.file失敗表現(xiàn)刪除文件delete()Files.delete(path)返回 false / 拋異常刪除存在才刪delete()后判斷返回值Files.deleteIfExists(path)返回 boolean / 返回 false創(chuàng)建目錄mkdir()Files.createDirectory(path)返回 false / 拋異常創(chuàng)建多級(jí)目錄mkdirs()Files.createDirectories(path)返回 false / 拋異常判斷存在exists()Files.exists(path)返回 boolean / 返回 boolean1.3 資源釋放數(shù)組免操心流必須關(guān)File.listFiles()返回的是File[]數(shù)組拿到數(shù)組后不需要額外釋放什么資源。這看上去很省事但代價(jià)是“一次性全量加載”。如果目錄里有十萬(wàn)個(gè)文件數(shù)組會(huì)一次性把全部條目加載進(jìn)內(nèi)存。NIO 的Files.newDirectoryStream()返回一個(gè)DirectoryStreamPath可以邊遍歷邊處理但注意它是AutoCloseable的必須關(guān)閉否則會(huì)泄漏文件句柄。try (DirectoryStreamPath stream Files.newDirectoryStream(dir)) { for (Path entry : stream) { // 處理 entry } } // 自動(dòng) closeFiles.list()和Files.walk()返回的是StreamPath同樣需要關(guān)閉。很多人會(huì)忽略這一點(diǎn)因?yàn)镾tream平時(shí)用起來(lái)不像“資源”。事實(shí)上Files.list()底層就包了一個(gè)DirectoryStream如果不用try-with-resources包住流不關(guān)閉句柄就會(huì)一直占著。Windows 上尤其明顯文件被句柄占著后面想刪除或移動(dòng)都會(huì)失敗。2. 路徑處理File 的歷史包袱與 Path 的現(xiàn)代化2.1 分隔符別再自己拼字符串了舊的FileAPI 里最常見的路徑拼接寫法是這樣String path data File.separator 2025 File.separator report.txt;如果不小心用了File.separatorWindows 和 Linux 還能自適應(yīng)但很多人圖省事直接寫死/或者\(yùn)\。其實(shí)File內(nèi)部能處理兩種分隔符只是拼接出來(lái)的字符串在跨平臺(tái)場(chǎng)景容易被其他組件誤解。Path從根本上消滅了這類問(wèn)題。使用Paths.get()傳入多個(gè)片段NIO 會(huì)自動(dòng)用當(dāng)前文件系統(tǒng)的分隔符拼接Path path Paths.get(data, 2025, report.txt);在 Windows 上它會(huì)得到data\2025\report.txt在 Linux 上得到data/2025/report.txt。無(wú)論后面是直接交給Files操作還是傳給其他接口都不會(huì)出現(xiàn)分隔符不一致的問(wèn)題。實(shí)際開發(fā)里我?guī)缀醪辉偈謩?dòng)拼接路徑字符串全部用這種可變參數(shù)構(gòu)造方式。2.2 絕對(duì)路徑與規(guī)范路徑一個(gè)“不碰磁盤”一個(gè)“必須碰”File提供了兩個(gè)容易混淆的方法getAbsolutePath()和getCanonicalPath()。getAbsolutePath()純粹從字面上補(bǔ)全路徑不會(huì)解析..和.也不會(huì)訪問(wèn)文件系統(tǒng)。getCanonicalPath()會(huì)解析..、.、符號(hào)鏈接返回“規(guī)范路徑”。因?yàn)樗L問(wèn)文件系統(tǒng)所以方法簽名上直接聲明了throws IOException。Path對(duì)應(yīng)的是toAbsolutePath()和toRealPath()。其中toRealPath()等價(jià)于getCanonicalPath()的增強(qiáng)版默認(rèn)會(huì)解析符號(hào)鏈接也可以通過(guò)參數(shù)LinkOption.NOFOLLOW_LINKS不跟隨鏈接Path path Paths.get(/tmp/data/../data/report.txt); System.out.println(path.toAbsolutePath()); // /tmp/data/../data/report.txt帶著 .. System.out.println(path.normalize()); // /tmp/data/report.txt詞法規(guī)約不碰磁盤 System.out.println(path.toRealPath()); // 解析符號(hào)鏈接要求文件必須存在否則拋異常三者各有用途。配置文件加載時(shí)我通常用toRealPath()因?yàn)樗鼤?huì)順帶校驗(yàn)文件是否存在如果只是想規(guī)整一下路徑格式但文件還不一定存在就用normalize()。搞清楚這三者的區(qū)別比記住一堆 API 名字有用得多。2.3 路徑段操作subpath 這類高階能力 File 完全沒有File里跟路徑段有關(guān)的只有g(shù)etName()、getParent()、getPath()想取完整路徑中的某一段需要自己在字符串上切。Path提供了更結(jié)構(gòu)化的能力Path path Paths.get(/projects/order-service/src/main/java/OrderService.java); System.out.println(path.getNameCount()); // 7 System.out.println(path.getName(0)); // projects System.out.println(path.subpath(0, 4)); // projects/order-service/src/main System.out.println(path.getFileName()); // OrderService.java System.out.println(path.getRoot()); // /subpath(0, 4)這種“截取中段路徑”的能力在按目錄結(jié)構(gòu)掃描代碼、按約定解析模塊路徑時(shí)特別好用。老代碼要實(shí)現(xiàn)相同的邏輯基本只能split(/)然后自己拼數(shù)組還得分隔符在不同平臺(tái)的差異。路徑段的操作能力是 NIO 對(duì)舊 API 一次實(shí)打?qū)嵉慕稻S打擊。3. 文件元數(shù)據(jù)從多次 stat 到一次屬性視圖3.1 存在性與類型判斷老代碼里最常見的判斷邏輯是這樣File f new File(/tmp/conf/application.yml); if (f.exists() f.isFile()) { // 讀配置 }這段代碼在大多數(shù)場(chǎng)景沒問(wèn)題但如果/tmp/conf/application.yml是一個(gè)符號(hào)鏈接就得小心了。java.io.File的isDirectory()和isFile()默認(rèn)會(huì)跟隨符號(hào)鏈接——也就是說(shuō)如果符號(hào)鏈接指向的是一個(gè)目錄isFile()會(huì)返回falseisDirectory()會(huì)返回true但有時(shí)候你恰恰想知道“這個(gè)鏈接本身指向什么類型”。NIO 的Files系列方法提供了LinkOption參數(shù)Path path Paths.get(/tmp/conf/application.yml); // 判斷是否是目標(biāo)類型跟隨鏈接 boolean isFile Files.isRegularFile(path); // 判斷鏈接本身的屬性不跟隨鏈接 boolean isFileNoFollow Files.isRegularFile(path, LinkOption.NOFOLLOW_LINKS); // 直接判斷是不是符號(hào)鏈接 boolean isSymlink Files.isSymbolicLink(path);實(shí)際項(xiàng)目里處理配置文件路徑時(shí)我一般先用Files.isSymbolicLink()判斷一下再?zèng)Q定是否讀取鏈接目標(biāo)。如果只是簡(jiǎn)單判斷目錄是否存在用Files.isDirectory(path)就夠但涉及符號(hào)鏈接的部署場(chǎng)景不加上NOFOLLOW_LINKS很容易誤判。3.2 屬性視圖一次調(diào)用拿全套元數(shù)據(jù)File查詢文件大小和修改時(shí)間需要分別調(diào)用File f new File(/tmp/data.bin); long size f.length(); long lastModified f.lastModified(); boolean isDir f.isDirectory(); boolean isHidden f.isHidden();每次調(diào)用都可能觸發(fā)一次文件系統(tǒng)操作也就是一次 stat。雖然單次 stat 開銷不大但在批量處理成千上萬(wàn)個(gè)文件時(shí)反復(fù)查詢多個(gè)屬性會(huì)讓性能明顯變差而且代碼也啰嗦。NIO 的Files.readAttributes()可以一次讀取整套屬性BasicFileAttributes attrs Files.readAttributes(path, BasicFileAttributes.class); long size attrs.size(); long lastModified attrs.lastModifiedTime().toMillis(); long creationTime attrs.creationTime().toMillis(); boolean isDirectory attrs.isDirectory(); boolean isRegularFile attrs.isRegularFile(); boolean isSymbolicLink attrs.isSymbolicLink();一次系統(tǒng)調(diào)用拿到全部信息。需要區(qū)分文件類型時(shí)attrs.isRegularFile()和attrs.isDirectory()已經(jīng)幫你分好了不用像File那樣先exists()再isFile()做兩次判斷。如果需要更精細(xì)的屬性還可以換用視圖類視圖類適用平臺(tái)擴(kuò)展屬性BasicFileAttributes所有大小、時(shí)間、文件類型DosFileAttributesWindows隱藏、只讀、歸檔、系統(tǒng)文件PosixFileAttributesLinux/macOS權(quán)限、屬主、屬組PosixFileAttributes posix Files.readAttributes(path, PosixFileAttributes.class); SetPosixFilePermission perms posix.permissions();這套屬性視圖機(jī)制在File時(shí)代是完全缺失的。拿File查 Linux 文件的讀、寫、執(zhí)行權(quán)限只能通過(guò)canRead()、canWrite()、canExecute()三個(gè)方法分別判斷拿不到具體的權(quán)限組合更拿不到屬主屬組。3.3 修改屬性從粒度過(guò)粗到精細(xì)可控File提供的修改能力很有限翻來(lái)覆去就那幾個(gè)file.setReadOnly(); // 只讀 file.setWritable(true, false); // 當(dāng)前用戶可寫ownerOnlyfalse file.setExecutable(true); // 當(dāng)前用戶可執(zhí)行 file.setLastModified(timestamp); // 修改時(shí)間粒度非常粗。想要“給所有用戶加執(zhí)行權(quán)限”這種操作File根本做不了只能借助外部命令。NIO 則可以通過(guò) PosixFilePermissions 精確控制權(quán)限位SetPosixFilePermission perms PosixFilePermissions.fromString(rwxr-x---); Files.setPosixFilePermissions(path, perms);fromString(rwxr-x---)這種寫法非常直觀一眼就能看出屬主是rwx、屬組是r-x、其他用戶是---。生產(chǎn)環(huán)境里我經(jīng)常用來(lái)給腳本文件加執(zhí)行權(quán)限部署完直接一條命令生效。這個(gè)能力在File時(shí)代只能靠Runtime.exec(chmod 750 xxx)繞過(guò)去麻煩還容易踩轉(zhuǎn)義坑。4. 目錄遍歷與遞歸刪除三種寫法的演進(jìn)4.1 遍歷一個(gè)目錄null 的坑和必須關(guān)閉的流File.listFiles()最大的坑是返回值。如果目錄里面沒有條目它返回空數(shù)組但如果發(fā)生了 IO 錯(cuò)誤比如目錄不存在、權(quán)限不足它返回null。如果代碼拿到null不去判空直接for遍歷瞬間NullPointerException。File[] files dir.listFiles(); if (files ! null) { // 必須判空否則可能 NPE for (File f : files) { // ... } }NIO 的Files.newDirectoryStream()遇到目錄不存在時(shí)直接拋NoSuchFileException不會(huì)返回null也沒有必要判空。更輕量的是Files.list()返回StreamPath配合現(xiàn)代 Java 的函數(shù)式風(fēng)格非常自然try (StreamPath stream Files.list(Paths.get(/tmp/data))) { stream.filter(Files::isRegularFile) .filter(p - p.toString().endsWith(.log)) .forEach(System.out::println); }這三個(gè)方法的取舍我實(shí)際使用下來(lái)是只是列目錄、無(wú)需過(guò)濾和自定義屬性查詢用Files.list()需要過(guò)濾條件比較復(fù)雜的比如只挑大于某個(gè)大小的文件用Files.newDirectoryStream()配合自定義過(guò)濾器更清晰如果目錄很大優(yōu)先newDirectoryStream()邊讀邊處理避免一次性加載全部條目到內(nèi)存。4.2 深度遍歷walk 與 walkFileTree 怎么選按目錄樹遞歸遍歷是文件操作里最高頻的需求之一。File時(shí)代只能手寫遞歸大概長(zhǎng)這樣void listAll(File dir) { File[] files dir.listFiles(); if (files null) return; for (File f : files) { if (f.isDirectory()) { listAll(f); } else { System.out.println(f.getPath()); } } }NIO 提供了兩種現(xiàn)成的深度遍歷方案。第一種Files.walk()惰性遍歷并返回StreamPath適合過(guò)濾、收集類的場(chǎng)景try (StreamPath stream Files.walk(Paths.get(/tmp/data))) { stream.filter(Files::isRegularFile) .forEach(System.out::println); }第二種Files.walkFileTree()基于訪問(wèn)者模式需要寫一個(gè)SimpleFileVisitor。它最大的優(yōu)勢(shì)是能夠在“進(jìn)入目錄前”“離開目錄后”“訪問(wèn)文件時(shí)”“訪問(wèn)失敗時(shí)”四個(gè)時(shí)機(jī)分別插入邏輯刪除目錄樹時(shí)尤其好用。Files.walkFileTree(Paths.get(/tmp/data), new SimpleFileVisitorPath() { Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); return FileVisitResult.CONTINUE; } Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { Files.delete(dir); return FileVisitResult.CONTINUE; } });FileVisitResult除了CONTINUE還有SKIP_SUBTREE跳過(guò)當(dāng)前目錄、TERMINATE終止遍歷。比如備份時(shí)需要跳過(guò).git目錄在preVisitDirectory里判斷目錄名直接返回SKIP_SUBTREE即可這種控制力是Stream方案給不了的。4.3 遞歸刪除的三種推薦寫法刪除一個(gè)非空目錄File.delete()直接失敗因?yàn)槟夸浄强?。File時(shí)代最原始的遞歸刪除長(zhǎng)這樣void deleteRecursively(File f) { if (f.isDirectory()) { File[] children f.listFiles(); if (children ! null) { for (File child : children) { deleteRecursively(child); } } } f.delete(); }NIO 時(shí)代常見三種寫法。前面提到的walkFileTree是最穩(wěn)的。第二種是利用Files.walk()配合反序刪除——因?yàn)镕iles.walk()默認(rèn)深度優(yōu)先先列出的路徑在樹的上層刪除前需要把流排序成“子路徑在前、父路徑在后”try (StreamPath stream Files.walk(Paths.get(/tmp/data))) { stream.sorted(Comparator.reverseOrder()) .forEach(p - { try { Files.deleteIfExists(p); } catch (IOException e) { throw new UncheckedIOException(e); } }); }第三種是用遞歸加Files.deleteIfExists()簡(jiǎn)潔但對(duì)深層目錄會(huì)造成較深的調(diào)用棧void deleteRecursive(Path dir) throws IOException { try (StreamPath stream Files.list(dir)) { for (Path p : stream) { if (Files.isDirectory(p, LinkOption.NOFOLLOW_LINKS)) { deleteRecursive(p); } else { Files.deleteIfExists(p); } } } Files.delete(dir); }我個(gè)人的選擇是老代碼重構(gòu)時(shí)用walkFileTree因?yàn)檎Z(yǔ)義清晰、可控性高寫一次性腳本或臨時(shí)清理邏輯時(shí)用sorted(reverseOrder())那一行流式寫法簡(jiǎn)潔。搜索“java 文件相關(guān)的操作”這個(gè)主題時(shí)遞歸刪除永遠(yuǎn)是最熱門的場(chǎng)景之一所以這里特意把三種姿勢(shì)都列出看你們項(xiàng)目風(fēng)格自取。5. 復(fù)制、移動(dòng)與刪除原子性是最容易被忽略的點(diǎn)5.1 刪除語(yǔ)義的差異File.delete()和Files.delete()的差別前面已經(jīng)提到這里再補(bǔ)一個(gè)實(shí)操場(chǎng)景清理日志文件時(shí)我們經(jīng)常遇到“目標(biāo)可能不存在”的情況。// 舊寫法 File logFile new File(/tmp/app.log); if (logFile.exists()) { // 有些人會(huì)先 exists 再 delete logFile.delete(); } // NIO 寫法 Files.deleteIfExists(Paths.get(/tmp/app.log));Files.deleteIfExists()把“存在才刪”這個(gè)語(yǔ)義封裝好了不用再手動(dòng)判存在也省掉了“exists 判斷后文件被并發(fā)刪除導(dǎo)致 delete 返回 false”的競(jìng)態(tài)問(wèn)題。需要注意deleteIfExists()在目錄非空時(shí)依然會(huì)拋DirectoryNotEmptyException所以刪除目錄還是要走遞歸方案。5.2 復(fù)制文件保留屬性是個(gè)細(xì)節(jié)活java.io.File沒有自己的復(fù)制能力老代碼通常用兩個(gè)流手動(dòng)搬運(yùn)try (InputStream in new FileInputStream(src); OutputStream out new FileOutputStream(dst)) { byte[] buffer new byte[8192]; int len; while ((len in.read(buffer)) ! -1) { out.write(buffer, 0, len); } }能復(fù)制內(nèi)容但源文件的修改時(shí)間、權(quán)限這些元數(shù)據(jù)全部丟失。而Files.copy()可以通過(guò)CopyOption控制復(fù)制行為Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);REPLACE_EXISTING表示目標(biāo)存在時(shí)覆蓋COPY_ATTRIBUTES表示盡量保留源文件的屬性修改時(shí)間等。如果不加COPY_ATTRIBUTES復(fù)制出來(lái)的文件時(shí)間戳就是“當(dāng)前時(shí)間”在發(fā)布構(gòu)建產(chǎn)物的場(chǎng)景里會(huì)造成緩存判斷錯(cuò)誤。這里有個(gè)細(xì)節(jié)Files.copy()底層在不同文件系統(tǒng)上的實(shí)現(xiàn)有差異如果源和目標(biāo)在同一個(gè)文件系統(tǒng)里某些平臺(tái)會(huì)走更高效的路徑但你不必關(guān)心這些差異API 層面一致即可。另外Files.copy()復(fù)制目錄時(shí)是淺復(fù)制只復(fù)制目錄本身不會(huì)遞歸復(fù)制子目錄和文件。需要完整復(fù)制目錄樹還得配合walkFileTree逐個(gè)創(chuàng)建和復(fù)制。5.3 移動(dòng)文件renameTo 靠不住ATOMIC_MOVE 有講究File.renameTo()是舊 API 里我踩過(guò)最多坑的方法。它的行為高度依賴平臺(tái)和文件系統(tǒng)在 Windows 上如果目標(biāo)文件已經(jīng)存在renameTo()很可能失敗如果跨文件系統(tǒng)比如從 C 盤挪到 D 盤renameTo()大概率直接返回 false如果目標(biāo)文件的父目錄不存在也會(huì)失敗。最難受的是它失敗返回false你完全不知道是哪種原因。Files.move()則干凈得多Files.move(src, dst, StandardCopyOption.REPLACE_EXISTING);這在同一個(gè)文件系統(tǒng)內(nèi)基本是原子的。如果需要把原子性作為硬性要求可以加上AtomicMoveNotSupportedException兜底try { Files.move(src, dst, StandardCopyOption.REPLACE_EXISTING, AtomicMoveOption.ATOMIC_MOVE); } catch (AtomicMoveNotSupportedException e) { // 文件系統(tǒng)不支持原子移動(dòng)降級(jí)為普通 move Files.move(src, dst, StandardCopyOption.REPLACE_EXISTING); }ATOMIC_MOVE保證移動(dòng)操作要么完成、要么完全沒發(fā)生。文件替換、日志輪轉(zhuǎn)這類場(chǎng)景特別看重這個(gè)語(yǔ)義——如果你在進(jìn)程正在寫文件時(shí)做替換非原子移動(dòng)可能出現(xiàn)目標(biāo)文件短暫不存在或內(nèi)容不完整的情況。這一點(diǎn)在生產(chǎn)環(huán)境里尤其重要比如部署新版本 jar 包如果不用原子替換的方式服務(wù)重啟瞬間可能讀到半截文件。5.4 臨時(shí)文件與退出清理File.createTempFile()和File.deleteOnExit()是老代碼里常見的組合File temp File.createTempFile(data, .tmp); temp.deleteOnExit();deleteOnExit()會(huì)在 JVM 退出時(shí)刪除文件邏輯本身還好但有幾個(gè)坑它只刪除注冊(cè)的這個(gè)文件不清理目錄而且如果文件已經(jīng)被刪除它不會(huì)報(bào)錯(cuò)。更麻煩的是如果 JVM 被kill -9強(qiáng)殺deleteOnExit()根本不會(huì)執(zhí)行臨時(shí)文件會(huì)殘留。NIO 的createTempFile()只負(fù)責(zé)創(chuàng)建沒有自帶退出清理Path temp Files.createTempFile(null, .tmp);清理需要自己做。如果是邊寫邊用的臨時(shí)文件最簡(jiǎn)單的是用完立刻刪try { Files.write(temp, data); // 使用 temp } finally { Files.deleteIfExists(temp); }如果臨時(shí)文件要跨越多個(gè)方法使用直到 JVM 退出可以注冊(cè)ShutdownHook做兜底。deleteOnExit()本身也是 JVM 內(nèi)部維護(hù)了一個(gè)待刪隊(duì)列所以存在一個(gè)隱藏問(wèn)題如果短時(shí)間創(chuàng)建大量臨時(shí)文件都會(huì)進(jìn)入隊(duì)列等待 JVM 退出時(shí)逐個(gè)清理如果程序崩得早列隊(duì)里的文件就全留下變成垃圾。實(shí)際項(xiàng)目里我傾向于盡快刪除臨時(shí)文件而不是依賴退出鉤子。6. 符號(hào)鏈接與文件監(jiān)聽NIO 獨(dú)有的兩個(gè)高價(jià)值能力6.1 符號(hào)鏈接判斷與讀取目標(biāo)java.io.File完全沒有符號(hào)鏈接的概念遇到符號(hào)鏈接會(huì)直接當(dāng)普通文件處理。NIO 在這塊補(bǔ)齊了關(guān)鍵能力。Path link Paths.get(/usr/bin/java); System.out.println(Files.isSymbolicLink(link)); // true Path target Files.readSymbolicLink(link); System.out.println(target); // 實(shí)際指向的路徑注意readSymbolicLink()讀取的是鏈接自己保存的目標(biāo)路徑不會(huì)遞歸解析最終目標(biāo)。如果你需要不斷解析直到找到真實(shí)文件可以結(jié)合toRealPath()Path realPath link.toRealPath(); // 默認(rèn)跟隨所有符號(hào)鏈接返回最終真實(shí)路徑在包含軟鏈的部署環(huán)境比如/usr/bin/java普遍是軟鏈下判斷 JDK 版本時(shí)用link.toRealPath()能拿到真正安裝的 JDK 路徑比File.getCanonicalPath()穩(wěn)定得多。6.2 WatchService監(jiān)控目錄變化替代無(wú)頭輪詢java.io.File沒有文件監(jiān)聽能力。老代碼想實(shí)現(xiàn)“目錄里多了新文件就處理”一般只能靠輪詢lastModified或者listFiles()比對(duì)前后差異又慢又容易漏。NIO 的WatchService是原生的目錄監(jiān)聽機(jī)制try (WatchService watchService FileSystems.getDefault().newWatchService()) { Path dir Paths.get(/tmp/incoming); dir.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY); while (true) { WatchKey key watchService.take(); // 阻塞等待事件 for (WatchEvent? event : key.pollEvents()) { Path changed (Path) event.context(); System.out.println(event.kind() : dir.resolve(changed)); } key.reset(); // 重置后繼續(xù)監(jiān)聽 } }這個(gè)機(jī)制的幾個(gè)注意事項(xiàng)很關(guān)鍵WatchService只能監(jiān)聽目錄本身不會(huì)遞歸監(jiān)聽子目錄。想監(jiān)聽整棵目錄樹需要手動(dòng)遍歷子目錄逐個(gè)register并在新目錄創(chuàng)建時(shí)動(dòng)態(tài)注冊(cè)。事件類型里ENTRY_MODIFY可能會(huì)觸發(fā)多次文件寫入過(guò)程中可能產(chǎn)生多次修改事件做業(yè)務(wù)處理時(shí)最好加一個(gè)短延遲去重。平臺(tái)延遲差異明顯Windows 上事件可能稍有延遲Linux 上則依賴 inotify 機(jī)制不同文件系統(tǒng)對(duì)事件粒度的支持也有區(qū)別。但在大多數(shù)場(chǎng)景下用WatchService替代“每 5 秒掃一遍目錄”的輪詢實(shí)現(xiàn)無(wú)論是實(shí)時(shí)性、準(zhǔn)確率還是系統(tǒng)開銷都有質(zhì)的提升。部署配置熱更新、文件導(dǎo)入落地的自動(dòng)觸發(fā)我都是用這個(gè)方案。7. 遷移清單與實(shí)操建議從 File 到 NIO 的平滑過(guò)渡7.1 方法替換映射表老項(xiàng)目改造時(shí)最實(shí)用的就是一張映射表。下面這份是我自己整理過(guò)的覆蓋日常 90% 的文件操作場(chǎng)景java.io.File操作java.nio.file替代new File(path)Paths.get(path)file.exists()Files.exists(path)file.isFile()Files.isRegularFile(path)file.isDirectory()Files.isDirectory(path)file.length()Files.size(path)file.lastModified()Files.getLastModifiedTime(path).toMillis()file.isHidden()Files.isHidden(path)file.mkdir()Files.createDirectory(path)file.mkdirs()Files.createDirectories(path)file.listFiles()Files.list(path)或Files.newDirectoryStream(path)file.renameTo(dest)Files.move(src, dest)file.delete()Files.deleteIfExists(path)file.getAbsolutePath()path.toAbsolutePath().toString()file.getCanonicalPath()path.toRealPath().toString()file.deleteOnExit()手動(dòng)立即清理或ShutdownHookfile.setReadOnly()Files.setPosixFilePermissions()或DosFileAttributeView這里特別強(qiáng)調(diào)一下file.length()到Files.size(path)的差異。File.length()對(duì)不存在的文件返回 0可能被誤讀為“文件存在但內(nèi)容為空”Files.size(path)對(duì)不存在的文件會(huì)拋NoSuchFileException語(yǔ)義更準(zhǔn)確。我見過(guò)不少生產(chǎn) bug 就是“文件不存在時(shí) length 返回 0然后被當(dāng)成空文件處理”。7.2 常見問(wèn)題速查表實(shí)際遷移過(guò)程中問(wèn)得最多的幾個(gè)問(wèn)題我整理成一張表問(wèn)題場(chǎng)景推薦方案關(guān)鍵坑點(diǎn)刪除目錄樹失敗walkFileTree配合SimpleFileVisitor目錄非空時(shí)delete()直接失敗遍歷大目錄內(nèi)存暴漲Files.newDirectoryStream()listFiles()一次性加載全部判斷符號(hào)鏈接Files.isSymbolicLink(path)File.isDirectory()默認(rèn)跟隨鏈接移動(dòng)文件要求原子Files.moveATOMIC_MOVE文件系統(tǒng)不支持時(shí)拋AtomicMoveNotSupportedException目錄不存在時(shí)靜默創(chuàng)建Files.createDirectories(path)mkdirs()失敗返回 false無(wú)異常信息流忘關(guān)導(dǎo)致句柄泄漏try-with-resources包住Stream/DirectoryStreamFiles.list()底層持有DirectoryStream需要監(jiān)控文件變化WatchService不遞歸子目錄需手動(dòng)注冊(cè)復(fù)制文件保留時(shí)間戳Files.copyCOPY_ATTRIBUTES不指定則時(shí)間戳是當(dāng)前時(shí)間7.3 遷移節(jié)奏建議老項(xiàng)目如果代碼量巨大不推薦一次性把所有File全換成Path/Files。我見過(guò)不少同事一上來(lái)就全局替換最后在File.separator、deleteOnExit這些邊緣語(yǔ)義上翻了車。穩(wěn)妥的做法是只改新代碼老代碼按模塊逐步替換。一個(gè)實(shí)用的中間策略是寫一個(gè)薄封裝工具類把高頻操作包一層。比如統(tǒng)一提供deleteQuietly(Path)、moveAtomic(Path, Path)、listFilesStream(Path)這類方法底層用 NIO 實(shí)現(xiàn)然后逐步把老代碼的調(diào)用點(diǎn)遷移到工具類上。這樣既能享受新 API 的能力又不至于一次性改動(dòng)太大。比較難遷移的是這幾類依賴FilenameFilter或FileFilter的老代碼可以改成DirectoryStream.FilterPath依賴file.deleteOnExit()清理臨時(shí)文件的要改成顯式清理依賴file.renameTo()實(shí)現(xiàn)移動(dòng)的務(wù)必改成Files.move()否則在 Windows 上的行為極不穩(wěn)定依賴file.getCanonicalPath()解析軟鏈路徑的改成path.toRealPath()語(yǔ)義更明確。新代碼只要運(yùn)行環(huán)境是 Java 8 以上我可以直接建議默認(rèn)java.nio.file沒有理由再用java.io.File做新的文件操作。唯一需要保留File的場(chǎng)景是調(diào)用第三方庫(kù)的舊接口——有些庫(kù)方法簽名還是File參數(shù)這時(shí)候用path.toFile()轉(zhuǎn)換即可。最后說(shuō)點(diǎn)我自己的體會(huì)。NIO 真正讓人覺得舒服的地方不是某個(gè) API 名字更好看而是它把“路徑”和“對(duì)路徑做什么”拆開了。File之所以難用根本原因是它把狀態(tài)判斷、屬性讀取、修改操作全堆在一個(gè)類里失敗時(shí)只給你一個(gè)boolean false你根本不知道發(fā)生了什么。從File遷到Path/Files不是把 API 名字換掉就完了而是把每一次操作腦子里過(guò)一遍它的語(yǔ)義刪除是不存在就報(bào)錯(cuò)還是不存在就跳過(guò)移動(dòng)失敗后是拋異常終止還是靜默降級(jí)目錄遍歷是需要全部加載還是邊讀邊處理把這些問(wèn)題想清楚了代碼的健壯性自然會(huì)上去這也是我寫這篇對(duì)比最想傳達(dá)的一個(gè)點(diǎn)。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
丁香五月人妻| 亚洲爆乳无码精品AAA片蜜桃| 丁香激情五月少妇| 色999五月色| 99热这里只有国产精品| 亚州色综合| 99超级碰碰| 五月六月播婷婷| 亚洲精品一区中文字幕乱码| 久机视频这只有精品| 森林影视大全,最好看的2019年视频 | 精品色色| 婷婷中文在线| 亚洲无码色色| 色五月激情综合| 停停五月色宗合| 91性高潮久久久久久久久| 久久996re热这里只有精品无码| 激情久久综合网| 五月丁香六月色| 亚洲综合婷婷六月丁香五月| 色综合xx| 熟女重口味αV| 97亚洲精品| 亚洲成人免费在线| 91热久久| 亚洲成人AV在线观看| 26UUU欧美激情一区二区| 99综合成人视频在线观看| 五月婷婷影院| 五月花免费视频| 99re思思热久久| 婷婷伊人激情婷婷| 狠狠色婷婷7| 久久婷网| 99re视频在线播放| 亚洲天堂热| 奇米色大香蕉| 国产综合A片| 欧洲第一无人区观看| 久久激情天堂| 日本久久婷| 色五XX| 六月色婷婷欧美| 婷婷五月丁香色播| 超碰三级片| 亚洲狠狠色丁香婷婷综合久久| 狠狠操狠狠爱| 丁香色婷婷五月天| 激情小说婷婷| 丁香五月激情婷婷| 国产午夜一区二区三区| 丁香六月婷婷色XXXXX| 五月丁香婷婷综合视频| 婷婷在线激情| 日本啪啪网| 色播播婷婷| 久久这里只有精品16| 狠狠操天天操| 六月丁香五月激情婷婷| 深爱五月激情| 五月久久婷婷天堂视频| 日本久久网| 婷婷五月综合久久中文字幕| 99这里只有精品|v| 欧美怡红院黄站| 99精品在线| 超碰在线国产| 丁香五月伊人| 99热1| 综合 蜜月 婷婷| 久操人| 激情婷婷22月间| 丁香五月色色婷| www,色综合| HD久久精品视频| 99久久精彩视频| 色色五月天com| 欧美啪啪五月天| 丁香六月色| 三级毛片7979| 五月天a婷婷伊人| 综合久色五月| 亚洲视频色婷婷| 日韩淑女人妻luan伦激情精品一区二| 五月婷婷深深爱| 99精品视频在线观看| 九九伊人网| 五月激情视频| 超碰国产AV| 久草性爱| 色爱终和网| www.狠狠艹| 99综合自拍| 丁香五月天色婷婷| www.婷婷五月.com| 久久精品爱爱| 国产午夜一区二区三区| 五月丁香激情综合| 五月婷婷六月丁香玖玖玫瑰91| 日韩黄黄| 激情综合激情综合| 51精品国自产在线| 九九热黄色| 五月天婷婷网站| 五月天激情亚洲| 五月天社区| 人妻丰满精品一区二区A片| 九九热青青草| 丁香婷婷人妻综合网| 亚洲人人操BD| 色播综合| 色婷网| 天天色天天色天天色天天色天天色| 色爱综合网| 久久综合干| 亚洲深喉AV| 伊人五月综合网| 高潮毛片遮挡费高一百度| 欧美英丁香开心快乐六月天网| 婷婷国产成人| 热热色色五月天婷婷| 综合激情五月婷婷| 五月天婷婷爱| 久久婷婷丁香花综合网| 亚洲婷婷五月天综合| 四月婷婷丁香| 97久久人人人干| 久久多色| 天天干天天插| 色五月中文字幕| 天天 日综合| 色婷婷综合综合网| 丁香六月激情综合| 一级七香蕉| 99这里只有精品视频在线| 26uuu成人网| 婷婷97狠狠成人网站| 91色在线 | 日韩| 五月丁香婷中文| 99在线精品观看99| 精品久久99| 色婷婷www| 高清一区二区三区日本久| 99亚洲精美视频在线观看| www.五月天。com| 99热国产这里只有精品| 久久五月天激情美女| 噜噜噜噜综合在线| 5五月综合网亚洲| 久久er+| 大香蕉综合| 九热视频精品| 五月丁香久久久久| 久久9精品| 久久丝袜婷婷| 爱射综合| 亚洲另类在线观看| 久久婷婷五月综合色播| 四虎99热在线观看网站| 五月伊人婷婷| 香焦网五月天| 99热免| 亚洲无线视频| 五月天婷婷激情小说电影| 99精品在线观看视频| 国产午夜精品一区二区| 999婷婷综合| 久久最新色| 婷婷狠狠97| 超碰熟女拍拍| 天天日夜夜欢| 色婷婷五月综合| 97色碰| 天天狠狠夜夜狠狠2023| 婷婷中文字幕版| 性做爰1一7伦| 深爱激情丁香| 91狠狠综合久久| 色九月婷婷| 玖玖国产视频一区| 婷婷在线五月综合| 丁香五月激情综合| 激情丁香久久| 久久久久97| 五月天亚洲综合网| 99精品久久| 丁香五月激情网| 五月天激情站| 亚洲av成人电影在线观看| 夜夜久久综合网| 天天肏夜夜肏| 五月丁香亭亭电影久久| 婷婷99狠狠躁天天躁中| 插插干干干色| 日韩 中文 欧美| www.99热这里只有精品| 五月情涩综合婷婷| 大香蕉五月天婷婷| 99精品手机在线视频| 久久精彩视频| 婷婷五月天激情在线观看| 狠狠精品干练久久久无码中文字幕| 6080av| 91大神在线免费看视频全集男男一起操| 色综合色| 婷婷丁香六月激情综合| 在线你懂的亚洲欧| 91大操| 日韩成人电影在线播放| 99热九九在线| 天天爽夜夜爽夜夜爽精品| 黄色网址五月婷婷| 99在线精品观看99| 月婷婷婷婷五月| 99久久婷婷国产综合精品青桔| 亚洲精品国产熟女久久久| 天天舔天天摸视频| 丁香五月色综合色播五月| 91高潮喷水久久久久久久久| 中文字幕在线观看视频www| 久久机只有这里精品| 亚洲六月综合激情久久下卡| 欧美成人va| 综合激情五月天六月婷免费视频| 精品一二三区视频立| 色婷婷综合在线| 婷婷五月天色色| 五月婷六月| 91操人| 好大好粗嗯啊-一级黄色大片免费观看-成人AV | 欧美三日本三级少妇三99| 婷婷的五月天另类视频| 九九色色| 色五月首页| 色吧网综合| 色九月| 五月丁香免费看| 五月婷婷和六月| 99爱操| 无码中文一区二区三区| 五月婷婷啪| 亚洲AV久久久久久久久久久久久久久久| w婷婷五月婷婷w| 色色色国产| 99国产小视频2013| 久久久精品99亚洲综合| 啪啪综合网| 久久免费试看120秒| 乱岳熟女50岁| 亚洲亚洲人成综合网络| 亚洲亚洲人成综合网络| 欧美成人精品三区综合A片| 丁香五月激情啪啪| 丁香久久| 成年人最刺激的综合网| 丁香六月婷婷久久综合| 人人操人人爰人人一天天碰夜夜拍夜夜爽-中国A级毛片天天看天天谢… | 182TV大香蕉| 久久免费婷婷视频| 五月人妻婷婷视频| 先锋资源91| 激情五月婷婷六月丁香| 五月天国产| 日批在线看| 狠狠久久婷五月综合色| wwccc久久久| 丁香五月天婷婷久久| 丁香六月色婷婷欧美| 97碰免费视频在线| 五月丁色AV| 久久精品日| 99天堂网| 色婷婷很很丝袜| 综合色、色综合| 丰满少妇乱A片无码| 国产午夜精品AV一区二区麻豆| 色色网站在线| 无码激情AAAAA片-区区| 办公室少妇激情呻吟A片在线观看 白人荫道BBWBBB大荫道 | 99热这里有精品| 亚洲激情av| 99ri国产在线| 在线观看国产高清视频免费网站| 久久大香蕉丁香| 4399无码视频| 大香蕉人人人| 色婷婷婷av| 五月天激情偷拍| 激情五月综合免费| 亚洲va在线∨a天堂va欧美va| 婷婷五月视屏| 大香蕉啪啪啪| 超碰人人摸人人操| www.日韩国产| 丁香五月瑟瑟| 久久九精品| 大香蕉五月天| 丁香五月六月| 欧在线一区| 狠狠se| 五月婷婷色情| 99久久综合精品五月天| 九九婷婷综合| 五月天丁香久久综合| 久久久噜噜噜操操操| 婷婷的色色五月天| 色欲香综合网| 99日本精品视频热| 日日操无码| 96精品久久久久久久久| 五月花婷婷最新| www.久热| 另类激情综合| 97超级碰人人| 99丁香五月婷| 婷婷情色五月天| 五月激情小说| 久久久宗合| 五月天婷婷丁香蜜桃91| 91热99| 五月天久久色| 亚洲性受XXXX五月丁香| 激情综合网五月激情网| 欧美精品中文字幕亚洲专区| 二色AV| 五月天 另类图片| 天天肏视频| 精品香蕉99久久久久网站| 9久久精品视频| 精品九九在线观看视频| 色综合久久44| 99视频在线啪| 九九综合久久| 中文字幕网伦射乱中文| 99啪| 婷婷五月丁香五月综合网| 中文字幕在线日亚州9| 色色婷婷色色| 第四色婷婷丁香五月| 99热欧美| www.henhenl| 亚洲婷婷激情888精品久| 婷婷色操| 久久久人人操A V| 色噜噜伊人| 超碰超碰在线| 五月天丁香婷| 五月丁香综合中文| 伊人九九热| 国产色五月婷婷| 337p大胆噜噜噜噜噜91Av| 美女伊人久久| 日日干天天| 97人碰人操| 天天做天天视天天谢| 综合另类视频| 亚洲成人AV在线观看| 五月天色不卡| 五月婷激情影院| 女高怪谈在线观看| 丁香六月av| 婷婷丁香色情五月天| 91久久日日| 婷五月丁香| 婷婷午夜综合| 97啪啪| 亚韩在线视频| 婷婷激情伍月网| 色九区| 國語久久婷| 日本久久婷婷| 五月丁香激情婷婷| 99热手机在线精品| 亚洲久久视频| 久cao香蕉影院| 色婷婷五月天激情综合| 97人碰人操| 五月天婷婷开心| 国产精品激情AV久久久青桔| 五月婷婷啪啪网| 日本三级99人妇网站| 五月婷婷手机在线| 青青草网武则天| 夜夜操夜夜操| 91干| 免费无码毛片一区二区A片| 五月激情丁香久久综合网| 亚洲操操操| 岛国资源网| 婷婷五月天综合亚洲| 欧美大奶熟女噜噜噜噜| 97操操网| 丁香激情五月| 久久婷婷激情五月天一区二区| www.色婷婷| 久久久久久久97| 欧美人妻一区二区| 三级大香蕉网| 久久新地址| 久久久中文| 99热这里只有精品13| 一级片无码| 欧美色性色好| 激情九月综合| 五月综合激情久久| 国产 亚洲 在线| 日日日,com| 狠狠色综合五月人人| 激情综合激情综合| 99热香港| 国产亚洲网站在线| 国外亚洲成AV人片在线观看| 激情五月天综合网| 丁香五月天人体| 成人视频网| 丁香六月激情综合啪啪| 人人干人人干骚美女| 可以直接看的av| WWW.桔色成人.COM| 久草五月| 老师把我爽高潮了免费A片| 99久久婷婷国产综合精品草原| 五月丁香好婷婷A片网 | 色9色| 日日操无码| 婷婷色在线| 色色亚卅| www.天天干.com| 精品九九久久| 色婷婷成人做爰A片免费看网站| 色色色无码| 国产xxxxx在线观看| 1024在线视频| 中文字幕有多少字| 天天天天天天操| 五月婷婷开心丁香| 天天插天天很| 国产精品成人AV在线| 人妻丰满精品一区二区A片| 第四色大香蕉| 涩涩涩五月天| 亚洲五月天狠狠| 99啪啪视频| www.com在线操视频免费观看| 天天综合网在线| 99在线精品视频| www.25五月婷婷| 日韩高清久久| 欧美婷婷综合网| 开心五月网 | 人妻久热| 天天爽天天| 天天 青草 丝袜制服 在线| 丝袜人妻| 久久久久久综合88| 久草a片| 天天综合网站| 丁香六月天| 97人人操人人爽| 九九青草热| 婷婷丁香五月久久| oumeisesewang| 激情综合网丁香| 日本一毛片| 成人性生活免费观看。| 爱操天堂| 综合久久五月| www,久久久人人| 91午夜婷婷狠狠久久综合9色| 天天精品视频免费观看| 久久婷婷伊人| 五月婷婷综合视频| 婷婷99狠狠| 99久久精品国产色欲| 婷婷五月丁香基地| 五月天丁香| 日本熟女二区| 色婷婷www| 四色女婷婷| 噜噜噜色噜噜| WWW,婷婷,COM| 免费观看大片视频 丁香婷婷 六月欧美| 五月激情久久综合网| 五月天综合缴情网网站0| 丁香五月婷婷狠狠色| 久久综合婷婷| 五月天成人伊人| 激情婷婷内射| 99色热综合| 久8色色| 亚洲五月天天| 9久热这里只有精品| 99日韩网站| 丁香六月色婷婷| 深情五月天| 丁香五月激情婷婷婷婷在线观看| 26UUU欧美激情一区二区| 亚州操操| 久久婷婷伊人| 51精品国自产在线| 在线91日韩| 久99久在线| 久久色在线视频| 婷婷激情蜜桃玖玖丁香| www,天天干| 五月丁香好婷婷A片网| 激情五月婷婷| 91 影音先锋| 国产女人十八水真多1| 碰碰碰97国产| 嫩草极品| 国产亚洲网站在线| 九九婷婷五月天影视| 日日日日操| 超碰超碰在线| 丁香伍月婷电影全集| 九九综合88| 99ri精品在线| 91五月天| 美臀自射自家人妻| 99精品网| 国产午夜伦鲁鲁| 丁香视频| 五月丁香拍拍激情综合| 激情五月婷黄版| 97色碰| 综合色视频| 丁香六月婷婷五月天| 色情丁香五月天| 美国十月色婷婷在线观看| 色色色综合网| 久久99免费视频| 99re思思热在线视频| 婷婷五月天BBw| 99综合| 97综合在线| 狠狠色婷婷综合开心影视| 丁香久久激情俄| 五月丁香激情综合啪啪| 区区欧美你爱| 婷婷俺去也| 婷婷玖玖丁香| 久久久五月婷婷| 亚洲六月色| 综合玖玖偷拍| 色色免费网战视频| 婷婷在线视频| 免费婷婷| 五月天婷婷在线观看| 久久婷婷五月天| 人妻激情视频| 激情五月婷婷在线区| 色婷婷导航| 亚洲婷婷综合视频| 毛片新网地| 日本色五月| 五月丁香婷婷成人版| 99热这里只有精品一区| 日日鲁鲁鲁夜夜爽爽狠狠视频97| 99热最新精品| 99性色| 91狠狠色丁香| 丁香五月婷婷五月天| 色欲色欲久久宗合网| 操日本色| 99成人精品六| 一本道在线电影| 丁香婷婷久久| 婷婷五月天色播| 丁香五月婷婷少妇| 毛片毛片毛片毛片| 欧洲区自拍| 中文乱子伦视频| 亚洲狠9| 人人人操B超碰| 免看黄大片AA | 丁香六月婷婷综合网| 狼人久草| 欧美激情丁香五月天久久婷婷一区| 久色网| 97操在线视频| 大香蕉AV在线| 婷婷五月天天天日日夜夜| 婷婷激情社区| 成人网站在线观看视频| 俺去也五月天婷婷| 亚洲 日韩色色| 99精品视频在线观看| 欧洲激情五月天婷婷| 久热大香蕉| 精品国产人人爱人人| 99热婷婷| wwwxxx五月婷婷小说| 99视频热99| 五月丁香六月婷婷亚洲综合| 玖玖婷婷色| 亚洲旡码| 26UUU成人网| AA片在线观看视频在线播放| 欧美婷婷五月天综合| yw国产AV| 夜夜骑福利资源| 91九九精品| 亚洲色图五月丁香| 久这里只有精品99| 丁香青青五月天| 五月天激情影院| 五月天色婷婷小说| 色碰干| EEUSS鲁片一区二区三区| 99re这里有精品手机在线| 9999热在线观看| 欧美内射AA| 五月天色综合服务平台| 天堂久久大香蕉| 综合图片色色| 久色视频在线| 欧美五月婷婷综合| www.五月婷婷久久.com| 国产精品噜噜在线视频| 久草嫩草在线观看| 99天堂网| 五月天激情无码专区| 9热视频在线观看| 中文字幕日产A片在线看| 亚洲第一精品成人999久久精品| 97色啪| 亚洲色久| 五月婷婷激情| 最新五月天婷婷影| 午夜激情婷婷| 91久女| 亚洲1区| 亚洲丁香五月在线观看| 国产综合81p| 五月丁香色婷婷| 天天操天天操天天操天天操天天操天天操天天操天天操天天操 | 色五月激情五月| 丁香婷婷人妻| 五月天色站| 丁香五月AV| 色色日本欧美| 九九热区一区二区三区| 天天插天天狠| 五月丁香六月婷| 精品一区二区三区三区| 九九99精品视品| 婷婷五月色| 五月丁香啪啪啪| 激情五月婷婷| 人妻久久久久久久| 五月天激情av| 亚洲五月天婷婷综合| 国产日批视频| 天天做综合| 99九九精品| 日本天堂爱爱| 99视频在线播放大全| 国产色99| 日本人人草草| 国产1区2区3区| 国产亚洲99久久| 9一精品视频观看| 丁香婷婷婷| 久热A片| 夜夜嗨一区二区三区直播内容 | 激情98色婷婷五| 午夜天堂一区人妻| 爱99干99| 91色综合久久| 黄色aa观看aaguochan| 亚洲精品第一国产综合亚AV | 在线另类| 99自拍视频在线| 色色色欧美| 亚洲激情97五月天| 超碰99资源站| 激情五月影院| 99热这里精| 久久九九经典| 亚洲精品国产成人AV在线| 99久久丝| 婷婷婷婷婷婷婷婷婷婷丁香| 日本va欧美va欧美精品88| 婷婷五月天丁香社区| 久久久婷| 五月丁香六月婷婷在线播放| 五月天丁香欧美激情| 91精品在线看| 日日想日日夜日日操| 九九伦子片| 激情久久久久久久久久久| 丁香六月婷婷综情欧美| 婷婷最新地址| 色伊人婷婷| 久久这里只有精品07| 婷婷综合国产| 91啪啪视频| 一二三区视频韩国| 婷婷五月综合啪| www五月| 激情五月狠狠| 丁香九月婷婷| 草榴成人影片| 丁香五月在线观看| 蜜桃五月天| 久/久精品99看9| 大香蕉在九| 激情综合网址| 思思热在线免费视频| 综合色情网| 婷婷中合| 久久ab| 九九性视频| 五月天激情综合在线| 热婷婷av| 婷婷丁香成人| 久久精品人妻| 人妻操在线看| 丁香五月激情宗合| 久热9热| 狠狠爱综合网| 激情性爱五月| 色五月婷婷内射| 这里都是精品99| 欧美精品A片一区在线观看| 无码人妻少妇色欲AV一区二区| 婷婷五月天综合在线| 五月丁香天天| 99亚洲天堂| 天综合日日夜综合7799| 国产伦亲子伦亲子视频观看| www超碰| 直接看的AV| 五月婷婷这里都是精品| 久久婷婷亚洲| 婷婷终合色图| 中文字幕91,综合| 日日影院 | 色婷婷久久| 色婷婷丁香五月| 婷婷激情网五月天| 婷婷AV丁香| www.99在线| 五月丁香久久色| 五月成人丁香av91| 五月激情影院| 五月天婷婷色综合| 超碰二区| 丁香激情五月天| 婷婷王月天影院| 色婷婷五月天成人网| 看婷婷五月天网| 九色自拍| 久久 婷婷 五月天| 色伊人啪| 九九 激情 网| 亚洲成人AV在线| 国产亚洲99久久精品熟| 丁香六月在线综合| 国产人妻777人伦精品HD| 丰满人妻一区二区三区| 丁香激情久久| 日本91在线| 99精品在线观看视频| 五月天成人免费视频| 舔色婷婷| 婷婷 色 丁香 夜| 亚洲色优| 99激情| 五月天婷婷丁香导航| 五月天亚洲综合网| 九九热在线观看视频| 五月婷婷开心五月| 四色五月婷婷在线观看| www,婷婷| 欧洲亚洲精品| 九九精品免费| 思思热在线视频精品| 无套内射极品大美女| 五月婷婷在线免费观看 | 九九无毛| 丁香五月九九| 五月天停停日日| 91久久电影| 9久热在线视频精品| 五月 成人 婷婷| 色碰碰| 丁香五月天啪啪| 综合亚洲五月天| 夜夜天天久久婷婷| 开心色播色五月婷婷| 五月丁香婷婷三级| 婷香五月激情视频| 五月色丁香| 欧美婷婷五月丁香| 无码色| 五月天综合在线网| av一区免费看| 狼友超碰| 狠狠做六月爱婷婷综合aⅴ| www.精品99| 性色99| 婷婷五月天天天| 网色99| 欧美色五月| 激情五月婷婷视频| 久久婷婷草| www.久久99| 亚洲XX日本| 婷婷五月天激情免费在线观看| 婷婷成人视频| 九九在线精点品| 天天躁日日躁狠狠躁日日躁2022年5月9日| 91精品刘玥| 手机旧版看人妻1025| 狠狠做六月爱婷婷综合aⅴ| www.狠狠干| 久久99热这里只有精品| 色五月网址| 中文字幕 中文字幕明步 | 五月香婷婷| 五月成人丁香av91| 久久99激情| 色婷婷欧美在线| 国产色色色色| 色情五月婷婷| 99日热在线视频| 色婷婷9| 久久五月网| 激情开心五月天| 久久五月天婷婷| 丁香五夜激情四射夜夜夜| 五月丁香999| 丁香五月天激情综合网| 99热99久久| 大战熟女丰满人妻AV| 色五月婷婷五月天激情综合| 成年AAAA色情| 五月激情婷婷国产精品久久久久久| 亚州操人在线视频| wwww.色婷婷| 亚洲va欧美| 亚洲狠狠干| 丁香久久| 久久婷网| 亚洲激情精品| 色婷婷丁香| 91视频免费后入强操| 丁香六月婷婷高清| 日本啪啪天堂| 亚洲AV电影av| 99热视| 亚洲旡码| 大香人妻| 婷婷日| 激情综合区| 五月婷九月| 夜夜骑操AV| 五月综合色| 亚韩精品视频1区| 天天天天天天天干| 国产激情av| 黃色三级三级三级三级 qixing300.shrkbk.com www.jinbozs.com tianmiaosw.com | AV九九| 99久久五月天| 天天爽综合| 日日色综合| 久色激情| 思思热AV| 99在线视频操999| 夜夜躁狠狠| 久激情网| 精品亚洲日韩99欧美片| 色色色色色色综合| 婷婷五月天激情网| 66精品国产成人| 五月婷激情影院| 欧美日韩色色| 怡红院院久久| 五月天激情小说| 九九色热| 成人短视频在线| 超碰高清在线| 99久久玖玖| 五月婷婷玖玖综合玖玖爱| 亚洲性爱干干| 久久久久久人妻| 91九色精品熟女内射| 97九色视频| 亭亭玉月丁香| 91午夜激情| 久草视频大香蕉99| 狠狠五月综合在线| 91人妻人人操| 激情五月婷婷色播网| 国产一二区爆乳_1国产日韩一区二区三-成人AV| 丁香 婷婷 激情 综合 五月| 超碰成人在线观看| 国产ava| 天堂色婷婷| 丁香六月婷婷久久高清| 欧美99视频| 小色小蛇伊人婷婷色香五月| 色五月婷婷小说亚洲中文字幕组| 日韩AV在线电影| 美女妹子后射视频网站在线观看| 久久成人亚洲欧美电影| 97好吊操| 东北熟女视频99| 色五开心五月五月深深爱| 色图亚洲91| 五月婷婷久| 1024在线视频| 九九这里有精品| 99久久玖玖| 99久久99九九九99九他书对| 欧美日韩成人免费在线| 五月婷婷基地| 天天 青草 制服丝袜 在线| 婷婷综合久久| 插插五月天| 丁香婷婷浪潮AV久久综合| 激情五月丁香六月| 成人在线高清| 婷婷五月花| 五月天婷婷色五月天| 少妇高潮呻吟A片免费看软件| 丁香八月综合激情| 欧美精品狠狠色丁香婷婷| 色婷婷成人| 久婷婷婷| 91精品久久久久久77777| 亚洲开心激情网| 国产精女同一区二区三区久| 五月丁香六月婷婷网| 影视av久久久噜噜噜噜噜三级| 伊人99热| 婷婷五月丁香基| 夜色.cnm| 久久精品4| 77799热| 无码字幕中文| 色婷婷AV在线| 精a品a视a频| seav天堂| 播播网色播播| 《诡秘之主》在线观看| 亚洲狠狠爱婷婷| 狠狠狠狠狠干| 五月丁香六月婷婷综合在线| 95精品区一区二| 五月精品| 最新热中文字幕| 性爱网五月婷婷| 五月色综合| 五月丁香网av| 极品五月天| 九九综合九九| 五月丁香久久激情网| 91视频久久久| 色婷婷99| 日韩aaaaa| 综合激情五月丁香9999久久精| 91在线人| AV性爱网| 国产精品色婷婷AV综合色色| 五月婷婷啪| 性色九九| 天天色宗合| 婷婷激情五月天小说校园| 亚洲天堂爱爱| 99热亚洲只有色| 丁香婷婷啪啪| 天天操夜夜爽| 日本91在线| 精品婷婷丁香五| 开心深爱激情网| 久久五月天色| 99热无码精品| 日韩精品一品二区三区的使用体验| 九九热免费视频| 天天操夜夜操| 天天天天天天天操| 在线日韩视频| 99资源在线| 亚洲最大成人综合网720P| 日本一毛片| 日日操人人操| 高清无码.com| 9 1在线视频| 免费无码毛片一区二区A片| 99九无网码| 性99网站| 激情五月图| 一区二区免费看| 高清a片基地| 亚洲精品视频在线| 久久综合丁香| 99re思思久久| 狠狠狠激情网| 99视频这里只有免费精品| 亚洲成片在线观看| 六月丁花香啪啪激情欧美| 欧美在线视频99| 色色色热| 丁香成人色情五月天| 在线,国产,色,热视频| 久久大香蕉同僚| 在线综合91| 久久婷青青草原| 日本综合色图| 国产亚洲色婷婷久久99精品91| 几激情五月婷婷色五月色天堂| 五月丁香啪啪啪啪| 五月天天天操天天爽夜夜操| 97狠狠色| 丁香五月婷婷偷拍| CAOBIBI| 亚洲免费成人电影AV| 亚洲欧洲中文日韩久久AV乱码| 婷婷五月色| 久久精品五月天| 精品久久人妻| 天天爽,夜夜爽| 五月丁香婷婷激激激综合网色播| 婷婷色无码| 婷婷五月69| 色五月大香蕉| 色色吧综合| 日日干天天射| 色婷婷9| 久久久99婷婷久久久久久| 国产综合81p| 成人网页在线观看| 黄色99热| 免费成人网在线观看| www.色色com| 激情淫乱男女| 奇米影视在线视频| 日韩有码一区| 99在线综合视频| 五月天伊人久久| 国产综合丁香五月天| 卡视频1区2区| 色色婷婷色色| 九九人人自拍| 久久总和99| 超碰人人艹| 九九色逼| 丁香五月天天哦| 亚州精品色情在线观看| 久热这里只有精品在线观看| 婷婷五月成年人| 天天爽天天日人人爱| www.99热视频在线观看| 色月视频| 人人摸人人射| 99视频热| 五月成人网站| 欧美日比视频| 九九99在线免费在线观看视频| 色婷婷久久| 色婷婷九月| 久久久天堂国产精品女人| 国产SUV精品一区二区883| 日本eVa一区=区视频| 琪琪狠狠干| 香蕉97碰碰碰超视精品| 色色色五月婷| 久久99久久99精品免视看婷婷| 丁香六月婷婷久久综合八月| 婷婷的五月天另类视频| 久色五月婷婷综合| 99精品小视频| 九九99精品视频| 丁香五月天色婷婷| 久久xx| 丁香婷婷激情网站| 1024欧美日韩精品久久久| 日本97在线视频| 色色综合无码| 色五月天视频| 六月婷婷色综合| 色综合久| 亚洲蜜桃精久久久久久久久久久久| 色涩视频久久| 丁香五月激情网| 日本色噜| 丁香五月综合网亚洲综合欧美狠狠| 开心婷婷中文字幕| 狠狠狠狠狠狠狠狠| 午夜无码熟熟妇丰满人妻| 婷婷五月a| 这里只有精品免费在线视频| 婷婷操逼网| AVDV久久| 大香蕉综合| www久久久久久久| 五月丁香综合激情网| 国产成人VA| 亚洲成人五月| 99色视频| 人人操91色| 亚洲艹网| 日本五月婷| 天天色综网| 亚洲av电影在线| 99激情在线| 欧美综合五月丁香六月婷| 色五月婷婷操逼| 婷婷五月色| 亚州综合色| 激情五月激情综合网一级丸片 | 久久看九九90| 97视频91| 五月丁香黄色| 久久ww| 九九99热精品| 国产精品久久99| 久久人妻www| 九九色婷婷| 五月丁香久久丝袜啪啪| 蜜臀av无码久久久久久久久 | 色婷婷影视99| 丁香六月色婷婷欧美| 直接看的av| 午夜少妇在线观看视频| 色哟哟性爱av| 亚洲综合婷婷| 日本色道视频网站| 亚洲韩国日产综合AV| 99rewww| 大天天伊人| 婷婷大香焦| 激情深爱五月婷婷| 激情都市丁香婷婷| 国内一级片| 97碰在线视频| 色婷婷电影网| 久久五月婷综合| 日日噜人人人做人| 97se视频在线| 综合另类激情| 五月婷高清视频| 国产亚洲色婷婷久久99精品91| 激情五月狠狠喔| 五月丁香网中文字幕| 欧美人妻一区二区| 91视频久久久| 五月天久久综合婷婷丁香| 天天爽夜夜操| 亚洲中文av| 九九热精品在线| 丁香九月色| 五月丁激情| 色综合天天| 欧美婷婷丁香五月社区| 婷婷色六月| 西西4r午夜剧场| 五月天色婷婷视频| 99视频自拍| 日韩ac不卡无码| 991精品在线视频| 欧美三级视频下载| 五月天成人在线播放丁香| 韩国真做片在线观看| 婷婷六月激情小说网| 大香蕉五月婷婷| 五月五月婷婷| 五月亚洲| 91九九热| 婷婷色情五月| 天堂呦 呦百度搜索-百度搜索| 无码天天操| 天天插天天日| 激情五月丁香五月| 97色在线视频| 日本久久视频| www.99热在线观看| A1片久久久| 日韩超碰在线| 婷婷色色丁香五月天| 久9热视频| 五月丁香激情综合啪啪| 九九热视频这里只有精品| 99日视频在线| 岛国av网站| 毛v一区二区视频| 天天插天天爽| 色9月| 超碰二区| 丁香五月综合婷婷| 黄网在线播放| 五月丁香综合啪啪| jiZZdr| 国产婷婷综合| 少妇搡BBBB搡BBB搡毛茸茸| 91丨人妻丨国产丨丝袜| 色涩视频久久| 日本噜噜色网| 亚洲六月综合激情久久下卡| 99视频这里只有久久精品 | 日本3级片一区2区| 久久WW| 人人操日| 五月丁香六月色婷婷综合五月天| 亭亭五月丁香五月天激情| 伊人五月天日日夜夜久久久天天| 久久久久久欧美精品se一二三四| 丁香五月 综合| 亚洲深喉AV| 婷婷色情五月| 久久婷婷五月激情综合| 久久精品系列| 五月婷婷av| 五月激情在线| 色五月六月婷婷| 99视频在线观看视频| 另类 在线| 秋霞性爱AV| 中国丰满熟女A片免费观| 色婷婷丁香特级性爱视频| 色婷婷精| 97精品自拍视频| 97人人操人人爽| AV九九| 五月丁香六月花| 五月丁香婷婷婷激情爱爱| 婷婷综合网| 色欲日日躁| 殴美97色| 亚洲啪啪视频| 99热国产这里只有| 国产九月婷婷| WWW99热| 精品一区二区三区四区五区六区介绍| 亚洲免费综合一区| 丁香五月天在线观看| 91AV婷婷| 99精品国产在热久久| 久久婷婷综合五月趴| 亚洲AV人人操| 天天射影院| 99热a片免| 五月婷婷另类| 丰滿爆乳一区二区三区| 九九这里是免费的视频5| 婷婷五月成人有| 欧在线一区| 97色婷婷| 亚洲人人操BD| 久久伊人婷婷| 密着浓厚中出乚交尾GvG935| 开心激情婷婷| 99这里有精品免费| 人人操人人看97干| 久99热| 综合在线色婷婷| WWW、日本色丁香co m| 色约约视频一区二区三区四区五区 | 另类激情四射| 免看黄大片AA | 大香蕉伊人99| 九九热视频免费的|