有人可以告诉我如何克隆输入流,尽可能少的创建时间?我需要多次克隆输入流以便多种方法来处理IS.我尝试了三种方法,因为某种原因,事情不起作用.

方法#1:
感谢stackoverflow社区,我发现以下链接很有帮助,并将代码片段合并到我的程序中.

How to clone an InputStream?

但是,使用此代码最多可能需要一分钟(对于10MB文件)来创建克隆的输入流,并且我的程序需要尽可能快.

int read = 0;
    byte[] bytes = new byte[1024*1024*2];

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    while ((read = is.read(bytes)) != -1)
        bos.write(bytes,read);
    byte[] ba = bos.toByteArray();

    InputStream is1 = new ByteArrayInputStream(ba);
    InputStream is2 = new ByteArrayInputStream(ba);
    InputStream is3 = new ByteArrayInputStream(ba);

方法#2:
我也尝试使用BufferedInputStream来克隆IS.这很快(创建时间最慢== 1ms.最快== 0ms).但是,在我发送is1进行处理之后,方法处理is2和is3引发了一个错误,说没有什么可以处理,几乎就像下面引用相同的IS的所有3个变量一样.

is = getFileFromBucket(path,filename);
    ...
    ...
    InputStream is1 = new BufferedInputStream(is);
    InputStream is2 = new BufferedInputStream(is);
    InputStream is3 = new BufferedInputStream(is);

方法#3:
我认为编译器对我说谎.我在上面两个例子中检查了is1的markSupported().它返回true,所以我以为我可以跑了

is1.mark() 
    is1.reset()

要不就

is1.reset();

在将IS传递给我各自的方法之前.在上面的两个例子中,我收到一个错误,说它是无效标记.

我现在没有想法,所以提前感谢你能给我的任何帮助.

附:从我收到的人们的评论中,我需要澄清一些与我的情况有关的事情:
1)该程序在VM上运行
2)输入流正从另一种方法传递给我.我不是从本地文件中读取的
3)输入流的大小未知

解决方法

how to clone an inputstream,taking as little creation time as possible? I need to clone an inputstream multiple times for multiple methods to process the IS

您可以创建某种自定义的ReusableInputStream类,其中您在第一次完整读取时立即写入内部ByteArrayOutputStream,然后在读取最后一个字节时将其包装在ByteBuffer中,最后在后续完整读取时重用相同的ByteBuffer当达到限制时会自动翻转.这样可以避免您在第一次尝试时完全阅读.

这是一个基本的启动示例:

public class ReusableInputStream extends InputStream {

    private InputStream input;
    private ByteArrayOutputStream output;
    private ByteBuffer buffer;

    public ReusableInputStream(InputStream input) throws IOException {
        this.input = input;
        this.output = new ByteArrayOutputStream(input.available()); // Note: it's resizable anyway.
    }

    @Override
    public int read() throws IOException {
        byte[] b = new byte[1];
        read(b,1);
        return b[0];
    }

    @Override
    public int read(byte[] bytes) throws IOException {
        return read(bytes,bytes.length);
    }

    @Override
    public int read(byte[] bytes,int offset,int length) throws IOException {
        if (buffer == null) {
            int read = input.read(bytes,offset,length);

            if (read <= 0) {
                input.close();
                input = null;
                buffer = ByteBuffer.wrap(output.toByteArray());
                output = null;
                return -1;
            } else {
                output.write(bytes,read);
                return read;
            }
        } else {
            int read = Math.min(length,buffer.remaining());

            if (read <= 0) {
                buffer.flip();
                return -1;
            } else {
                buffer.get(bytes,read);
                return read;
            }
        }

    }

    // You might want to @Override flush(),close(),etc to delegate to input.
}

