zoukankan      html  css  js  c++  java
  • java网络---流

    网络操作很大一部分功能就是输入和输出数据。

    简单归纳就是上传和下载文件。文件也是数据的一种载体。

    java对数据的操作归并为流。

    所以对于数据流的操作定义2个基本类。

    java.io.OutputStream

    java.io.InputStream

    一:OutputStream & InputStream

    输出流。也就是写入数据,在这里有个易被忽视的方法:flush。

        public void flush() throws IOException {
        }

    这个方法的作用,我们每次写一个字符到文件或者其他地方是十分冗余的,如果可以,那就有一个缓存,当我数据达到一定量的时候,

    才开始写入的操作。

    所以调用:

     public void write(byte b[], int off, int len) throws IOException 

    不一定会立刻把数据写入到文件中,这个时候如果close,这部分数据就会丢失掉。

    而flush的作用就是,在缓存区,不管数据是否达到一个临界值,强制把数据写入到文件中!

    输入流,与输出流相对的。

    也有很多方法。最重要的当然是read。

    读取单个字符的方式,显然不是很好的一个方式。

        @Override public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
            return IoBridge.read(fd, buffer, byteOffset, byteCount);
        }

    以上就是android里面java/io/FileInputStream.java 读取多个字符的方法。

    由于网络会比较忙,所以通常传输1024字节的内容,可能只收到512个,剩余部分还在传输过程中。

    二:缓冲流

    BufferedInputStream和BufferedOutputStream

    他们会对inputStream & OutputStream做缓存,然后提高传输的性能。

    对于网络传输来说,一次传递1个字节,但是它要包40个字节的头,所以1K的数据会变成41K,

    而如果打包在一次,则只要1K多点的数据就可以,性能显然会差很多。

    @Override
        public synchronized int read() throws IOException {
            // Use local refs since buf and in may be invalidated by an
            // unsynchronized close()
            byte[] localBuf = buf;
            InputStream localIn = in;
            if (localBuf == null || localIn == null) {
                throw streamClosed();
            }
    
            /* Are there buffered bytes available? */
            if (pos >= count && fillbuf(localIn, localBuf) == -1) {
                return -1; /* no, fill buffer */
            }
            // localBuf may have been invalidated by fillbuf
            if (localBuf != buf) {
                localBuf = buf;
                if (localBuf == null) {
                    throw streamClosed();
                }
            }
    
            /* Did filling the buffer fail with -1 (EOF)? */
            if (count - pos > 0) {
                return localBuf[pos++] & 0xFF;
            }
            return -1;
        }

    关键就是fillbuf这个操作,所以read方法每次读取的都是一段字节,而不是依次读取的。

    private int fillbuf(InputStream localIn, byte[] localBuf)
                throws IOException {
            if (markpos == -1 || (pos - markpos >= marklimit)) {
                /* Mark position not set or exceeded readlimit */
                int result = localIn.read(localBuf);
                if (result > 0) {
                    markpos = -1;
                    pos = 0;
                    count = result == -1 ? 0 : result;
                }
                return result;
            }
            if (markpos == 0 && marklimit > localBuf.length) {
                /* Increase buffer size to accommodate the readlimit */
                int newLength = localBuf.length * 2;
                if (newLength > marklimit) {
                    newLength = marklimit;
                }
                byte[] newbuf = new byte[newLength];
                System.arraycopy(localBuf, 0, newbuf, 0, localBuf.length);
                // Reassign buf, which will invalidate any local references
                // FIXME: what if buf was null?
                localBuf = buf = newbuf;
            } else if (markpos > 0) {
                System.arraycopy(localBuf, markpos, localBuf, 0, localBuf.length
                        - markpos);
            }
            /* Set the new position and mark position */
            pos -= markpos;
            count = markpos = 0;
            int bytesread = localIn.read(localBuf, pos, localBuf.length - pos);
            count = bytesread <= 0 ? pos : pos + bytesread;
            return bytesread;
        }

    可以看到fillbuf里面会调用

     int bytesread = localIn.read(localBuf, pos, localBuf.length - pos);

    所以buffer 会把stream放入到一个byte[]的数组里面。

    三:压缩流:

    DeflaterOutputStream
    InflaterInputStream
    GZIPOutputStream
    GZIPInputStream
    ZipOutputStream
    ZipInputStream

    这六个就是java提供的压缩流,他们的读写就是使用read & write方法。

    输出流压缩数据,输入流解压数据。

    四:摘要流

    DigestInputStream,DigestOutputStream

    摘要流的目的,主要是可以验证数据的完整性。

    虽然程序员可以更高效的写出独立的验证算法,但是统一使用以后,可以简化这部分的操作。

    五:阅读器和书写器

    Reader -> BufferedReader     -> LineNumberReader 
           -> InputStreamReader  -> FileReader
    
    Writer -> BufferedWriter
           -> OutputStreamWriter -> FileWriter

    网络传输中有各种不同的字符编码,所以就会需要有一个读写和处理的工具来操作流。

    FileReader & FileWrite是处理文件的,具体的细节就不写了!

  • 相关阅读:
    11
    centos删除安装vsftpd
    linux安装jdk
    linux安装mysql
    关闭opera自动更新
    执行处理程序“System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper”的子请求时出错
    ckeditor3.6.4+ckfinder2.2.2 上传图片到指定目录
    关于android@home的一点想法
    2012书单
    SAP GUI saplogon.ini配置文件的位置
  • 原文地址:https://www.cnblogs.com/deman/p/5067200.html
Copyright © 2011-2022 走看看