将大流转换为字符串时内存不足

2024-01-06

我正在尝试将大流(4mb)转换为字符串,最终将其转换为 JSON 数组。

当流大小很小(以 KB 为单位)时,一切正常,当它开始处理 4mb 流时,它就会耗尽内存

下面是我用来将流转换为字符串的方法,我几乎尝试了所有方法,我怀疑问题出在 while 循环上。有人可以帮忙吗?

  public String convertStreamToString(InputStream is)
            throws IOException {

        if (is != null) {
            Writer writer = new StringWriter();

            char[] buffer = new char[1024];
            try
            {
                Reader reader = new BufferedReader(
                        new InputStreamReader(is, "UTF-8"));
                int n;
                while ((n = reader.read(buffer)) != -1) 
                {
                    writer.write(buffer, 0, n);
                }
            }
            finally 
            {
                is.close();
            }
            return writer.toString();
        } else {       
            return "";
        }
    }

更新: 好吧,这就是我现在到达的地方,我走在正确的轨道上吗? 我想我已经很接近了..不知道我还能关闭或刷新什么来恢复记忆..

public String convertStreamToString(InputStream is)
        throws IOException {

    String encoding = "UTF-8";
    int maxlines = 2000;
    StringWriter sWriter = new StringWriter(7168);
    BufferedWriter writer = new BufferedWriter(sWriter);
    BufferedReader reader = null;
    if (is == null) {
        return "";
    } else {     


        try {
            int count = 0;
            reader = new BufferedReader(new InputStreamReader(is, encoding));
            for (String line; (line = reader.readLine()) != null;) {
                if (count++ % maxlines == 0) {
                    sWriter.close();
                    // not sure what else to close or flush here to regain memory
                    //Log.v("Max Lines Reached", "Max Lines Reached");;
                }

                writer.write(line);


            }
            Log.v("Finished Loop", "Looping over");


    } finally {
        is.close();
        writer.close();

    }
        return writer.toString();
    }
}

StringWriter写入一个StringBuffer内部。 AStringBuffer基本上是一个围绕 a 的包装char大批。该阵列具有一定的容量。当这个能力不足的时候,StringBuffer将分配一个新的更大的char数组并复制前一个数组的内容。最后你打电话toString()在 StringWriter 上,这将再次复制char数组放入char结果字符串的数组。

如果您有任何方法可以事先知道所需的容量是多少,则应该使用 StringWriter 的构造函数来设置初始容量。这将避免不必要地复制数组以增加缓冲区。

但这并不能避免最终的副本发生在toString()。如果您正在处理可能很大的流,您可能需要重新考虑是否真的需要该输入流作为String。使用足够大的char直接数组可以避免所有的复制,并且会大大减少内存使用。

最终的解决方案是在所有输入进入之前对输入进行一些处理,因此可以丢弃已处理的字符。这样,您只需在内存中保存处理步骤所需的内容即可。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将大流转换为字符串时内存不足 的相关文章

随机推荐

  • 当我不关心枚举包含什么值时,如何在“if”语句中使用枚举?

    我有一个枚举 derive PartialEq Eq enum Foo A B usize 我可以用它if涉及其他逻辑的语句 例如baz fn bar foo Foo baz bool if foo Foo B 3 baz println
  • 将值解析为可空枚举

    假设我有这个 PriorityType priority string userInput 我无法改变它的定义方式 PriorityType priority因为它实际上是与另一段代码签订的合同的一部分 我尝试了这个 但它不起作用 if E
  • 常见的未知 PHP 安全陷阱

    我知道这样的问题已经被问过一百次了 但我的有点不同 我了解所有常见且广为人知的安全问题 例如 SQL 注入 XSS 等 但是那些经常出现但大多数时候未被识别或未被判断为漏洞的问题呢 有吗 我见过很多作为一项功能而开发的一件事 直到为时已晚才
  • 有没有办法在 C++ 中实现 Python 的“separator”.join() 的模拟?

    我所找到的只是boost algorithm string join 然而 仅使用 Boost 进行连接似乎有点矫枉过正 那么也许有一些经过时间考验的食谱 UPDATE 抱歉 问题标题不好 我正在寻找用分隔符连接字符串的方法 而不仅仅是一一
  • PHPExcel toArray 跳过第一个标题行

    我正在将 Excel 文件上传到网站并对其进行处理以供数据库使用 我在用着toArray 函数获取 php 数组中的所有行 但我想跳过第一行 标题行 其余行将存储在数组中 我怎样才能跳过第一行 注意 我不能使用rangeToArray 函数
  • 如何从 Azure DevOps 管道将密钥写入 Azure Key Vault?

    我已经使用 ARM 在 Azure DevOps 中创建了一个 Key Vault 现在我想在同一管道中向它写入一个密钥 我使用以下内联 PowerShell 创建了一个 Azure PowerShell 任务 secretvalue Co
  • 使用 ImageMagick 批量调整图像大小并将图像输出到新文件夹

    当前图像文件夹路径 public html images thumbs 输出图像文件夹路径 public html images new thumbs 我当前文件夹中的每个视频有 10 个视频拇指 名为图像拇指 1 1 jpg 1 2 jp
  • 如何在 C++ 中从基类构造函数调用派生类方法? [复制]

    这个问题在这里已经有答案了 我有一个基类和两个派生类 基类构造函数在调用时应计算一些属性 尽管这些属性取决于派生类的详细信息 为了避免在每个派生类构造函数中重新编码相同的步骤 我在基类构造函数中对这些步骤进行编码 如下例所示 问题是 当我这
  • 使用 UIImagePickerController 时 iOS 10 错误 [access]

    我正在使用 XCode 8 并使用 iOS 10 2 Beta 进行测试 我已将 Photos PhotosUI 和 MobileCoreServices 框架添加到项目中 非常简单的代码 import
  • 在客户端访问IE8中文件输入的文件数据?

    是否可以获取在文件输入中选择的实际文件数据 我正在尝试执行以下代码 但 this files 不包含我期望的文件数据 在 Chrome 中确实存在 document getElementById txtFileInput onchange
  • Objective-C中使用GCD的dispatch_once创建单例

    如果您可以定位 iOS 4 0 或更高版本 使用GCD 这是在Objective C 线程安全 中创建单例的最佳方式吗 instancetype sharedInstance static dispatch once t once stat
  • 如何在自定义 Cordova 插件中包含多个 AAR 文件?

    我是科尔多瓦开发的新手 我需要编写一个引用两个 aar 文件的自定义插件 我可以将第一个 aar 文件添加到插件中 但是我对添加第二个 aar 文件有一些疑问 我可以在同一个自定义插件中添加第二个 aar 文件吗 或者我是否需要创建另一个自
  • 如何在 T-SQL 中计算 GROUP BY 行数

    我有一个 SQL 查询 它执行 GROUP BY 将包含相同 Player id 但不相同 Game id 的所有行合并在一起 SELECT p Player id p Name p Position SUM s Goals AS goal
  • 如何通过电视马拉松将消息转发给其他联系人

    当我收到联系人发来的消息后 如何立即将消息转发到另一个聊天室 我创建这个示例只是为了测试路由 但它不起作用 usr local bin python3 from telethon import TelegramClient events a
  • 如果进程以参数启动,Ruby readline 将失败

    我遇到了最奇怪的问题 下面的代码工作正常 require json require net http h Net HTTP new localhost 4567 while l gets chomp res h post api v1 se
  • Varargs Kotlin Java 互操作无法正常工作

    对于 makeSceneTransitionAnimation 有两个静态函数 public static ActivityOptionsCompat makeSceneTransitionAnimation Activity activi
  • Javascript键盘输入过滤

    有没有人有一个有效的动态 JavaScript 输入过滤器 可以限制跨多个浏览器的文本输入 我在网上看到了多个示例 但大多数似乎都有缺陷或缺乏多浏览器支持 我当前的尝试发布在下面 但在 Firefox 下移动数字失败 而且我还没有尝试过其他
  • Swift Actor 中发生数据争用

    我使用 Thread Sanitizer 在 Swift 应用程序中发现了数据争用 因此我第一次尝试通过转换有问题的数据来修复争用条件class to an actor 竞争造成的崩溃似乎已经消失 但 Thread Sanitizer 仍然
  • Angular 9 引入了需要加载的全局“$localize()”函数

    我在新的角度项目设置中遇到以下错误 已安装的软件包及其版本 https i stack imgur com 2Fb18 png 错误错误 未捕获 承诺 错误 它看起来像你的 应用程序或其依赖项之一正在使用 i18n 角9 推出了全球 loc
  • 将大流转换为字符串时内存不足

    我正在尝试将大流 4mb 转换为字符串 最终将其转换为 JSON 数组 当流大小很小 以 KB 为单位 时 一切正常 当它开始处理 4mb 流时 它就会耗尽内存 下面是我用来将流转换为字符串的方法 我几乎尝试了所有方法 我怀疑问题出在 wh