Java读取InputStream长度,以及available、readAllBytes、read、mark、reset方法介绍

    /** 根据InputStream对应的字节数组读取InputStream长度,会将InputStream指针移动至InputStream尾,不利于后续读取,readInputStream(inputStream).length等同于inputStream.readAllBytes().length,readAllBytes从当前指针位置读取,读取后指针留在最后的位置 */

    public byte[] readInputStream(InputStream inputStream) {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length;
        try {
            while ((length = inputStream.read(buffer)) != -1) {
                outStream.write(buffer, 0, length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return outStream.toByteArray();
    }
	
	/** 一步到位方式,从InputStream指针当前位置起获取InputStream长度,且读取后不会改动InputStream指针位置,没有read指针从0开始 */
	inputStream.available();
	
    /** 扩展:从网络中读取InputStream后,可能因网络质量一次读取后InputStream长度为0,建议加入循环 */
	int count = 0; 
    while (count == 0) { 
    count = inputStream.available(); 
    }
  
    /** 扩展:如果已知InputStream长度,InputStream指针在首部,可在当前指针位置,通过mark标记位置,参数为标记位无效前的已读字节长,已读的字节数超过此参数,标记位无效,reset也不能将指针返回此标记位,注意:已读字节长相对于mark标记位置开始,而非从InputStream的头部开始 */
    inputStream.mark(count);
  
    inputStream.reset();
  
    /** 指针移动至当前指针1024个字节后 */
    inputStream.read(new byte[1024]);

    /** 更新:从网络中获取inputstream,并得到其长度时,如果网络阻塞,inputstream的available()会小于完整长度,甚至为0,推荐: */
    URL url = null;
    try {
        url = new URL(urlString);
    } catch (MalformedURLException e) {
         e.printStackTrace();
    }

    HttpURLConnection httpURLConnection = null;
    try {
        httpURLConnection = (HttpURLConnection) url.openConnection();
    } catch (IOException e) {
        e.printStackTrace();
    }

    httpURLConnection.getContentLength();
  

 

<think>好的,用户让我介绍一下JavaInputStream的skip和reset方法的作用和使用方法。我得先回想一下这两个方法的具体用途,确保自己理解正确。 首先,skip方法应该是用来跳过输入流中的某些字节,对吧?比如用户想跳过n个字节不读取,这时候可以用skip(n)。不过要注意的是,这个方法可能会因为流的不同而返回实际跳过的字节数,比如遇到文件末尾或者其他情况。需要提醒用户处理返回值,确保跳过了预期的数量。 然后reset方法,这个可能有点复杂。因为InputStream本身并没有实现reset方法,只有特定的子类比如BufferedInputStream或者ByteArrayInputStream才支持。这个方法的作用应该是把流的指针重置到之前标记的位置。所以得提到markreset配合使用,先调用mark(readlimit)设置标记,再读取一些数据后,调用reset就能回到那个位置。不过需要强调markSupported()方法检查是否支持,否则会抛出异常。 接下来要考虑用户可能的疑问。比如,用户可能不知道哪些流支持reset,或者为什么skip返回的值可能比预期小。这时候在解释的时候要提前说明这些常见问题,帮助用户避免错误。 还要注意结构清晰,分点说明每个方法的作用、用法、注意事项,最好给出代码示例。比如用skip跳过一些字节,或者用mark/reset来重复读取某部分数据。这样用户能更直观地理解。 另外,用户提到要使用中文回答,所以语言要准确且易懂。可能用户是刚开始学习Java的IO操作,所以需要详细但不过于复杂。需要检查是否覆盖了所有关键点,比如异常处理、方法的使用前提条件等。 总结一下,回答的结构应该是先介绍每个方法,再分点说明作用、使用方法、注意事项,最后给出示例。确保用户能一步步理解,并且知道在实际编码中如何应用这两个方法,同时避免常见的错误。</think>JavaInputStream的`skip()`和`reset()`方法的作用及用法如下: --- ### 一、skip()方法 #### 作用 跳过输入流中指定数量的字节。适用于需要忽略部分数据的场景(如文件头跳过)。 #### 使用方法 ```java long skipped = inputStream.skip(n); // n为要跳过的字节数 ``` - 返回值:实际跳过的字节数(可能小于请求值,如遇到文件末尾) - 典型场景:读取文件时跳过固定长度的无效数据 #### 注意事项 1. 返回值必须校验,可能需要循环调用直到跳过目标字节数 2. 不支持跳过的流(如某些网络流)可能返回0 --- ### 二、reset()方法 #### 作用 将流重置到最后一次调用`mark()`方法时的位置,用于重复读取数据。 #### 使用方法 ```java // 必须先调用mark()设置标记点 inputStream.mark(readLimit); // readLimit为标记的有效范围 // 读取若干字节... inputStream.reset(); // 回到标记点重新读取 ``` - 典型场景:需要回溯读取数据时(如协议解析) #### 注意事项 1. **不是所有流都支持**,需先调用`markSupported()`验证 2. 必须与`mark()`配合使用,单独调用会抛`IOException` 3. `BufferedInputStream`等包装流通常支持该功能 --- ### 三、对比示例 #### skip()示例(跳过文件头) ```java try (FileInputStream fis = new FileInputStream("data.bin")) { long skipped = fis.skip(128); // 跳过128字节文件头 if (skipped != 128) { throw new IOException("未能跳过完整文件头"); } // 继续读取有效数据... } ``` #### reset()示例(重复读取验证) ```java try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("data.txt"))) { if (bis.markSupported()) { bis.mark(1024); // 标记当前位置,允许最多回退1024字节 // 第一次读取 byte[] buffer1 = new byte[100]; bis.read(buffer1); bis.reset(); // 回到标记位置 // 第二次读取相同内容 byte[] buffer2 = new byte[100]; bis.read(buffer2); } } ``` --- ### 四、关键区别总结 | 方法 | 前提条件 | 典型应用场景 | 实现依赖 | |-------|-------------------|---------------------|------------------| | skip | 无 | 跳过不需要的数据 | 所有InputStream | | reset | 必须调用mark() | 数据回溯读取 | 需支持mark的流 | --- 通过合理使用这两个方法,可以更灵活地控制数据读取流程。注意根据具体流类型选择适用方法,特别是在使用`reset()`时务必验证`markSupported()`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风铃峰顶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值