Есть ли более простой способ изменить BufferedReader на строку? - PullRequest
1 голос
/ 07 октября 2009

Прямо сейчас у меня есть

;; 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)))))

Это слишком медленно.

Edit:

  • У меня есть BufferedReader

  • когда я пытаюсь это сделать (str BufferedReader), он выдает мне «java.io.BufferedReader@1ce784b»

  • вышеприведенный цикл слишком медленный, и мне не хватает места в памяти.

Ответы [ 6 ]

5 голосов
/ 08 октября 2009
(clojure.contrib.duck-streams/slurp* your-buffer) ; is what you want

Ваш код работает медленно, потому что буфер не намекается.

3 голосов
/ 08 октября 2009

Я не знаю Clojure, поэтому я не могу сказать, есть ли у вас неправильные детали в вашем коде, но использование StringBuffer и добавление строки к строке является правильным способом сделать это (ну, используя StringBuilder инициализируется до ожидаемого конечного размера, если известно, что принесет существенные, но не существенные улучшения).

Если вам не хватает памяти, то, возможно, содержимое вашего BufferedReader слишком велико, чтобы уместиться в вашей памяти, и нет способа разместить его в виде одной строки - в этом случае вам придется либо увеличить свой размер кучи или найдите способ обрабатывать данные по одному небольшому куску за раз.

Кстати, если вы знаете размер вашего ввода, более эффективным методом будет использование CharBuffer и заполнение его с помощью Reader.read () (вы будете нужно обратить внимание на метод возврата и использовать его в цикле).

0 голосов
/ 08 октября 2009

используйте slurp для чтения (файлы разумного размера) in
используйте коса , чтобы записать их обратно из снова.

0 голосов
/ 08 октября 2009

Я не знаю clojure, только Java. Давайте работать оттуда.

Некоторые моменты для рассмотрения:

  • Если ваша целевая версия JVM>> 1.5, вы можете использовать StringBuilder вместо StringBuffer для небольшого улучшения производительности (без синхронизации, и она вам не нужна) , Читайте об этом здесь

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

  • Но ваша высокая производительность, вероятно, связана с расширением буфера. Когда вы создаете экземпляр StringBuffer / StringBuilder без использования конструктора с аргументом емкости, вы получаете небольшую емкость.

    Когда вы начинаете с небольшой емкости (размер внутреннего буфера), у вас есть много расширений - каждый раз, когда вы превышаете эту емкость, его внутренний буфер перераспределяется на новую емкость, достаточно большую, чтобы вместить только что добавленный текст, что означает копирование весь ранее сохраненный текст в новый буфер.

    Это очень медленно, когда вы добавляете больше текста к уже очень большой строке.

    Если у вас есть доступ к размеру текста, который вы читаете (размер файла был бы приблизительным), вы можете значительно уменьшить количество расширений.

  • Я также мог бы сказать вам использовать read () метод BufferedReader , один с 3 аргументами, этот:

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

    Затем можно использовать один из конструкторов класса String , которые принимают массив char , чтобы преобразовать буфер char в String

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

    ... однако, я подозреваю, что улучшение производительности будет не таким значительным, особенно по сравнению с тем, которое заключается в сокращении количества расширений StringBuilder .

  • Независимо от приближения, у вас, похоже, проблема с объемом памяти:

    В конце вам понадобится как минимум вдвое больше памяти, чем занимает весь текст.

    Либо, если вы используете подход StringBuilder / StringBuffer или другой, в конце вам придется скопировать текстовое содержимое в новую строку, содержащую результат.

В конце вам, вероятно, нужно будет поработать из этой коробки:

  • Вы уверены, что у вас есть только BufferedReader в качестве начала и String в качестве конца? Вы должны предоставить более широкую картину!

Если это самый широкий из имеющихся у вас вариантов, вам потребуется как минимум экземпляр JVM, сконфигурированный с большей кучей, поскольку в любом случае вам, вероятно, не хватит памяти для любого из этих решений.

0 голосов
/ 08 октября 2009

в 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();
}
0 голосов
/ 08 октября 2009

buffer.ToString ()? Или в вашем случае, может быть (буфер .toString)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...