InputStream、FileInputStream之read()、skip()可靠性加强

原创 2016年05月30日 21:34:21

        有经验java程序猿都知道,java中对输入流的读取往往是不可靠的,例如inputStream.read(buffer,0,1024);并不是每次都能读取到1024个字节,而是最多能够读取1024个字节,jdk源码如下:

public int read(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return 0;
        }


        int c = read();
        if (c == -1) {
            return -1;
        }
        b[off] = (byte)c;


        int i = 1;
        try {
            for (; i < len ; i++) {
                c = read();
                if (c == -1) {
                    break;
                }
                b[off + i] = (byte)c;
            }
        } catch (IOException ee) {
        }
        return i;
    }

可以看到当出现一次IO异常则该次读取结束,提高了性能的同时,其可靠性打了折扣,通常都会使用while循环来从读过的索引位置继续读取,但是有的时候我们要求不使用while循环而就要读到我们需要的字节数,下面通过设置可靠性系数,以牺牲发生IO异常时的性能来提高其可靠性,对jdk源码稍加改造如下:


import java.io.IOException;
import java.io.InputStream;


/**
 * 改善InputStream自带方法的不可靠缺陷
 * @author zhangh-ag
 *
 */
public class InputStreamUtil {

private static native int readBytes(byte b[], int off, int len) throws IOException;

/**
* 改善InputStream自带read方法不可靠的问题
* @param oInputStream 要读取的流
* @param b 接收数组
* @param off 从数组的哪个位置
* @param len 读的长度
* @param reReadMaxCount 可靠系数(默认同原生InputStream)
* @return
*/
public static int read(InputStream oInputStream, byte b[], int off, int len, int reReadMaxCount) throws IOException {
if (b == null) {
            throw new NullPointerException();
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return 0;
        }

if (reReadMaxCount <= 0) {
reReadMaxCount = 1;
}



        int c = -1;
try {
c = oInputStream.read();
} catch (IOException e) {
e.printStackTrace();
}
        if (c == -1) {
            return -1;
        }
        b[off] = (byte)c;


        int i = 1;
        int nCount = 1;
    while (i < len && nCount <= reReadMaxCount) {
    try {
c = oInputStream.read();
if (c == -1) {
               break;
           }
           b[off + i] = (byte)c;
           i++;
} catch (IOException e) {
nCount++;
}
    }
   
    if (nCount > reReadMaxCount && reReadMaxCount != 1) {
    throw new IOException();
    }
   
        return i;
}

/**
* 改善InputStream自带skip方法不可靠的问题
* @param oInputStream 要读取的流
* @param n 要跳过的长度
* @param reReadMaxCount  可靠系数(默认同原生InputStream)
* @return
* @throws IOException
*/
public static long skip(InputStream oInputStream, long n, int reReadMaxCount) throws IOException {
long remaining = n;
        int nr = 0;


        if (n <= 0) {
            return 0;
        }
        
        int nCount = 1;
        if (reReadMaxCount <= 0) {
        reReadMaxCount = 1;
        }


        int size = (int)remaining;
        byte[] skipBuffer = new byte[size];
        while (remaining > 0 && nCount <= reReadMaxCount) {
            try {
nr = oInputStream.read(skipBuffer, nr, (int)Math.min(size, remaining));
} catch (IOException e) {
nCount++;
}
            if (nr < 0) {
                break;
            }
            remaining -= nr;
        }
        
        if (nCount > reReadMaxCount && reReadMaxCount != 1) {
    throw new IOException();
    }


        return n - remaining;
}


}




package com.glodon.util;


import java.io.FileInputStream;
import java.io.IOException;


/**
 * 改善FileInputStream自带方法的不可靠缺陷
 * @author zhangh-ag
 *
 */
