Android leverages Okio simplifies processing I/O operations

Source: Internet
Author: User
<span id="Label3"></p><p><p>The Okio library, developed by the Square company, complements Java.io and Java.nio to make it easier and faster to access, store, and process your Data. The base of Okhttp also uses this library as Support. In the development, the use of the library can greatly bring you convenience.</p></p><p><p>currently, the latest version of Okio is 1.6.0,gradle's reference to the following</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs bash"><span class="hljs-string">‘com.squareup.okio:okio:1.6.0‘</span></code></pre></pre><p><p>The Okio has two key interfaces,<strong>Sink</strong> and <strong>Source</strong>, both of which inherit the closeable interface, and Sink can simply be seen as outputstream, Source can be simply seen as Inputstream. Both interfaces support Read-write timeout settings. The structure diagram is as follows</p></p><p><p></p></p><p><p>They each have a sub-class interface that supports buffers, Bufferedsink and bufferedsource, and Bufferedsink has an implementation class realbufferedsink, Bufferedsource has an implementation class realbufferedsource; in addition, sink and source it each have an implementation class that supports GZIP compression gzipsink and Gzipsource , an abstract class with a delegate function Forwardingsink and forwardingsource; Another implementation class is Inflatersource and deflatersink, and these two classes are mainly used for compression, Services for Gzipsink and gzipsource; the overall structure is shown below</p></p><p><p></p></p><p><p>Bufferedsink defines a series of methods for writing buffers, such as the Write method writes a byte array, WriteUtf8 writes a string, and some columns of writebyte,writestring,writeshort,writeint, Writelong,writedecimallong and other methods;</p></p><p><p>Bufferedsource defines the method and Bufferedsink very similar, but one is to write a read, basically is one by one corresponding, such as readutf8,readbyte,readstring,readshort, Readint and so On. Both of the methods in the interface are interested in the point source to see on it.</p></p><p><p>The implementation classes Realbufferedsink and Realbufferedsource of the two buffer-supported interfaces are implemented by wrapping a sink+buffer or source+buffer. As shown</p></p><p><p></p></p><p><p>Take Realbufferedsink for example, the actual call to write a series of methods, are directly to the member variable buffer operation, when the write buffer succeeds, the final call a method to write the contents of buffer into the sink, Let's take a look at it in a random way.</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs java"> <span class="hljs-keyword">public</span><span class="hljs-title">writeLong</span>(<span class="hljs-keyword">long</span><span class="hljs-keyword">throws</span> IOException { <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.closed) { <span class="hljs-keyword">throw</span><span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"closed"</span>); <span class="hljs-keyword">else</span> { <span class="hljs-keyword">this</span>.buffer.writeLong(v); <span class="hljs-keyword">return</span><span class="hljs-keyword">this</span>.emitCompleteSegments(); } }</code></pre></pre><p><p>As you can see, you will first determine if the closed member variable is marked closed, throw an exception if it has been closed, otherwise write the content to buffer, call a emitcompletesegments method after the write is completed, and do what in the method, yes, is to write the contents of the buffer into the sink member variable, and then return itself.</p></p><pre class="prettyprint"><code class=" hljs java"><code class="hljs java"> <span class="hljs-keyword">public </span> bufferedsink <span class="hljs-title"> Emitcompletesegments </span> () <span class="hljs-keyword">throws </span> ioexception {<span class="hljs-keyword">if </span> (<span class="hljs-keyword">this </span>. closed) {<span class="hljs-keyword">throw </span> <span class="h Ljs-keyword ">new </span> illegalstateexception (<span class=" hljs-string ">" closed "</span>); } <span class="hljs-keyword">else </span> {<span class="hljs-keyword">long </span> byteCount = <span class="hljs -keyword ">this </span>. Buffer.completesegmentbytecount (); <span class="hljs-keyword">if </span> (byteCount > <span class="hljs-number">0 </span> L) {<span class="hljs-keyword">this </span>. sink.write (<span class="hljs-keyword">this </span>. buffer, Bytecoun t); } <span class="hljs-keyword">return </span> <span class="hljs-keyword">this </span>; } }</code></code></pre><p><p>All the methods inside the two implementation classes are similar and are not unfolded here.</p></p><p><p>And all this behind is a class called Buffer that supports buffers, which are the implementation classes of Bufferedsink and bufferedsource, so it can be used both to read data and to write Data. The internal use of a segment and segmentpool, maintaining a linked list, its recycling mechanism and the use of the message in Android is the same mechanism.</p></p><pre class="prettyprint"><code class=" hljs d"><span class="hljs-keyword"><span class="hljs-keyword">Final</span></span> <span class="hljs-keyword"><span class="hljs-keyword">class</span></span>Segmentpool {<span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Final</span></span> <span class="hljs-built_in"><span class="hljs-built_in">Long</span></span>Max_size =<span class="hljs-number"><span class="hljs-number">65536L</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">Static</span></span>Segment next;<span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-built_in"><span class="hljs-built_in">Long</span></span>byteCount;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Segmentpool () {}<span class="hljs-keyword"><span class="hljs-keyword">Static</span></span>Segment take () {Class var0 = Segmentpool.<span class="hljs-keyword"><span class="hljs-keyword">class</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">synchronized</span></span>(segmentpool.<span class="hljs-keyword"><span class="hljs-keyword">class</span></span>) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(next! =<span class="hljs-literal"><span class="hljs-literal">NULL</span></span>{Segment result = next; Next = result.next; Result.next =<span class="hljs-literal"><span class="hljs-literal">NULL</span></span>; byteCount-=<span class="hljs-number"><span class="hljs-number">2048L</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>Result } }<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Segment (); }<span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span>Recycle (Segment Segment) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(segment.next = =<span class="hljs-literal"><span class="hljs-literal">NULL</span></span>&& Segment.prev = =<span class="hljs-literal"><span class="hljs-literal">NULL</span></span>) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(!segment.<span class="hljs-keyword"><span class="hljs-keyword">shared</span></span>) {Class var1 = Segmentpool.<span class="hljs-keyword"><span class="hljs-keyword">class</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">synchronized</span></span>(segmentpool.<span class="hljs-keyword"><span class="hljs-keyword">class</span></span>) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(byteCount +<span class="hljs-number"><span class="hljs-number">2048L</span></span><=<span class="hljs-number"><span class="hljs-number">65536L</span></span>) {byteCount + =<span class="hljs-number"><span class="hljs-number">2048L</span></span>; Segment.next = next; Segment.pos = Segment.limit =<span class="hljs-number"><span class="hljs-number">0</span></span>; Next = segment; } } } }<span class="hljs-keyword"><span class="hljs-keyword">Else</span></span>{<span class="hljs-keyword"><span class="hljs-keyword">Throw</span></span> <span class="hljs-keyword"><span class="hljs-keyword">New</span></span>IllegalArgumentException (); } }}</code></pre><p><p>The inner one member variable next points to the next element of the list, the Take method first determines whether there are any available in the pool, the presence is returned, the new one does not exist, and the recycle is the segment that is no longer used to be thrown back into the Pool. So as to achieve the role of a segment Pool.</p></p><p><p>The class that Okio exposes to external use is the Okio class, which has a number of static methods inside it, including a source for bufferedsource, and a bufferedsink through a sink. This process is simple, we call Okio's buffer method to return what we need, as follows</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs avrasm">Okio<span class="hljs-preprocessor">.buffer</span>(sink)Okio<span class="hljs-preprocessor">.buffer</span>(source)</code></pre></pre><p><p>however, the above two methods need to pass a sink or source, then this sink and source is how to get it. In fact, the method is also Okio in this class. We can call the sink method to get a sink, call the source method to get a source, and the source or destination of the data can be a file, an input or output stream, a socket link, and so On. As follows</p></p><pre class="prettyprint"><pre class="prettyprint"><code class="hljs vhdl">okio.sink (<span class="hljs-keyword">new </span> <span class=" Hljs-keyword ">file </span> (<span class=" hljs-string " " * "< span>)); okio.sink (<span class=" Hljs-keyword ">new </span> fileoutputstream (<span class="hljs-keyword">new </span> <span class="hljs-keyword">file </span> (<span class="hljs-string" , "* * *" < span>)), okio.sink (<span class="hljs-keyword">new </span> Socket ( <span class="hljs-string" "* * *" < span>, <span class="hljs-number">8888 </span>); Okio.source ( <span class="hljs-keyword">new </span> <span class="hljs-keyword">file </span> (<span class="hljs-string"> "* * *" </span>)); O Kio.source (<span class="hljs-keyword">new </span> fileinputstream (<span class="hljs-keyword">new </span> <span class="hljs-keyword">file </span> (<span class="hljs-string"> "* * *" </span>)); Okio.source ( <span class="hljs-keyword">new </span> Socket (<span class="hljs-string" "* * *" < span>, <span class="hljs-number">8888 </span>)); </span></span></span></span></code> </pre></pre><p><p>So you might not be enjoying it, so let's connect it up, now we read a file from the local, read it and then write the content to another File.</p></p><pre class="prettyprint"><code class=" hljs cs"><span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Main</span></span>(string[] Args) {source Source =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>; Bufferedsource Bufferedsource =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{file file =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>File (<span class="hljs-string"><span class="hljs-string">"resources/test.txt"</span></span>); Source = Okio.source (file); Bufferedsource = Okio.buffer (source); String content = Bufferedsource.readutf8 (); System.<span class="hljs-keyword"><span class="hljs-keyword"></span> out</span>. println (content); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(filenotfoundexception E) {e.printstacktrace (); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(ioexception E) {e.printstacktrace (); }<span class="hljs-keyword"><span class="hljs-keyword">finally</span></span>{closequietly (bufferedsource); } Sink Sink =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>; Bufferedsink Bufferedsink =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{File dest =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>File (<span class="hljs-string"><span class="hljs-string">"resources/dest.txt"</span></span>); Sink = Okio.sink (dest); Bufferedsink = Okio.buffer (sink); Bufferedsink.writeutf8 (<span class="hljs-string"><span class="hljs-string">"11111111111"</span></span>); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(filenotfoundexception E) {e.printstacktrace (); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(ioexception E) {e.printstacktrace (); }<span class="hljs-keyword"><span class="hljs-keyword">finally</span></span>{closequietly (bufferedsink); }}<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">closequietly</span></span>(closeable Closeable) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(closeable! =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>) {<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{closeable.close (); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(runtimeexception Rethrown) {<span class="hljs-keyword"><span class="hljs-keyword">Throw</span></span>rethrown; }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(Exception Ignored) { } }}</code></pre><p><p>Perhaps sometimes in a network request, we need to use the functionality of gzip, then we can simply use the GZIP function</p></p><pre class="prettyprint"><code class=" hljs http"><span class="cs"><span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Main</span></span>(string[] Args) {Sink Sink =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>; Bufferedsink Bufferedsink =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>; Gzipsink gzipsink=<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{File dest =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>File (<span class="hljs-string"><span class="hljs-string">"resources/gzip.txt"</span></span>); Sink = Okio.sink (dest); gzipsink=<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Gzipsink (sink); Bufferedsink = Okio.buffer (gzipsink); Bufferedsink.writeutf8 (<span class="hljs-string"><span class="hljs-string">"android vs ios"</span></span>); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(filenotfoundexception E) {e.printstacktrace (); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(ioexception E) {e.printstacktrace (); }<span class="hljs-keyword"><span class="hljs-keyword">finally</span></span>{closequietly (bufferedsink); } Source Source =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>; Bufferedsource Bufferedsource =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>; Gzipsource gzipsource=<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{file file =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>File (<span class="hljs-string"><span class="hljs-string">"resources/gzip.txt"</span></span>); Source = Okio.source (file); Gzipsource=<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Gzipsource (source); Bufferedsource = Okio.buffer (gzipsource); String content = Bufferedsource.readutf8 (); System.<span class="hljs-keyword"><span class="hljs-keyword"></span> out</span>. println (content); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(filenotfoundexception E) {e.printstacktrace (); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(ioexception E) {e.printstacktrace (); }<span class="hljs-keyword"><span class="hljs-keyword">finally</span></span>{closequietly (bufferedsource); }}<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">closequietly</span></span>(closeable Closeable) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(closeable! =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>) {<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{closeable.close (); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(runtimeexception Rethrown) {<span class="hljs-keyword"><span class="hljs-keyword">Throw</span></span>rethrown; }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(Exception Ignored) { } }}</span></code></pre><p><p>The correct way to verify is to see if the file being written is garbled, and whether the original string is Read.</p></p><p><p>Compare the original gzip compression and decompression method, you will find that still a lot of simple</p></p><pre class="prettyprint"><code class=" hljs java"><span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-class"><span class="hljs-class"> <span class="hljs-keyword">class</span> <span class="hljs-title">gziputil</span> {</span></span> <span class="hljs-javadoc"><span class="hljs-javadoc">/** * Gzip Compressed * *<span class="hljs-javadoctag"> @param</span> data *<span class="hljs-javadoctag"> @return</span> </span> */</span> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">byte</span></span>[]<span class="hljs-title"><span class="hljs-title">gzip</span></span>(<span class="hljs-keyword"><span class="hljs-keyword">byte</span></span>[] Data)<span class="hljs-keyword"><span class="hljs-keyword">throws</span></span>Exception {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(data = =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>|| Data.length = =<span class="hljs-number"><span class="hljs-number">0</span></span>) {<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>; } Bytearrayoutputstream out =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Bytearrayoutputstream (); Gzipoutputstream zos; Bufferedinputstream bis =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Bufferedinputstream (<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Bytearrayinputstream (data));<span class="hljs-keyword"><span class="hljs-keyword">byte</span></span>[] buf =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span> <span class="hljs-keyword"><span class="hljs-keyword">byte</span></span>[<span class="hljs-number"><span class="hljs-number"></span> +</span>];<span class="hljs-keyword"><span class="hljs-keyword">int</span></span>Len<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{zos =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Gzipoutputstream (out);<span class="hljs-keyword"><span class="hljs-keyword"></span> while</span>(len = Bis.read (buf))! =-<span class="hljs-number"><span class="hljs-number">1</span></span>) {zos.write (buf,<span class="hljs-number"><span class="hljs-number">0</span></span>, len); Zos.flush (); } bis.close (); Zos.close ();<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>Out.tobytearray (); }<span class="hljs-keyword"><span class="hljs-keyword">finally</span></span>{<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(out! =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>) {<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{out.close (); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(Exception E2) { } } } }<span class="hljs-javadoc"><span class="hljs-javadoc">/** * Gzip Unzip *<span class="hljs-javadoctag"> @param</span> b *<span class="hljs-javadoctag"> @return</span> </span> * *</span> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">byte</span></span>[]<span class="hljs-title"><span class="hljs-title">Ungzip</span></span>(<span class="hljs-keyword"><span class="hljs-keyword">byte</span></span>[] B) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(b = =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>|| B.length = =<span class="hljs-number"><span class="hljs-number">0</span></span>) {<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>; } Bytearrayoutputstream out =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Bytearrayoutputstream (); Bytearrayinputstream in =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Bytearrayinputstream (b);<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{gzipinputstream Gunzip =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Gzipinputstream (in);<span class="hljs-keyword"><span class="hljs-keyword">byte</span></span>[] buffer =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span> <span class="hljs-keyword"><span class="hljs-keyword">byte</span></span>[<span class="hljs-number"><span class="hljs-number"></span> the</span>];<span class="hljs-keyword"><span class="hljs-keyword">int</span></span>N<span class="hljs-keyword"><span class="hljs-keyword"></span> while</span>((n = Gunzip.read (buffer)) >=<span class="hljs-number"><span class="hljs-number">0</span></span>) {out.write (buffer,<span class="hljs-number"><span class="hljs-number">0</span></span>, n); }<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>Out.tobytearray (); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(ioexception E) {LOG.E (wdcore.getinstance (). getconfiguration (). getlogtag (),<span class="hljs-string"><span class="hljs-string">"uncompress error"</span></span>, e); }<span class="hljs-keyword"><span class="hljs-keyword">finally</span></span>{<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(out! =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>) {out.close (); }<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(in! =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>) {in.close (); } }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(Exception E2) { } }<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>; }}</code></pre><p><p>There is also a bytestring class, which can be used to make various changes, it transfers a byte to a string, and this string can be a value of utf8, or it can be a value after base64, or it can be a value of md5, or it can be a value of sha256. In short, it is all kinds of changes, and finally get the value you Want.</p></p><p><p>In short, in the appropriate place to use the Okio this library, will certainly give you the development of a lot of convenience, why not!</p></p> <p><p>Android leverages Okio simplifies processing I/O operations</p></p></span>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.