1 NIO的一些基础预备知识
Java中IO流类的体系中BIO与NIO:https://blog.csdn.net/ZGL_cyy/article/details/104326458
Java IO体系与NIO和BIO体系面试题 :https://blog.csdn.net/ZGL_cyy/article/details/122836368
为什么使用NIO:因为传统IO文件传输速率低,所以选择了NIO进行文件的下载操作。NIO还有一个好处就是其中零拷贝可以实现减少内存中数据的重复,减少CPU操作的效果。所以相对于传统IO,NIO有着效率高点的优势。
2 NIO为何较传统的io速度较快
就拿单个io过程来看,首先时间主要花在了用户态和内核态的转换上,其次,考虑将多个io的“合并”为一个io,这不就节省时间了吗
相应的NIO主要做了两方面的提升
1.避免了用户态和内核态的交换,直接操作内存,用户态和内核态的转换是很费时的,传统的io写入磁盘时,用户态的接口不能直接操作内存,而是通过操作系统调用内核态接口来进行io。
2.利用buffer减少io的次数,buffer化零为整”的写入方式因为大大减小了寻址/写入次数,所以就降低了硬盘的负荷。
3.IO 是基于流来读取的,而NIO则是基于块读取,面向流 的 I/O 系统一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。为流式数据创建过滤器非常容易。链接几个过滤器,以便每个过滤器只负责单个复杂处理机制的一部分,这样也是相对简单的。不利的一面是,面向流的 I/O 通常相当慢。
一个 面向块 的 I/O 系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多。但是面向块的 I/O 缺少一些面向流的 I/O 所具有的优雅性和简单性。
4.非阻塞IO 和 异步IO的支持, 减少线程占有的栈空间,以及上下文切换
5.IO 多路复用的支持
6.Buffer 支持,所有读写操作都是基于 缓冲 来实现
7.NIO 支持 Direct Memory, 可以减少一次数据拷贝
8.Netty 零拷贝的支持
3 NIO实战上传下载
3.1 url下载文件
java NIO包提供了无缓冲情况下在两个通道之间直接传输字节的可能。
为了读来自URL的文件,需从URL流创建ReadableByteChannel :
ReadableByteChannel readableByteChannel = Channels.newChannel(url.openStream());
从ReadableByteChannel 读取字节将被传输至FileChannel:
FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME); FileChannel fileChannel = fileOutputStream.getChannel();
然后使用transferFrom方法,从ReadableByteChannel 类下载来自URL的字节传输到FileChannel:
fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
transferTo() 和 transferFrom() 方法比简单使用缓存从流中读更有效。依据不同的底层操作系统,数据可以直接从文件系统缓存传输到我们的文件,而不必将任何字节复制到应用程序内存中。
在Linux和UNIX系统上,这些方法使用零拷贝技术,减少了内核模式和用户模式之间的上下文切换次数。
工具类:
/**NIO文件下载工具类 * @author olalu */ public class NioDownloadUtils { /** * @description: * @param file: 要下在文件 * @return: void */ public static void downloadDoc(File file,HttpServletResponse response) throws IOException { OutputStream outputStream = response.getOutputStream(); String contentType = Files.probeContentType(Paths.get(file.getAbsolutePath())); //设置响应头 response.setHeader("Content-Type", contentType); response.setHeader("Content-Disposition", "attachment;filename="+ new String(file.getName().getBytes("utf-8"),"ISO8859-1")); response.setContentLength((int) file.length()); //获取文件输入流 FileInputStream fileInputStream = new FileInputStream(file); //获取输出流通道 WritableByteChannel writableByteChannel = Channels.newChannel(outputStream); FileChannel fileChannel = fileInputStream.getChannel(); //采用零拷贝的方式实现文件的下载 fileChannel.transferTo(0,fileChannel.size(),writableByteChannel); //关闭对应的资源 fileChannel.close(); outputStream.flush(); writableByteChannel.close(); } public static void downloadDoc(String path,HttpServletResponse response) throws IOException { File file = new File(path); if (!file.exists()){ throw new RuntimeException("文件不存在"); } downloadDoc(file,response); } }
3.2 通过NIO上传文件
/** * 文件上传方法 */ public static Result uploading(MultipartFile file) { //获取文件名 String realName = file.getOriginalFilename(); String newName = null; if(realName != null && realName != ""){ //获取文件后缀 String suffixName = realName.substring(realName.lastIndexOf(".")); //生成新名字 newName = UUID.randomUUID().toString().replaceAll("-", "")+suffixName; }else { return Result.fail("文件名不可为空"); } //创建流 FileInputStream fis = null; FileOutputStream fos = null; //创建通道 FileChannel inChannel = null; FileChannel outChannel = null; try { fis = (FileInputStream)file.getInputStream(); //开始上传 fos = new FileOutputStream(UPLOAD_URL+"\\"+newName); //通道间传输 inChannel = fis.getChannel(); outChannel = fos.getChannel(); //上传 inChannel.transferTo(0,inChannel.size(),outChannel); }catch (IOException e){ return Result.fail("文件上传路径错误"); }finally { //关闭资源 try { if (fis != null) { fis.close(); } if (fos != null) { fos.close(); } if (inChannel != null) { inChannel.close(); } if (outChannel != null) { outChannel.close(); } } catch (IOException e) { e.printStackTrace(); } } return Result.ok(newName); }
以上是Java怎麼使用NIO優化IO實作檔案上傳下載功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

新興技術對Java的平台獨立性既有威脅也有增強。 1)雲計算和容器化技術如Docker增強了Java的平台獨立性,但需要優化以適應不同雲環境。 2)WebAssembly通過GraalVM編譯Java代碼,擴展了其平台獨立性,但需與其他語言競爭性能。

不同JVM實現都能提供平台獨立性,但表現略有不同。 1.OracleHotSpot和OpenJDKJVM在平台獨立性上表現相似,但OpenJDK可能需額外配置。 2.IBMJ9JVM在特定操作系統上表現優化。 3.GraalVM支持多語言,需額外配置。 4.AzulZingJVM需特定平台調整。

平台獨立性通過在多種操作系統上運行同一套代碼,降低開發成本和縮短開發時間。具體表現為:1.減少開發時間,只需維護一套代碼;2.降低維護成本,統一測試流程;3.快速迭代和團隊協作,簡化部署過程。

Java'splatformindependencefacilitatescodereusebyallowingbytecodetorunonanyplatformwithaJVM.1)Developerscanwritecodeonceforconsistentbehavioracrossplatforms.2)Maintenanceisreducedascodedoesn'tneedrewriting.3)Librariesandframeworkscanbesharedacrossproj

要解決Java應用程序中的平台特定問題,可以採取以下步驟:1.使用Java的System類查看系統屬性以了解運行環境。 2.利用File類或java.nio.file包處理文件路徑。 3.根據操作系統條件加載本地庫。 4.使用VisualVM或JProfiler優化跨平台性能。 5.通過Docker容器化確保測試環境與生產環境一致。 6.利用GitHubActions在多個平台上進行自動化測試。這些方法有助於有效地解決Java應用程序中的平台特定問題。

類加載器通過統一的類文件格式、動態加載、雙親委派模型和平台無關的字節碼,確保Java程序在不同平台上的一致性和兼容性,實現平台獨立性。

Java編譯器生成的代碼是平台無關的,但最終執行的代碼是平台特定的。 1.Java源代碼編譯成平台無關的字節碼。 2.JVM將字節碼轉換為特定平台的機器碼,確保跨平台運行但性能可能不同。

多線程在現代編程中重要,因為它能提高程序的響應性和資源利用率,並處理複雜的並發任務。 JVM通過線程映射、調度機制和同步鎖機制,在不同操作系統上確保多線程的一致性和高效性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3漢化版
中文版,非常好用

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。