java 有没有更简单的方法可以将 BufferedReader 更改为字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1533787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 16:58:41  来源:igfitidea点击:

Is there an easier way to change BufferedReader to string?

javaclojure

提问by unj2

Right Now I have

现在我有

;; buffer->string: BufferedReader -> String
(defn buffer->string [buffer]
 (loop [line  (.readLine buffer) sb (StringBuilder.)]
     (if(nil? line)
        (.toString sb)
        (recur (.readLine buffer) (.append sb line)))))

This is too slow.

这太慢了。

Edit:

编辑:

  • I have a BufferedReader

  • when i try to do (str BufferedReader) it gives me "java.io.BufferedReader@1ce784b"

  • the above loop is too slow and I run out of memory space.

  • 我有一个 BufferedReader

  • 当我尝试做(str BufferedReader)时,它给了我“java.io.BufferedReader@1ce784b”

  • 上面的循环太慢了,我的内存空间用完了。

回答by cgrand

(clojure.contrib.duck-streams/slurp* your-buffer) ; is what you want

Your code is slow because buffer isn't hinted.

您的代码很慢,因为没有暗示缓冲区。

回答by Michael Borgwardt

I don't know Clojure, so I can't tell if you have some detail wrong in your code, but using StringBufferand appending the input line by line is the correct way to do it (well, using a StringBuilderinitialized to the expected final size if known would bring significant but not dramatic improvements).

我不知道 Clojure,所以我不知道您的代码中是否有一些细节错误,但是StringBuffer逐行使用和附加输入是正确的方法(好吧,使用StringBuilder初始化为预期的最终大小如果知道将带来显着但不是显着的改进)。

If you run out of memory, then maybe the content of your BufferedReader is simply too large to fit into your memory and there is no way to have it as a single string - in that case, you'll either have to increase your heap size or find a way to process the data one small chunk at a time.

如果内存不足,则 BufferedReader 的内容可能太大而无法放入内存中,并且无法将其作为单个字符串 - 在这种情况下,您要么必须增加堆大小或者找到一种方法一次处理一小块数据。

BTW, if you know the size of your input, a more efficient method would be to use a CharBufferand fill it by using Reader.read()(you'll have to pay attention to the return method and use it in a loop).

顺便说一句,如果您知道输入的大小,更有效的方法是使用CharBuffer并使用Reader.read()填充它(您必须注意返回方法并在循环中使用它) .

回答by unj2

buffer.ToString()? Or in your case, maybe (.toString buffer)?

缓冲区.ToString()?或者在你的情况下,也许(.toString 缓冲区)?

回答by unj2

in java you would do something like;

在 Java 中,你会做类似的事情;

public String getStringFromBuffer(){
BufferedReader bRead = new BufferedReader();
String line = null;
StringBuffer theText = new StringBuffer();
while((line=bRead.readLine())!=null){
   theText.append(line+"\n);
}

return theText.toString();
}

回答by Paulo Gaspar

I don't know clojure, just Java. Lets work from there.

我不知道 clojure,只知道 Java。让我们从那里开始工作。

Some points to consider:

需要考虑的几点:

  • If your target JVM version is >= 1.5 you can use StringBuilderinstead of StringBufferfor a small performance improvement (no synchronization and you don't need it). Read about it here

    http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html

  • But your big performance cost is probably on the buffer expansion. When you instantiate a StringBuffer/StringBuilderwithout using the constructor with the capacity argument you get a small capacity.

    When starting with a small capacity (the internal buffer size) you have many expansions - every time you exceed that capacity, its internal buffer is reallocated to a new capacity, just large enough to hold the newly appended text, which means copying all previously held text to the new buffer.

    This is very slow when you are appending more text to an already very large string.

    If you have access to the size of the text you are reading (a file size would be an approximation) you can significantly reduce the amount of expansions.

  • I could also tell you to use read()method of the BufferedReader, the one with 3 arguments, this one:

    BufferedReader.read(char[], int, int)

    You could then use one of the String's class constructors that accept a chararray to convert the charbuffer into a String:

    String.String(char[], int, int)

    ...however, I suspect that the performance improvement will not be that big, especially when compared with the one of reducing how many StringBuilderexpansions you'll have.

  • Whatever the approximation, you seem to have memory capacity problem:

    In the end you will need at least twice as much memory as the whole text occupies.

    Either if you use the StringBuilder/StringBufferapproach or the other one, in the end you will have to copy the text contents to the new String holding the result.

  • 如果您的目标 JVM 版本 >= 1.5,您可以使用StringBuilder而不是StringBuffer来实现小的性能改进(没有同步并且您不需要它)。在这里阅读

    http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html

  • 但是您的巨大性能成本可能在于缓冲区扩展。当您在不使用带有容量参数的构造函数的情况下实例化StringBuffer/ StringBuilder 时,您会得到一个小容量。

    当从小容量(内部缓冲区大小)开始时,您有许多扩展 - 每次超过该容量时,其内部缓冲区都会重新分配到新容量,大小刚好足以容纳新附加的文本,这意味着复制所有先前持有的文本到新缓冲区。

    当您将更多文本附加到已经非常大的字符串时,这非常慢。

    如果您可以访问正在阅读的文本的大小(文件大小是近似值),则可以显着减少扩展量。

  • 我还可以告诉你使用BufferedReader 的read()方法,这个方法有 3 个参数,这个:

    BufferedReader.read(char[], int, int)

    然后,您可以使用接受char数组的String类构造函数之一将char缓冲区转换为String

    String.String(char[], int, int)

    ...但是,我怀疑性能改进不会那么大,尤其是与减少您将拥有的StringBuilder扩展数量相比时。

  • 无论近似值如何,您似乎都有内存容量问题:

    最后,您需要的内存至少是整个文本占用的内存的两倍。

    如果您使用StringBuilder/ StringBuffer方法或另一种方法,最后您必须将文本内容复制到保存结果的新 String 中。

In the end you will probably need to work out of this box:

最后,您可能需要开箱即用:

  • Are you sure you only have a BufferedReaderas a start and a Stringas an end? You should provide the broader picture!
  • 你确定你只有一个BufferedReader作为开始,一个String作为结束吗?你应该提供更广泛的图片!

If this is the broadest you have, you will need at least a JVM instance configured with more heap since you will probably run out of memory with any of this solutions anyway.

如果这是您拥有的最广泛的实例,那么您至少需要一个配置有更多堆的 JVM 实例,因为无论如何使用这些解决方案中的任何一个都可能会耗尽内存。

回答by Arthur Ulfeldt

use slurpto read (reasonably sized files) in
use spitto write them back outagain.

使用啜食读(合理大小的文件)
使用写他们回来一次。