{"id":1207,"date":"2018-05-03T23:34:57","date_gmt":"2018-05-03T15:34:57","guid":{"rendered":"https:\/\/damogame.cn:15443\/wordpress\/?p=1207"},"modified":"2018-05-03T23:34:57","modified_gmt":"2018-05-03T15:34:57","slug":"%e5%af%b9%e4%ba%8e-netty-bytebuf-%e7%9a%84%e9%9b%b6%e6%8b%b7%e8%b4%9dzero-copy-%e7%9a%84%e7%90%86%e8%a7%a3","status":"publish","type":"post","link":"https:\/\/i007.cc\/wordpress\/archives\/1207","title":{"rendered":"\u5bf9\u4e8e Netty ByteBuf \u7684\u96f6\u62f7\u8d1d(Zero Copy) \u7684\u7406\u89e3"},"content":{"rendered":"<h1 class=\"postTitle\"><a id=\"cb_post_title_url\" class=\"postTitle2\" href=\"http:\/\/www.cnblogs.com\/xys1228\/p\/6088805.html\">\u5bf9\u4e8e Netty ByteBuf \u7684\u96f6\u62f7\u8d1d(Zero Copy) \u7684\u7406\u89e3<\/a><\/h1>\n<div class=\"clear\"><\/div>\n<div class=\"postBody\">\n<div id=\"cnblogs_post_body\" class=\"blogpost-body cnblogs-markdown\">\n<p>\u4f5c\u8005\uff1a<a href=\"http:\/\/www.cnblogs.com\/xys1228\/\" target=\"_blank\" rel=\"noopener\">@xys1228<\/a><br \/>\n\u672c\u6587\u4e3a\u4f5c\u8005\u539f\u521b\uff0c\u8f6c\u8f7d\u8bf7\u6ce8\u660e\u51fa\u5904\uff1a<a class=\"uri\" href=\"https:\/\/www.cnblogs.com\/xys1228\/p\/6088805.html\">https:\/\/www.cnblogs.com\/xys1228\/p\/6088805.html<\/a><br \/>\nEmail\uff1ayongshun1228@gmail.com<\/p>\n<hr \/>\n<blockquote>\n<h4>\u76ee\u5f55<\/h4>\n<p><a href=\"https:\/\/www.cnblogs.com\/xys1228\/p\/6088805.html#_caption_0\"><strong>\u901a\u8fc7 CompositeByteBuf \u5b9e\u73b0\u96f6\u62f7\u8d1d<\/strong><\/a><br \/>\n<a href=\"https:\/\/www.cnblogs.com\/xys1228\/p\/6088805.html#_caption_1\"><strong>\u901a\u8fc7 wrap \u64cd\u4f5c\u5b9e\u73b0\u96f6\u62f7\u8d1d<\/strong><\/a><br \/>\n<a href=\"https:\/\/www.cnblogs.com\/xys1228\/p\/6088805.html#_caption_2\"><strong>\u901a\u8fc7 slice \u64cd\u4f5c\u5b9e\u73b0\u96f6\u62f7\u8d1d<\/strong><\/a><br \/>\n<a href=\"https:\/\/www.cnblogs.com\/xys1228\/p\/6088805.html#_caption_3\"><strong>\u901a\u8fc7 FileRegion \u5b9e\u73b0\u96f6\u62f7\u8d1d<\/strong><\/a><\/p><\/blockquote>\n<hr \/>\n<p>\u6b64\u6587\u7ae0\u5df2\u540c\u6b65\u53d1\u5e03\u5728\u6211\u7684\u00a0<a href=\"https:\/\/segmentfault.com\/a\/1190000007560884\" target=\"_blank\" rel=\"noopener\">segmentfault<\/a>\u00a0\u4e13\u680f.<\/p>\n<p>\u6839\u636e Wiki \u5bf9 Zero-copy \u7684\u5b9a\u4e49:<\/p>\n<blockquote><p>&#8220;Zero-copy&#8221; describes computer operations in which the CPU does not perform the task of copying data from one memory area to another. This is frequently used to save CPU cycles and memory bandwidth when transmitting a file over a network.<\/p><\/blockquote>\n<p>\u5373\u6240\u8c13\u7684\u00a0<code>Zero-copy<\/code>, \u5c31\u662f\u5728\u64cd\u4f5c\u6570\u636e\u65f6, \u4e0d\u9700\u8981\u5c06\u6570\u636e buffer \u4ece\u4e00\u4e2a\u5185\u5b58\u533a\u57df\u62f7\u8d1d\u5230\u53e6\u4e00\u4e2a\u5185\u5b58\u533a\u57df. \u56e0\u4e3a\u5c11\u4e86\u4e00\u6b21\u5185\u5b58\u7684\u62f7\u8d1d, \u56e0\u6b64 CPU \u7684\u6548\u7387\u5c31\u5f97\u5230\u7684\u63d0\u5347.<\/p>\n<p>\u5728 OS \u5c42\u9762\u4e0a\u7684\u00a0<code>Zero-copy<\/code>\u00a0\u901a\u5e38\u6307\u907f\u514d\u5728\u00a0<code>\u7528\u6237\u6001(User-space)<\/code>\u00a0\u4e0e\u00a0<code>\u5185\u6838\u6001(Kernel-space)<\/code>\u00a0\u4e4b\u95f4\u6765\u56de\u62f7\u8d1d\u6570\u636e. \u4f8b\u5982 Linux \u63d0\u4f9b\u7684\u00a0<code>mmap<\/code>\u00a0\u7cfb\u7edf\u8c03\u7528, \u5b83\u53ef\u4ee5\u5c06\u4e00\u6bb5\u7528\u6237\u7a7a\u95f4\u5185\u5b58\u6620\u5c04\u5230\u5185\u6838\u7a7a\u95f4, \u5f53\u6620\u5c04\u6210\u529f\u540e, \u7528\u6237\u5bf9\u8fd9\u6bb5\u5185\u5b58\u533a\u57df\u7684\u4fee\u6539\u53ef\u4ee5\u76f4\u63a5\u53cd\u6620\u5230\u5185\u6838\u7a7a\u95f4; \u540c\u6837\u5730, \u5185\u6838\u7a7a\u95f4\u5bf9\u8fd9\u6bb5\u533a\u57df\u7684\u4fee\u6539\u4e5f\u76f4\u63a5\u53cd\u6620\u7528\u6237\u7a7a\u95f4. \u6b63\u56e0\u4e3a\u6709\u8fd9\u6837\u7684\u6620\u5c04\u5173\u7cfb, \u6211\u4eec\u5c31\u4e0d\u9700\u8981\u5728\u00a0<code>\u7528\u6237\u6001(User-space)<\/code>\u00a0\u4e0e\u00a0<code>\u5185\u6838\u6001(Kernel-space)<\/code>\u00a0\u4e4b\u95f4\u62f7\u8d1d\u6570\u636e, \u63d0\u9ad8\u4e86\u6570\u636e\u4f20\u8f93\u7684\u6548\u7387.<\/p>\n<p>\u800c\u9700\u8981\u6ce8\u610f\u7684\u662f, Netty \u4e2d\u7684\u00a0<code>Zero-copy<\/code>\u00a0\u4e0e\u4e0a\u9762\u6211\u4eec\u6240\u63d0\u5230\u5230 OS \u5c42\u9762\u4e0a\u7684\u00a0<code>Zero-copy<\/code>\u00a0\u4e0d\u592a\u4e00\u6837, Netty\u7684\u00a0<code>Zero-coyp<\/code>\u5b8c\u5168\u662f\u5728\u7528\u6237\u6001(Java \u5c42\u9762)\u7684, \u5b83\u7684\u00a0<code>Zero-copy<\/code>\u00a0\u7684\u66f4\u591a\u7684\u662f\u504f\u5411\u4e8e\u00a0<code>\u4f18\u5316\u6570\u636e\u64cd\u4f5c<\/code>\u00a0\u8fd9\u6837\u7684\u6982\u5ff5.<\/p>\n<p>Netty \u7684\u00a0<code>Zero-copy<\/code>\u00a0\u4f53\u73b0\u5728\u5982\u4e0b\u51e0\u4e2a\u4e2a\u65b9\u9762:<\/p>\n<ul>\n<li>Netty \u63d0\u4f9b\u4e86\u00a0<code>CompositeByteBuf<\/code>\u00a0\u7c7b, \u5b83\u53ef\u4ee5\u5c06\u591a\u4e2a ByteBuf \u5408\u5e76\u4e3a\u4e00\u4e2a\u903b\u8f91\u4e0a\u7684 ByteBuf, \u907f\u514d\u4e86\u5404\u4e2a ByteBuf \u4e4b\u95f4\u7684\u62f7\u8d1d.<\/li>\n<li>\u901a\u8fc7 wrap \u64cd\u4f5c, \u6211\u4eec\u53ef\u4ee5\u5c06 byte[] \u6570\u7ec4\u3001ByteBuf\u3001ByteBuffer\u7b49\u5305\u88c5\u6210\u4e00\u4e2a Netty ByteBuf \u5bf9\u8c61, \u8fdb\u800c\u907f\u514d\u4e86\u62f7\u8d1d\u64cd\u4f5c.<\/li>\n<li>ByteBuf \u652f\u6301 slice \u64cd\u4f5c, \u56e0\u6b64\u53ef\u4ee5\u5c06 ByteBuf \u5206\u89e3\u4e3a\u591a\u4e2a\u5171\u4eab\u540c\u4e00\u4e2a\u5b58\u50a8\u533a\u57df\u7684 ByteBuf, \u907f\u514d\u4e86\u5185\u5b58\u7684\u62f7\u8d1d.<\/li>\n<li>\u901a\u8fc7\u00a0<code>FileRegion<\/code>\u00a0\u5305\u88c5\u7684<code>FileChannel.tranferTo<\/code>\u00a0\u5b9e\u73b0\u6587\u4ef6\u4f20\u8f93, \u53ef\u4ee5\u76f4\u63a5\u5c06\u6587\u4ef6\u7f13\u51b2\u533a\u7684\u6570\u636e\u53d1\u9001\u5230\u76ee\u6807\u00a0<code>Channel<\/code>, \u907f\u514d\u4e86\u4f20\u7edf\u901a\u8fc7\u5faa\u73af write \u65b9\u5f0f\u5bfc\u81f4\u7684\u5185\u5b58\u62f7\u8d1d\u95ee\u9898.<\/li>\n<\/ul>\n<p>\u4e0b\u9762\u6211\u4eec\u5c31\u6765\u7b80\u5355\u4e86\u89e3\u4e00\u4e0b\u8fd9\u51e0\u79cd\u5e38\u89c1\u7684\u96f6\u62f7\u8d1d\u64cd\u4f5c.<\/p>\n<p><a name=\"_caption_0\"><\/a><\/p>\n<h2 id=\"\u901a\u8fc7-compositebytebuf-\u5b9e\u73b0\u96f6\u62f7\u8d1d\">\u901a\u8fc7 CompositeByteBuf \u5b9e\u73b0\u96f6\u62f7\u8d1d<\/h2>\n<p>\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4efd\u534f\u8bae\u6570\u636e, \u5b83\u7531\u5934\u90e8\u548c\u6d88\u606f\u4f53\u7ec4\u6210, \u800c\u5934\u90e8\u548c\u6d88\u606f\u4f53\u662f\u5206\u522b\u5b58\u653e\u5728\u4e24\u4e2a ByteBuf \u4e2d\u7684, \u5373:<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_741717\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java plain\">ByteBuf header = ...<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java plain\">ByteBuf body = ...<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>\u6211\u4eec\u5728\u4ee3\u7801\u5904\u7406\u4e2d, \u901a\u5e38\u5e0c\u671b\u5c06 header \u548c body \u5408\u5e76\u4e3a\u4e00\u4e2a ByteBuf, \u65b9\u4fbf\u5904\u7406, \u90a3\u4e48\u901a\u5e38\u7684\u505a\u6cd5\u662f:<\/p>\n<pre><code class=\"hljs\">ByteBuf allBuf = Unpooled.buffer(header.readableBytes() + body.readableBytes());\r\nallBuf.writeBytes(header);\r\nallBuf.writeBytes(body);<\/code><\/pre>\n<p>\u53ef\u4ee5\u770b\u5230, \u6211\u4eec\u5c06 header \u548c body \u90fd\u62f7\u8d1d\u5230\u4e86\u65b0\u7684 allBuf \u4e2d\u4e86, \u8fd9\u65e0\u5f62\u4e2d\u589e\u52a0\u4e86\u4e24\u6b21\u989d\u5916\u7684\u6570\u636e\u62f7\u8d1d\u64cd\u4f5c\u4e86.<\/p>\n<p>\u90a3\u4e48\u6709\u6ca1\u6709\u66f4\u52a0\u9ad8\u6548\u4f18\u96c5\u7684\u65b9\u5f0f\u5b9e\u73b0\u76f8\u540c\u7684\u76ee\u7684\u5462? \u6211\u4eec\u6765\u770b\u4e00\u4e0b\u00a0<code>CompositeByteBuf<\/code>\u00a0\u662f\u5982\u4f55\u5b9e\u73b0\u8fd9\u6837\u7684\u9700\u6c42\u7684\u5427.<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_540469\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java plain\">ByteBuf header = ...<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java plain\">ByteBuf body = ...<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java plain\">CompositeByteBuf compositeByteBuf = Unpooled.compositeBuffer();<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java plain\">compositeByteBuf.addComponents(<\/code><code class=\"java keyword\">true<\/code><code class=\"java plain\">, header, body);<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>\u4e0a\u9762\u4ee3\u7801\u4e2d, \u6211\u4eec\u5b9a\u4e49\u4e86\u4e00\u4e2a\u00a0<code>CompositeByteBuf<\/code>\u00a0\u5bf9\u8c61, \u7136\u540e\u8c03\u7528<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_850781\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java plain\">CompositeByteBuf addComponents(<\/code><code class=\"java keyword\">boolean<\/code>\u00a0<code class=\"java plain\">increaseWriterIndex, ByteBuf... buffers) {<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java plain\">...<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>\u65b9\u6cd5\u5c06\u00a0<code>header<\/code>\u00a0\u4e0e\u00a0<code>body<\/code>\u00a0\u5408\u5e76\u4e3a\u4e00\u4e2a\u903b\u8f91\u4e0a\u7684 ByteBuf, \u5373:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/images2015.cnblogs.com\/blog\/1006163\/201611\/1006163-20161122125123065-1400680861.png\" \/><\/p>\n<p><code>\u4e0d\u8fc7\u9700\u8981\u6ce8\u610f\u7684\u662f, \u867d\u7136\u770b\u8d77\u6765 CompositeByteBuf \u662f\u7531\u4e24\u4e2a ByteBuf \u7ec4\u5408\u800c\u6210\u7684, \u4e0d\u8fc7\u5728 CompositeByteBuf \u5185\u90e8, \u8fd9\u4e24\u4e2a ByteBuf \u90fd\u662f\u5355\u72ec\u5b58\u5728\u7684, CompositeByteBuf \u53ea\u662f\u903b\u8f91\u4e0a\u662f\u4e00\u4e2a\u6574\u4f53.<\/code><\/p>\n<p>\u4e0a\u9762\u00a0<code>CompositeByteBuf<\/code>\u00a0\u4ee3\u7801\u8fd8\u4ee5\u4e00\u4e2a\u5730\u65b9\u503c\u5f97\u6ce8\u610f\u7684\u662f, \u6211\u4eec\u8c03\u7528\u00a0<code>addComponents(boolean increaseWriterIndex, ByteBuf... buffers)<\/code>\u00a0\u6765\u6dfb\u52a0\u4e24\u4e2a ByteBuf, \u5176\u4e2d\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u00a0<code>true<\/code>, \u8868\u793a\u5f53\u6dfb\u52a0\u65b0\u7684 ByteBuf \u65f6, \u81ea\u52a8\u9012\u589e CompositeByteBuf \u7684\u00a0<code>writeIndex<\/code>.<br \/>\n\u5982\u679c\u6211\u4eec\u8c03\u7528\u7684\u662f<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_921859\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java plain\">compositeByteBuf.addComponents(header, body);<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>\u90a3\u4e48\u5176\u5b9e\u00a0<code>compositeByteBuf<\/code>\u00a0\u7684\u00a0<code>writeIndex<\/code>\u00a0\u4ecd\u7136\u662f0, \u56e0\u6b64\u6b64\u65f6\u6211\u4eec\u5c31\u4e0d\u53ef\u80fd\u4ece\u00a0<code>compositeByteBuf<\/code>\u00a0\u4e2d\u8bfb\u53d6\u5230\u6570\u636e, \u8fd9\u4e00\u70b9\u5e0c\u671b\u5927\u5bb6\u8981\u7279\u522b\u6ce8\u610f.<\/p>\n<p>\u9664\u4e86\u4e0a\u9762\u76f4\u63a5\u4f7f\u7528\u00a0<code>CompositeByteBuf<\/code>\u00a0\u7c7b\u5916, \u6211\u4eec\u8fd8\u53ef\u4ee5\u4f7f\u7528\u00a0<code>Unpooled.wrappedBuffer<\/code>\u00a0\u65b9\u6cd5, \u5b83\u5e95\u5c42\u5c01\u88c5\u4e86\u00a0<code>CompositeByteBuf<\/code>\u00a0\u64cd\u4f5c, \u56e0\u6b64\u4f7f\u7528\u8d77\u6765\u66f4\u52a0\u65b9\u4fbf:<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_590837\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java plain\">ByteBuf header = ...<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java plain\">ByteBuf body = ...<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java plain\">ByteBuf allByteBuf = Unpooled.wrappedBuffer(header, body);<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p><a name=\"_caption_1\"><\/a><\/p>\n<h2 id=\"\u901a\u8fc7-wrap-\u64cd\u4f5c\u5b9e\u73b0\u96f6\u62f7\u8d1d\">\u901a\u8fc7 wrap \u64cd\u4f5c\u5b9e\u73b0\u96f6\u62f7\u8d1d<\/h2>\n<p>\u4f8b\u5982\u6211\u4eec\u6709\u4e00\u4e2a byte \u6570\u7ec4, \u6211\u4eec\u5e0c\u671b\u5c06\u5b83\u8f6c\u6362\u4e3a\u4e00\u4e2a ByteBuf \u5bf9\u8c61, \u4ee5\u4fbf\u4e8e\u540e\u7eed\u7684\u64cd\u4f5c, \u90a3\u4e48\u4f20\u7edf\u7684\u505a\u6cd5\u662f\u5c06\u6b64 byte \u6570\u7ec4\u62f7\u8d1d\u5230 ByteBuf \u4e2d, \u5373:<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_239693\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">byte<\/code><code class=\"java plain\">[] bytes = ...<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java plain\">ByteBuf byteBuf = Unpooled.buffer();<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java plain\">byteBuf.writeBytes(bytes);<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>\u663e\u7136\u8fd9\u6837\u7684\u65b9\u5f0f\u4e5f\u662f\u6709\u4e00\u4e2a\u989d\u5916\u7684\u62f7\u8d1d\u64cd\u4f5c\u7684, \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 Unpooled \u7684\u76f8\u5173\u65b9\u6cd5, \u5305\u88c5\u8fd9\u4e2a byte \u6570\u7ec4, \u751f\u6210\u4e00\u4e2a\u65b0\u7684 ByteBuf \u5b9e\u4f8b, \u800c\u4e0d\u9700\u8981\u8fdb\u884c\u62f7\u8d1d\u64cd\u4f5c. \u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u4ee5\u6539\u4e3a:<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_836930\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">byte<\/code><code class=\"java plain\">[] bytes = ...<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java plain\">ByteBuf byteBuf = Unpooled.wrappedBuffer(bytes);<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>\u53ef\u4ee5\u770b\u5230, \u6211\u4eec\u901a\u8fc7\u00a0<code>Unpooled.wrappedBuffer<\/code>\u00a0\u65b9\u6cd5\u6765\u5c06 bytes \u5305\u88c5\u6210\u4e3a\u4e00\u4e2a UnpooledHeapByteBuf \u5bf9\u8c61, \u800c\u5728\u5305\u88c5\u7684\u8fc7\u7a0b\u4e2d, \u662f\u4e0d\u4f1a\u6709\u62f7\u8d1d\u64cd\u4f5c\u7684. \u5373\u6700\u540e\u6211\u4eec\u751f\u6210\u7684\u751f\u6210\u7684 ByteBuf \u5bf9\u8c61\u662f\u548c bytes \u6570\u7ec4\u5171\u7528\u4e86\u540c\u4e00\u4e2a\u5b58\u50a8\u7a7a\u95f4, \u5bf9 bytes \u7684\u4fee\u6539\u4e5f\u4f1a\u53cd\u6620\u5230 ByteBuf \u5bf9\u8c61\u4e2d.<\/p>\n<p>Unpooled \u5de5\u5177\u7c7b\u8fd8\u63d0\u4f9b\u4e86\u5f88\u591a\u91cd\u8f7d\u7684 wrappedBuffer \u65b9\u6cd5:<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_222866\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1\">8<\/div>\n<div class=\"line number9 index8 alt2\">9<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java keyword\">static<\/code>\u00a0<code class=\"java plain\">ByteBuf wrappedBuffer(<\/code><code class=\"java keyword\">byte<\/code><code class=\"java plain\">[] array)<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java keyword\">static<\/code>\u00a0<code class=\"java plain\">ByteBuf wrappedBuffer(<\/code><code class=\"java keyword\">byte<\/code><code class=\"java plain\">[] array, <\/code><code class=\"java keyword\">int<\/code>\u00a0<code class=\"java plain\">offset, <\/code><code class=\"java keyword\">int<\/code>\u00a0<code class=\"java plain\">length)<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java keyword\">static<\/code>\u00a0<code class=\"java plain\">ByteBuf wrappedBuffer(ByteBuffer buffer)<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java keyword\">static<\/code>\u00a0<code class=\"java plain\">ByteBuf wrappedBuffer(ByteBuf buffer)<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java keyword\">static<\/code>\u00a0<code class=\"java plain\">ByteBuf wrappedBuffer(<\/code><code class=\"java keyword\">byte<\/code><code class=\"java plain\">[]... arrays)<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java keyword\">static<\/code>\u00a0<code class=\"java plain\">ByteBuf wrappedBuffer(ByteBuf... buffers)<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java keyword\">static<\/code>\u00a0<code class=\"java plain\">ByteBuf wrappedBuffer(ByteBuffer... buffers)<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java keyword\">static<\/code>\u00a0<code class=\"java plain\">ByteBuf wrappedBuffer(<\/code><code class=\"java keyword\">int<\/code>\u00a0<code class=\"java plain\">maxNumComponents, <\/code><code class=\"java keyword\">byte<\/code><code class=\"java plain\">[]... arrays)<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java keyword\">static<\/code>\u00a0<code class=\"java plain\">ByteBuf wrappedBuffer(<\/code><code class=\"java keyword\">int<\/code>\u00a0<code class=\"java plain\">maxNumComponents, ByteBuf... buffers)<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java keyword\">static<\/code>\u00a0<code class=\"java plain\">ByteBuf wrappedBuffer(<\/code><code class=\"java keyword\">int<\/code>\u00a0<code class=\"java plain\">maxNumComponents, ByteBuffer... buffers)<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>\u8fd9\u4e9b\u65b9\u6cd5\u53ef\u4ee5\u5c06\u4e00\u4e2a\u6216\u591a\u4e2a buffer \u5305\u88c5\u4e3a\u4e00\u4e2a ByteBuf \u5bf9\u8c61, \u4ece\u800c\u907f\u514d\u4e86\u62f7\u8d1d\u64cd\u4f5c.<\/p>\n<p><a name=\"_caption_2\"><\/a><\/p>\n<h2 id=\"\u901a\u8fc7-slice-\u64cd\u4f5c\u5b9e\u73b0\u96f6\u62f7\u8d1d\">\u901a\u8fc7 slice \u64cd\u4f5c\u5b9e\u73b0\u96f6\u62f7\u8d1d<\/h2>\n<p>slice \u64cd\u4f5c\u548c wrap \u64cd\u4f5c\u521a\u597d\u76f8\u53cd,\u00a0<code>Unpooled.wrappedBuffer<\/code>\u00a0\u53ef\u4ee5\u5c06\u591a\u4e2a ByteBuf \u5408\u5e76\u4e3a\u4e00\u4e2a, \u800c slice \u64cd\u4f5c\u53ef\u4ee5\u5c06\u4e00\u4e2a ByteBuf\u00a0<code>\u5207\u7247<\/code>\u00a0\u4e3a\u591a\u4e2a\u5171\u4eab\u4e00\u4e2a\u5b58\u50a8\u533a\u57df\u7684 ByteBuf \u5bf9\u8c61.<br \/>\nByteBuf \u63d0\u4f9b\u4e86\u4e24\u4e2a slice \u64cd\u4f5c\u65b9\u6cd5:<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_956498\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java plain\">ByteBuf slice();<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java plain\">ByteBuf slice(<\/code><code class=\"java keyword\">int<\/code>\u00a0<code class=\"java plain\">index, <\/code><code class=\"java keyword\">int<\/code>\u00a0<code class=\"java plain\">length);<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>\u4e0d\u5e26\u53c2\u6570\u7684\u00a0<code>slice<\/code>\u00a0\u65b9\u6cd5\u7b49\u540c\u4e8e\u00a0<code>buf.slice(buf.readerIndex(), buf.readableBytes())<\/code>\u00a0\u8c03\u7528, \u5373\u8fd4\u56de buf \u4e2d\u53ef\u8bfb\u90e8\u5206\u7684\u5207\u7247. \u800c\u00a0<code>slice(int index, int length)<\/code>\u00a0\u65b9\u6cd5\u76f8\u5bf9\u5c31\u6bd4\u8f83\u7075\u6d3b\u4e86, \u6211\u4eec\u53ef\u4ee5\u8bbe\u7f6e\u4e0d\u540c\u7684\u53c2\u6570\u6765\u83b7\u53d6\u5230 buf \u7684\u4e0d\u540c\u533a\u57df\u7684\u5207\u7247.<\/p>\n<p>\u4e0b\u9762\u7684\u4f8b\u5b50\u5c55\u793a\u4e86\u00a0<code>ByteBuf.slice<\/code>\u00a0\u65b9\u6cd5\u7684\u7b80\u5355\u7528\u6cd5:<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_917404\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java plain\">ByteBuf byteBuf = ...<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java plain\">ByteBuf header = byteBuf.slice(<\/code><code class=\"java value\">0<\/code><code class=\"java plain\">, <\/code><code class=\"java value\">5<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java plain\">ByteBuf body = byteBuf.slice(<\/code><code class=\"java value\">5<\/code><code class=\"java plain\">, <\/code><code class=\"java value\">10<\/code><code class=\"java plain\">);<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>\u7528\u00a0<code>slice<\/code>\u00a0\u65b9\u6cd5\u4ea7\u751f header \u548c body \u7684\u8fc7\u7a0b\u662f\u6ca1\u6709\u62f7\u8d1d\u64cd\u4f5c\u7684, header \u548c body \u5bf9\u8c61\u5728\u5185\u90e8\u5176\u5b9e\u662f\u5171\u4eab\u4e86 byteBuf \u5b58\u50a8\u7a7a\u95f4\u7684\u4e0d\u540c\u90e8\u5206\u800c\u5df2. \u5373:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/images2015.cnblogs.com\/blog\/1006163\/201611\/1006163-20161122125113893-136149474.png\" \/><\/p>\n<p><a name=\"_caption_3\"><\/a><\/p>\n<h2 id=\"\u901a\u8fc7-fileregion-\u5b9e\u73b0\u96f6\u62f7\u8d1d\">\u901a\u8fc7 FileRegion \u5b9e\u73b0\u96f6\u62f7\u8d1d<\/h2>\n<p>Netty \u4e2d\u4f7f\u7528 FileRegion \u5b9e\u73b0\u6587\u4ef6\u4f20\u8f93\u7684\u96f6\u62f7\u8d1d, \u4e0d\u8fc7\u5728\u5e95\u5c42 FileRegion \u662f\u4f9d\u8d56\u4e8e Java NIO\u00a0<code>FileChannel.transfer<\/code>\u00a0\u7684\u96f6\u62f7\u8d1d\u529f\u80fd.<\/p>\n<p>\u9996\u5148\u6211\u4eec\u4ece\u6700\u57fa\u7840\u7684 Java IO \u5f00\u59cb\u5427. \u5047\u8bbe\u6211\u4eec\u5e0c\u671b\u5b9e\u73b0\u4e00\u4e2a\u6587\u4ef6\u62f7\u8d1d\u7684\u529f\u80fd, \u90a3\u4e48\u4f7f\u7528\u4f20\u7edf\u7684\u65b9\u5f0f, \u6211\u4eec\u6709\u5982\u4e0b\u5b9e\u73b0:<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_973195\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1\">8<\/div>\n<div class=\"line number9 index8 alt2\">9<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java keyword\">static<\/code>\u00a0<code class=\"java keyword\">void<\/code>\u00a0<code class=\"java plain\">copyFile(String srcFile, String destFile) <\/code><code class=\"java keyword\">throws<\/code>\u00a0<code class=\"java plain\">Exception {<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">byte<\/code><code class=\"java plain\">[] temp = <\/code><code class=\"java keyword\">new<\/code>\u00a0<code class=\"java keyword\">byte<\/code><code class=\"java plain\">[<\/code><code class=\"java value\">1024<\/code><code class=\"java plain\">];<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">FileInputStream in = <\/code><code class=\"java keyword\">new<\/code>\u00a0<code class=\"java plain\">FileInputStream(srcFile);<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">FileOutputStream out = <\/code><code class=\"java keyword\">new<\/code>\u00a0<code class=\"java plain\">FileOutputStream(destFile);<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">int<\/code>\u00a0<code class=\"java plain\">length;<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">while<\/code>\u00a0<code class=\"java plain\">((length = in.read(temp)) != -<\/code><code class=\"java value\">1<\/code><code class=\"java plain\">) {<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">out.write(temp, <\/code><code class=\"java value\">0<\/code><code class=\"java plain\">, length);<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">in.close();<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">out.close();<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>\u4e0a\u9762\u662f\u4e00\u4e2a\u5178\u578b\u7684\u8bfb\u5199\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u4ee3\u7801\u5b9e\u73b0\u4e86. \u4e0d\u7528\u6211\u8bf4, \u5927\u5bb6\u80af\u5b9a\u90fd\u77e5\u9053, \u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\u4e0d\u65ad\u4e2d\u6e90\u6587\u4ef6\u4e2d\u8bfb\u53d6\u5b9a\u957f\u6570\u636e\u5230 temp \u6570\u7ec4\u4e2d, \u7136\u540e\u518d\u5c06 temp \u4e2d\u7684\u5185\u5bb9\u5199\u5165\u76ee\u7684\u6587\u4ef6, \u8fd9\u6837\u7684\u62f7\u8d1d\u64cd\u4f5c\u5bf9\u4e8e\u5c0f\u6587\u4ef6\u5012\u662f\u6ca1\u6709\u592a\u5927\u7684\u5f71\u54cd, \u4f46\u662f\u5982\u679c\u6211\u4eec\u9700\u8981\u62f7\u8d1d\u5927\u6587\u4ef6\u65f6, \u9891\u7e41\u7684\u5185\u5b58\u62f7\u8d1d\u64cd\u4f5c\u5c31\u6d88\u8017\u5927\u91cf\u7684\u7cfb\u7edf\u8d44\u6e90\u4e86.<br \/>\n\u4e0b\u9762\u6211\u4eec\u6765\u770b\u4e00\u4e0b\u4f7f\u7528 Java NIO \u7684\u00a0<code>FileChannel<\/code>\u00a0\u662f\u5982\u4f55\u5b9e\u73b0\u96f6\u62f7\u8d1d\u7684:<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_485371\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1\">8<\/div>\n<div class=\"line number9 index8 alt2\">9<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java keyword\">static<\/code>\u00a0<code class=\"java keyword\">void<\/code>\u00a0<code class=\"java plain\">copyFileWithFileChannel(String srcFileName, String destFileName) <\/code><code class=\"java keyword\">throws<\/code>\u00a0<code class=\"java plain\">Exception {<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">RandomAccessFile srcFile = <\/code><code class=\"java keyword\">new<\/code>\u00a0<code class=\"java plain\">RandomAccessFile(srcFileName, <\/code><code class=\"java string\">\"r\"<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">FileChannel srcFileChannel = srcFile.getChannel();<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">RandomAccessFile destFile = <\/code><code class=\"java keyword\">new<\/code>\u00a0<code class=\"java plain\">RandomAccessFile(destFileName, <\/code><code class=\"java string\">\"rw\"<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">FileChannel destFileChannel = destFile.getChannel();<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">long<\/code>\u00a0<code class=\"java plain\">position = <\/code><code class=\"java value\">0<\/code><code class=\"java plain\">;<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">long<\/code>\u00a0<code class=\"java plain\">count = srcFileChannel.size();<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">srcFileChannel.transferTo(position, count, destFileChannel);<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>\u53ef\u4ee5\u770b\u5230, \u4f7f\u7528\u4e86\u00a0<code>FileChannel<\/code>\u00a0\u540e, \u6211\u4eec\u5c31\u53ef\u4ee5\u76f4\u63a5\u5c06\u6e90\u6587\u4ef6\u7684\u5185\u5bb9\u76f4\u63a5\u62f7\u8d1d(<code>transferTo<\/code>) \u5230\u76ee\u7684\u6587\u4ef6\u4e2d, \u800c\u4e0d\u9700\u8981\u989d\u5916\u501f\u52a9\u4e00\u4e2a\u4e34\u65f6 buffer, \u907f\u514d\u4e86\u4e0d\u5fc5\u8981\u7684\u5185\u5b58\u64cd\u4f5c.<\/p>\n<p>\u6709\u4e86\u4e0a\u9762\u7684\u4e00\u4e9b\u7406\u8bba\u77e5\u8bc6, \u6211\u4eec\u6765\u770b\u4e00\u4e0b\u5728 Netty \u4e2d\u662f\u600e\u4e48\u4f7f\u7528\u00a0<code>FileRegion<\/code>\u00a0\u6765\u5b9e\u73b0\u96f6\u62f7\u8d1d\u4f20\u8f93\u4e00\u4e2a\u6587\u4ef6\u7684:<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_79118\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1\">8<\/div>\n<div class=\"line number9 index8 alt2\">9<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<div class=\"line number18 index17 alt1\">18<\/div>\n<div class=\"line number19 index18 alt2\">19<\/div>\n<div class=\"line number20 index19 alt1\">20<\/div>\n<div class=\"line number21 index20 alt2\">21<\/div>\n<div class=\"line number22 index21 alt1\">22<\/div>\n<div class=\"line number23 index22 alt2\">23<\/div>\n<div class=\"line number24 index23 alt1\">24<\/div>\n<div class=\"line number25 index24 alt2\">25<\/div>\n<div class=\"line number26 index25 alt1\">26<\/div>\n<div class=\"line number27 index26 alt2\">27<\/div>\n<div class=\"line number28 index27 alt1\">28<\/div>\n<div class=\"line number29 index28 alt2\">29<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java color1\">@Override<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java keyword\">public<\/code>\u00a0<code class=\"java keyword\">void<\/code>\u00a0<code class=\"java plain\">channelRead0(ChannelHandlerContext ctx, String msg) <\/code><code class=\"java keyword\">throws<\/code>\u00a0<code class=\"java plain\">Exception {<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">RandomAccessFile raf = <\/code><code class=\"java keyword\">null<\/code><code class=\"java plain\">;<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">long<\/code>\u00a0<code class=\"java plain\">length = -<\/code><code class=\"java value\">1<\/code><code class=\"java plain\">;<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">try<\/code>\u00a0<code class=\"java plain\">{<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java comments\">\/\/ 1. \u901a\u8fc7 RandomAccessFile \u6253\u5f00\u4e00\u4e2a\u6587\u4ef6.<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">raf = <\/code><code class=\"java keyword\">new<\/code>\u00a0<code class=\"java plain\">RandomAccessFile(msg, <\/code><code class=\"java string\">\"r\"<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">length = raf.length();<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">} <\/code><code class=\"java keyword\">catch<\/code>\u00a0<code class=\"java plain\">(Exception e) {<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">ctx.writeAndFlush(<\/code><code class=\"java string\">\"ERR: \"<\/code>\u00a0<code class=\"java plain\">+ e.getClass().getSimpleName() + <\/code><code class=\"java string\">\": \"<\/code>\u00a0<code class=\"java plain\">+ e.getMessage() + <\/code><code class=\"java string\">'\\n'<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">return<\/code><code class=\"java plain\">;<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">} <\/code><code class=\"java keyword\">finally<\/code>\u00a0<code class=\"java plain\">{<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">if<\/code>\u00a0<code class=\"java plain\">(length &lt; <\/code><code class=\"java value\">0<\/code>\u00a0<code class=\"java plain\">&amp;&amp; raf != <\/code><code class=\"java keyword\">null<\/code><code class=\"java plain\">) {<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">raf.close();<\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number17 index16 alt2\"><\/div>\n<div class=\"line number18 index17 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">ctx.write(<\/code><code class=\"java string\">\"OK: \"<\/code>\u00a0<code class=\"java plain\">+ raf.length() + <\/code><code class=\"java string\">'\\n'<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number19 index18 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">if<\/code>\u00a0<code class=\"java plain\">(ctx.pipeline().get(SslHandler.<\/code><code class=\"java keyword\">class<\/code><code class=\"java plain\">) == <\/code><code class=\"java keyword\">null<\/code><code class=\"java plain\">) {<\/code><\/div>\n<div class=\"line number20 index19 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java comments\">\/\/ SSL not enabled - can use zero-copy file transfer.<\/code><\/div>\n<div class=\"line number21 index20 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java comments\">\/\/ 2. \u8c03\u7528 raf.getChannel() \u83b7\u53d6\u4e00\u4e2a FileChannel.<\/code><\/div>\n<div class=\"line number22 index21 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java comments\">\/\/ 3. \u5c06 FileChannel \u5c01\u88c5\u6210\u4e00\u4e2a DefaultFileRegion<\/code><\/div>\n<div class=\"line number23 index22 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">ctx.write(<\/code><code class=\"java keyword\">new<\/code>\u00a0<code class=\"java plain\">DefaultFileRegion(raf.getChannel(), <\/code><code class=\"java value\">0<\/code><code class=\"java plain\">, length));<\/code><\/div>\n<div class=\"line number24 index23 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">} <\/code><code class=\"java keyword\">else<\/code>\u00a0<code class=\"java plain\">{<\/code><\/div>\n<div class=\"line number25 index24 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java comments\">\/\/ SSL enabled - cannot use zero-copy file transfer.<\/code><\/div>\n<div class=\"line number26 index25 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">ctx.write(<\/code><code class=\"java keyword\">new<\/code>\u00a0<code class=\"java plain\">ChunkedFile(raf));<\/code><\/div>\n<div class=\"line number27 index26 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number28 index27 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">ctx.writeAndFlush(<\/code><code class=\"java string\">\"\\n\"<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number29 index28 alt2\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>\u4e0a\u9762\u7684\u4ee3\u7801\u662f Netty \u7684\u4e00\u4e2a\u4f8b\u5b50, \u5176\u6e90\u7801\u5728\u00a0<strong>netty\/example\/src\/main\/java\/io\/netty\/example\/file\/FileServerHandler.java<\/strong><br \/>\n\u53ef\u4ee5\u770b\u5230, \u7b2c\u4e00\u6b65\u662f\u901a\u8fc7\u00a0<code>RandomAccessFile<\/code>\u00a0\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6, \u7136\u540e Netty \u4f7f\u7528\u4e86\u00a0<code>DefaultFileRegion<\/code>\u00a0\u6765\u5c01\u88c5\u4e00\u4e2a\u00a0<code>FileChannel<\/code>\u00a0\u5373:<\/p>\n<div class=\"sourceCode\">\n<div>\n<div id=\"highlighter_687993\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">new<\/code>\u00a0<code class=\"java plain\">DefaultFileRegion(raf.getChannel(), <\/code><code class=\"java value\">0<\/code><code class=\"java plain\">, length)<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>\u5f53\u6709\u4e86 FileRegion \u540e, \u6211\u4eec\u5c31\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7\u5b83\u5c06\u6587\u4ef6\u7684\u5185\u5bb9\u76f4\u63a5\u5199\u5165 Channel \u4e2d, \u800c\u4e0d\u9700\u8981\u50cf\u4f20\u7edf\u7684\u505a\u6cd5: \u62f7\u8d1d\u6587\u4ef6\u5185\u5bb9\u5230\u4e34\u65f6 buffer, \u7136\u540e\u518d\u5c06 buffer \u5199\u5165 Channel. \u901a\u8fc7\u8fd9\u6837\u7684\u96f6\u62f7\u8d1d\u64cd\u4f5c, \u65e0\u7591\u5bf9\u4f20\u8f93\u5927\u6587\u4ef6\u5f88\u6709\u5e2e\u52a9.<\/p>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u5bf9\u4e8e Netty ByteBuf \u7684\u96f6\u62f7<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[],"tags":[118],"class_list":["post-1207","post","type-post","status-publish","format-standard","hentry","tag-02-"],"_links":{"self":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts\/1207","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/comments?post=1207"}],"version-history":[{"count":0,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts\/1207\/revisions"}],"wp:attachment":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/media?parent=1207"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/categories?post=1207"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/tags?post=1207"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}