(请注意,实际作业是在int read(byte [],int,int)中执行而不是在int read()中执行,因此当调用者本身也使用byte []缓冲区进行流式处理时,预期会更快.

您可以按如下方式使用它:

InputStream input = new ReusableInputStream(getFileFromBucket(path,filename));
IoUtils.copy(input,new FileOutputStream("/copy1.ext"));
IoUtils.copy(input,new FileOutputStream("/copy2.ext"));
IoUtils.copy(input,new FileOutputStream("/copy3.ext"));

至于性能,每10MB 1分钟更可能是硬件问题,而不是软件问题.我的7200rpm笔记本电脑硬盘在不到1秒的时间内完成.

如何在最短的时间内在java中克隆输入流的更多相关文章

  1. swift 下 UNcode字符串 转为中文字符

    顺便一提,1F436这个16进制数,也能直接通过UnicodeScalar转换成字符串,就像下面这样DOGFACE

  2. Swift学习第十三枪-使用Swift开发IOS中蓝牙4.0的开发流程

    前面总结了几篇关于Swift的使用,今天要讲的是关于使用Swift开发IOS中蓝牙4.0的开发流程,我以前只是会搞android的蓝牙开发,最近开始了Swift的学习,作为一个swift爱好者,想把蓝牙4.0的这个装逼神器在swift中使用一下。使用Swift开发IOS中蓝牙4.0的开发流程有如下的几个步骤:建立桥接文件案例的实现1.建立桥接文件1.1在用Swift使用OC中得类文件的时候,需要进行桥接,首先建一个.h的头文件。

  3. 往返Swift数字类型到/从数据

    Swift3倾向于Data而不是[UInt8],我试图找出最有效/惯用的编码/解码方式,将各种数字类型转换为Data对象。有thisanswerforusing[UInt8],但似乎使用各种指针API,我不能在数据上找到。在早期的Swift版本中,你可以通过做函数参数本身是一个变量,这不再支持了。>最后声明符合所有类型,可以安全地转换为数据并返回:这使得转换更加优雅:第二种方法的优点是,您不能无意中执行不安全的转化。缺点是你必须显式列出所有“安全”类型。

  4. 在Swift中将两个字节的UInt8数组转换为UInt16

    使用Swift我想将字节从uint8_t数组转换为整数。“C”示例:Swift尝试:从Swift中的UInt8数组创建UInt16值的正确语法或代码是什么?我对NSData版本感兴趣,并且正在寻找一个不使用临时数组的解决方案。如果你想通过NSData去,那么它将像这样工作:或者:两种变体都假定字节是主机字节顺序。

  5. 如何在swift中将Int16转换为两个UInt8字节

    我有一些二进制数据,将两个字节的值编码为有符号整数.解码这很简单–我可以从这些字节中提取Int16值:编码这是我遇到问题的地方.我的大多数数据规范都要求使用UInt,这很简单,但我无法提取组成Int16的两个字节题如何提取构成Int16值的两个字节你应该使用无符号整数:如果您想将UInt16转换为等效的Int16,那么您可以使用特定的初始化程序:反之亦然:在你的情况下:

  6. Swift 3中的数据MD5

    我正在尝试获取我的数据的MD5哈希值.不幸的是,我已经将框架升级到swift3,而我一直使用的方法现在不起作用.我已经转换了大部分内容,但我无法从数据中获取字节数:CommonCrypto已作为自定义模块导入.问题是我得到’字节’不可用:在CC_MD5上使用withUnsafeBytes(data.bytes,…

  7. 使用Swift从NSData获取数据

    2)文档说这个参数应该是_buffer:UnsafeMutablePointer.那么这是如何工作的呢?为什么我要这样做而不是更原生/托管[Uint8]构造?我想知道UnsafeMutablePointer是否是一个协议,但它是一个结构.大胆地直接读取值,我想也许我可以尝试另一种结构.我有一个6字节的结构,看起来像:哪个实际上有效!但这让我担心结构包装细节?

  8. 如何在Swift中创建打包数据结构?

    我正在将一个项目从Objective-C转换为Swift,我正在使用一个打包的结构来输入通过套接字发送的转换二进制消息:我不确定Swift中最好的方法是什么,我能得到的最接近的近似值是:翻译中丢失了两个重要的细节:没有保证整数类型的比特,并且没有结构打包.我不认为这可以在Swift中表达,但如果是这样,怎么样?

  9. android – 如何实现消息读取状态,如whatsapp蓝色刻度?

    我正在开发一个应用程序,聊天是一个模块,聊天我正在使用xmpp.当我发送消息时,我使用DeliveryReceiptManager获取该消息传递状态.但我需要表明该消息是用户READ或NOTwhatsApp蓝色tickmark,任何人都可以帮助我,我被击中了.如何实现此消息读取概念.提前致谢.解决方法创建自定义数据包扩展类当进入聊天列表时发送具有相同包ID的消息标签其中mConnection是xm

  10. 如何解码base64字符串并将其转换为pdf / jpg并将其保存在存储中

    谢谢大家=)解决方法你可以试试这个:哪里:>filepath:新文件的路径>base64String:您要转换的base64字符串

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部