public class FileInputStreamUtil {

/**
* 改善FileInputStream自带read方法不可靠的问题
* @param oInputStream 要读取的流
* @param b 接收数组
* @param off 从数组的哪个位置
* @param len 读的长度
* @param reReadMaxCount 可靠系数(默认同原生InputStream)
* @return
*/
public static int read(FileInputStream oFileInputStream, byte b[], int off, int len, int reReadMaxCount) throws IOException {
if (b == null) {
            throw new NullPointerException();
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return 0;
        }

if (reReadMaxCount <= 0) {
reReadMaxCount = 1;
}

        int nCount = 1;
        int nTempLength = 0;
int bytesRead = 0;

while (bytesRead < len && nTempLength != -1) {
try {
nTempLength = oFileInputStream.read(b, off + bytesRead, len - bytesRead);
} catch (IOException e) {
nCount ++;
if (nCount > reReadMaxCount) {
throw e;
}
}

if (nTempLength != -1) {
bytesRead += nTempLength;
}
}

        return bytesRead;
}

/**
* 改善FileInputStream自带skip方法不可靠的问题
* @param oInputStream 要读取的流
* @param n 要跳过的长度
* @param reReadMaxCount  可靠系数(默认同原生InputStream)
* @return
* @throws IOException
*/
public static long skip(FileInputStream oFileInputStream, long n, int reReadMaxCount) throws IOException {
if (n <= 0) {
            return 0;
        }

if (reReadMaxCount <= 0) {
reReadMaxCount = 1;
}

int nCount = 1;
long remain = n;
long refactSkipLength = 0;

while (remain > 0 && refactSkipLength != -1) {
try {
refactSkipLength = oFileInputStream.skip(remain);
} catch (IOException e) {
nCount ++;
if (nCount > reReadMaxCount) {
throw e;
}
}
if (refactSkipLength != -1) {
remain -= refactSkipLength;
}
}

return n- remain;
}


}

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

InputStream.skip方法的思考

在java.io.InputStream类中定义了skip这个方法。在API中的描述如下:skippublic long skip(long n) throws IOExcepti...
  • GSYzhu
  • GSYzhu
  • 2012-10-23 12:42
  • 13702

Java软件低级错误(十 八):忽略InputStream.skip()返回值的处理

解读: java.io.InputStream.skip(long n):跳过和放弃此输入流中的 n 个数据字节,返回的是跳过的实际字节数。如果skip方法的返回值小于要跳过得字节数,则说明有异常...
  • zxcvg
  • zxcvg
  • 2011-08-09 18:51
  • 4872

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

Java.IO.InputStream.skip() 错误(跳过字节数和预想的不等)

最近写一个网络下载软件,需要使用java.IO.InputStream.skip(long n) 方法,它的作用是从输入流中跳过 n 个字节,比如 inputStream.skip(12),就是从in...

InputStream.skip方法的思考

http://blog.csdn.net/gsyzhu/article/details/8102286 在java.io.InputStream类中定义了skip这个方法。在API中的描...

InputStream方法详解

字节输入流的基础类InputStream和OutputStream有许多相同的地方,也有许多不同点,需注意区分。 概要 与OutputStream相比,这个抽象类定义的方法要多一些。读入数据有些时...

InputStream、FileInputStream之read()、skip()可靠性加强

有经验java程序猿都知道,java中对输入流的读取往往是不可靠的,例如inputStream.read(buffer,0,1024);并不是每次都能读取到1024个字节,而是最多能够读取1024个字...

java 流常用操作

1.FileInputStream FileInputStream类是InputStream的子类,主要是用于从文件系统中的某个文件中获取输入字节 FileInputSream(File file...

【IO】FileInputStream中的方法及其演示

【IO----FileInputStream中的方法及其演示】 一、代码及其笔记 package ioDemo.inputStream; import java.io.FileInputStrea...

inputstream、outputstream 、fileinputstream

输入流的整理

Java 之InputStream FileInputStream FileReader InputStreamReader BufferedReader

文章出处:http://www.cnblogs.com/lianghui66/p/3303546.html java.io下面有两个抽象类:InputStream和Reader InputStre...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)