Дамп Java StringBuilder в файл

Лучший способ, который я нашел для этого, - это создание приложений, а затем проект их склеивания. Большинство моих проектов имеют похожие приложения, которые включены в каждый. Электронная почта, заметки, напоминания о действиях, авторизация пользователя и т. Д. Мой предпочтительный макет выглядит примерно так:

  • project /
    • settings.py
    • urls.py
    • views.py
    • ...
  • apps /
    • электронные письма /
      • urls.py
      • views.py
      • ...
      • notes /
        • urls.py
        • views.py
        • ...
        • ...

      apps:

      Каждое из «приложений» стоит само по себе и, кроме settings.py, не зависит от сам проект (хотя он может полагаться на другие приложения). Одним из приложений является аутентификация и управление пользователями. Он имеет все URL для выполнения своих задач в apps/auth/urls.py. Все его шаблоны находятся в apps/auth/templates/auth/. Вся его функциональность автономна, поэтому, когда мне нужно что-то настроить, я знаю, куда идти.

      проект:

      project/ содержит весь клей, необходимый для объединения этих отдельных приложений в окончательный проект. В моем случае я использовал settings.INSTALLED_APPS в project/, чтобы понять, какие виды из приложений были доступны для меня. Таким образом, если я возьму apps.notes из своего INSTALLED_APPS, все по-прежнему работает чудесно, просто без заметок.

      Техническое обслуживание:

      Этот план / методология / план также имеет долгосрочные положительные последствия. Позже вы можете повторно использовать любое из приложений, практически без работы. Вы можете протестировать систему снизу вверх, убедившись, что каждое из приложений работает, как предполагалось, прежде чем интегрироваться в целое, что поможет вам быстрее находить / исправлять ошибки. Вы можете реализовать новую функцию, не распространяя ее на существующие экземпляры приложения (если ее нет в INSTALLED_APPS, они не могут ее увидеть).

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

35
задан Etienne Neveu 28 September 2011 в 21:23
поделиться

6 ответов

Как указывалось другими, используйте Writer и используйте BufferedWriter, но затем не вызывайте writer.write (stringBuilder.toString ()); вместо этого просто writer.append (stringBuilder); .

РЕДАКТИРОВАТЬ: Но я вижу, что вы приняли другой ответ, потому что он был однострочным. Но у этого решения есть две проблемы:

  1. оно не принимает java.nio.Charset . ПЛОХО. Вы всегда должны указывать Charset явно.

  2. это все еще заставляет вас страдать от stringBuilder.toString () . Если вам действительно нужна простота, попробуйте следующее из проекта Guava :

Files.write (stringBuilder, file, Charsets.UTF_8)

40
ответ дан 27 November 2019 в 06:36
поделиться

Вы можете использовать библиотеку Apache Commons IO , которая дает вам FileUtils :

FileUtils.writeStringToFile(file, stringBuilder.toString(), Charset.forName("UTF-8"))
14
ответ дан 27 November 2019 в 06:36
поделиться

Well, if the string is huge, toString().getBytes() will create duplicate bytes (2 or 3 times). The size of the string.

To avoid this, you can extract chunk of the string and write it in separate parts.

Here is how it may looks:

final StringBuilder aSB = ...;
final int    aLength = aSB.length();
final int    aChunk  = 1024;
final char[] aChars  = new char[aChunk];

for(int aPosStart = 0; aPosStart < aLength; aPosStart += aChunk) {
    final int aPosEnd = Math.min(aPosStart + aChunk, aLength);
    aSB.getChars(aPosStart, aPosEnd, aChars, 0);                 // Create no new buffer
    final CharArrayReader aCARead = new CharArrayReader(aChars); // Create no new buffer

    // This may be slow but it will not create any more buffer (for bytes)
    int aByte;
    while((aByte = aCARead.read()) != -1)
        outputStream.write(aByte);
}

Hope this helps.

15
ответ дан 27 November 2019 в 06:36
поделиться

You should use a BufferedWriter to optimize the writes (always write character data using a Writer instead of an OutputStream). If you weren't writing character data, you would use a BufferedOutputStream.

File file = new File("path/to/file.txt");
BufferedWriter writer = null;
try {
    writer = new BufferedWriter(new FileWriter(file));
    writer.write(stringBuilder.toString());
} finally {
    if (writer != null) writer.close();
}

or, using try-with-resources (Java 7 and up)

File file = new File("path/to/file.txt");
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
    writer.write(stringBuilder.toString());
}

Since you're ultimately writing to a file, a better approach would be to write to the BufferedWriter more often instead of creating a huge StringBuilder in-memory and writing everything at the end (depending on your use-case, you might even be able to eliminate the StringBuilder entirely). Writing incrementally during processing will save memory and will make better use of your limited I/O bandwidth, unless another thread is trying to read a lot of data from the disk at the same time you're writing.

24
ответ дан 27 November 2019 в 06:36
поделиться

Если сама строка длинная, вам определенно следует избегать toString (), который создает еще одну копию строки. Наиболее эффективный способ записи в поток должен быть примерно таким:

OutputStreamWriter writer = new OutputStreamWriter(
        new BufferedOutputStream(outputStream), "utf-8");

for (int i = 0; i < sb.length(); i++) {
    writer.write(sb.charAt(i));
}
1
ответ дан 27 November 2019 в 06:36
поделиться

Для символьные данные лучше использовать Reader / Writer . В вашем случае используйте BufferedWriter . Если возможно, используйте BufferedWriter с самого начала вместо StringBuilder для экономии памяти.

Обратите внимание, что ваш способ вызова не-arg getBytes () будет использовать кодировку символов по умолчанию платформы для декодирования символов. Это может привести к сбою, если кодировка платформы по умолчанию, например, ISO-8859-1 , а ваши строковые данные содержат символы вне кодировки ISO-8859-1 . Лучше использовать getBytes (charset) , где вы можете указать кодировку самостоятельно,

3
ответ дан 27 November 2019 в 06:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: