Изображение с кодировкой Base64 кажется усеченным на строку [duplicate]

[D1] / ******************************************* *************************** * он будет записывать содержимое в указанный файл * * @param keyString * @throws IOException ***** ************************************************** ************** / public static void writeToFile (String keyString, String textFilePAth) throws IOException {// Для вывода в файл Файл a = новый файл (textFilePAth); if (! a.exists ()) {a.createNewFile (); } FileWriter fw = new FileWriter (a.getAbsoluteFile (), true); BufferedWriter bw = новый BufferedWriter (fw); bw.append (KeyString); bw.newLine (); bw.close (); } // конец writeToFile ()
77
задан aroth 17 January 2012 в 03:31
поделиться

10 ответов

В logcat для двоичных журналов (/dev/log/events) существует буфер фиксированного размера, и этот предел составляет 1024 байта. Для недвоичных журналов существует также предел:

#define LOGGER_ENTRY_MAX_LEN        (4*1024)
#define LOGGER_ENTRY_MAX_PAYLOAD (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))

. Таким образом, реальный размер сообщения для двоичных и не двоичных журналов составляет ~ 4076 байт. Интерфейс регистратора ядра накладывает это ограничение LOGGER_ENTRY_MAX_PAYLOAD.

Источники liblog (используемые logcat) также говорят:

  • Сообщение могло быть усечено с помощью Драйвер журнала ядра.

Я бы рекомендовал вам инструмент nxlog , который не использует двоичный файл logcat, но из-за ограничений в ядре I сомневайтесь, что он решит вашу проблему. Тем не менее, возможно, стоит попробовать. (отказ от ответственности: я автор.)

31
ответ дан Sky Kelsey 16 August 2018 в 04:40
поделиться
  • 1
    Где я могу найти это? Является ли он в "logcat" код? Итак, нужно ли мне скомпилировать собственный модифицированный логарифм? – d4Rk 2 July 2015 в 15:38
  • 2
    Что такое бинарный / небинный журнал? – fobbymaster 9 November 2016 в 19:17
  • 3
    Из-за добавления полей метаданных LOGGER_ENTRY_MAX_PAYLOAD было уменьшено с 4076 до 4068 в более поздних версиях Android (см. здесь ). – mhsmith 14 February 2018 в 17:10

Код ниже - это уточнение того, что было опубликовано Марком Буйкема. Он разбивает строку на новые строки. Полезно для записи длинных строк JSON.

  public static void dLong(String theMsg)
  {
    final int MAX_INDEX = 4000;
    final int MIN_INDEX = 3000;

    // String to be logged is longer than the max...
    if (theMsg.length() > MAX_INDEX)
    {
      String theSubstring = theMsg.substring(0, MAX_INDEX);
      int    theIndex = MAX_INDEX;

      // Try to find a substring break at a line end.
      theIndex = theSubstring.lastIndexOf('\n');
      if (theIndex >= MIN_INDEX)
      {
        theSubstring = theSubstring.substring(0, theIndex);
      }
      else
      {
        theIndex = MAX_INDEX;
      }

      // Log the substring.
      Log.d(APP_LOG_TAG, theSubstring);

      // Recursively log the remainder.
      dLong(theMsg.substring(theIndex));
    }

    // String to be logged is shorter than the max...
    else
    {
      Log.d(APP_LOG_TAG, theMsg);
    }
  }
2
ответ дан dazed 16 August 2018 в 04:40
поделиться

Вот код, который я использую - он обрезает линии на пределе 4000, а также разбивая линию на новые строки, а не на середину строки. Делает для более легкого чтения файла журнала.

Использование:

Logger.debugEntire("....");

Реализация:

package ...;

import android.util.Log;

import java.util.Arrays;

public class Logger {

    private static final String LOG_TAG = "MyRockingApp";

    /** @see <a href="http://stackoverflow.com/a/8899735" /> */
    private static final int ENTRY_MAX_LEN = 4000;

    /**
     * @param args If the last argument is an exception than it prints out the stack trace, and there should be no {}
     *             or %s placeholder for it.
     */
    public static void d(String message, Object... args) {
        log(Log.DEBUG, false, message, args);
    }

    /**
     * Display the entire message, showing multiple lines if there are over 4000 characters rather than truncating it.
     */
    public static void debugEntire(String message, Object... args) {
        log(Log.DEBUG, true, message, args);
    }

    public static void i(String message, Object... args) {
        log(Log.INFO, false, message, args);
    }

    public static void w(String message, Object... args) {
        log(Log.WARN, false, message, args);
    }

    public static void e(String message, Object... args) {
        log(Log.ERROR, false, message, args);
    }

    private static void log(int priority, boolean ignoreLimit, String message, Object... args) {
        String print;
        if (args != null && args.length > 0 && args[args.length-1] instanceof Throwable) {
            Object[] truncated = Arrays.copyOf(args, args.length -1);
            Throwable ex = (Throwable) args[args.length-1];
            print = formatMessage(message, truncated) + '\n' + android.util.Log.getStackTraceString(ex);
        } else {
            print = formatMessage(message, args);
        }
        if (ignoreLimit) {
            while (!print.isEmpty()) {
                int lastNewLine = print.lastIndexOf('\n', ENTRY_MAX_LEN);
                int nextEnd = lastNewLine != -1 ? lastNewLine : Math.min(ENTRY_MAX_LEN, print.length());
                String next = print.substring(0, nextEnd /*exclusive*/);
                android.util.Log.println(priority, LOG_TAG, next);
                if (lastNewLine != -1) {
                    // Don't print out the \n twice.
                    print = print.substring(nextEnd+1);
                } else {
                    print = print.substring(nextEnd);
                }
            }
        } else {
            android.util.Log.println(priority, LOG_TAG, print);
        }
    }

    private static String formatMessage(String message, Object... args) {
        String formatted;
        try {
            /*
             * {} is used by SLF4J so keep it compatible with that as it's easy to forget to use %s when you are
             * switching back and forth between server and client code.
             */
            formatted = String.format(message.replaceAll("\\{\\}", "%s"), args);
        } catch (Exception ex) {
            formatted = message + Arrays.toString(args);
        }
        return formatted;
    }
}
4
ответ дан enl8enmentnow 16 August 2018 в 04:40
поделиться

Если ваш журнал очень длинный (например, запись всего дампа вашей базы данных по причинам отладки и т. д.), может случиться, что logcat предотвращает чрезмерное ведение журнала. Чтобы обойти это, вы можете добавить тайм-аут evry x миллисекунды.

/**
 * Used for very long messages, splits it into equal chunks and logs each individual to
 * work around the logcat max message length. Will log with {@link Log#d(String, String)}.
 *
 * @param tag     used in for logcat
 * @param message long message to log
 */
public static void longLogDebug(final String tag, @NonNull String message) {
    int i = 0;

    final int maxLogLength = 1000;
    while (message.length() > maxLogLength) {
        Log.d(tag, message.substring(0, maxLogLength));
        message = message.substring(maxLogLength);
        i++;

        if (i % 100 == 0) {
            StrictMode.noteSlowCall("wait to flush logcat");
            SystemClock.sleep(32);
        }
    }
    Log.d(tag, message);
}

Остерегайтесь, используйте его только для целей отладки, так как он может остановить основной поток блоков.

1
ответ дан for3st 16 August 2018 в 04:40
поделиться

, предоставляя мой собственный подход к решению Тревиса,

void d(String msg) {
  println(Log.DEBUG, msg);
}

private void println(int priority, String msg) {
    int l = msg.length();
    int c = Log.println(priority, TAG, msg);
    if (c < l) {
        return c + println(priority, TAG, msg.substring(c+1));
    } else {
        return c;
    }
}

использует тот факт, что Log.println() возвращает количество байтов, записанных во избежание жесткого кодирования «4000». затем рекурсивно называть себя частью сообщения, которое невозможно зарегистрировать, пока ничего не останется.

1
ответ дан Jeffrey Blattman 16 August 2018 в 04:40
поделиться
  • 1
    К сожалению, println возвращает # байтов, а символы - байты. – gnuf 29 May 2013 в 19:39
  • 2
    ну, это работает. Я предполагаю, что я только регистрирую текст ascii. – Jeffrey Blattman 29 May 2013 в 21:21

Разбить его на несколько частей рекурсивно.

public static void largeLog(String tag, String content) {
   if (content.length() > 4000) {
       Log.d(tag, content.substring(0, 4000));
       largeLog(tag, content.substring(4000));
   } else {
       Log.d(tag, content);
   }
}
36
ответ дан Mark Buikema 16 August 2018 в 04:40
поделиться
  • 1
    Это, безусловно, самое чистое решение, и я впервые использовал рекурсию в производственном коде. – Aggressor 25 July 2016 в 22:54
  • 2
    @Aggressor, почему вам нужно регистрировать 4000+ длинных сообщений на производстве? – TWiStErRob 10 September 2016 в 09:24
  • 3
    @TWiStErRob Очень большие объекты, которые необходимо стягивать. Например. массив с тысячами мест. – Aggressor 10 September 2016 в 15:49
  • 4
    @Aggressor вопрос был направлен на часть production . Зачем вам нужно регистрировать эти тысячи строк на каждом устройстве пользователя? – TWiStErRob 10 September 2016 в 16:11
  • 5
    Мой вариант использования - вывести большой материал json. Файлы просто боль. – Marcel Falliere 7 March 2017 в 17:40

нас эта логика поискового вызова

    /*
     * StringBuffer sb - long text which want to show in multiple lines 
     * int lenth - lenth of line need
     */

public static void showInPage(StringBuffer sb, int lenth) {
    System.out.println("sb.length = " + sb.length());
    if (sb.length() > lenth) {

        int chunkCount = sb.length() / lenth; // integer division
        if ((chunkCount % lenth) > 1)
            chunkCount++;
        for (int i = 0; i < chunkCount; i++) {
            int max = lenth * (i + 1);
            if (max >= sb.length()) {
                System.out.println("");
                System.out.println("chunk " + i + " of " + chunkCount + ":"
                        + sb.substring(lenth * i));
            } else {
                System.out.println("");
                System.out.println("chunk " + i + " of " + chunkCount + ":"
                        + sb.substring(lenth * i, max));
            }
        }
    }

}
2
ответ дан neeraj t 16 August 2018 в 04:40
поделиться

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

if (sb.length() > 4000) {
    Log.v(TAG, "sb.length = " + sb.length());
    int chunkCount = sb.length() / 4000;     // integer division
    for (int i = 0; i <= chunkCount; i++) {
        int max = 4000 * (i + 1);
        if (max >= sb.length()) {
            Log.v(TAG, "chunk " + i + " of " + chunkCount + ":" + sb.substring(4000 * i));
        } else {
            Log.v(TAG, "chunk " + i + " of " + chunkCount + ":" + sb.substring(4000 * i, max));
        }
    }
} else {
    Log.v(TAG, sb.toString());
}

Отредактировано, чтобы показать последнюю строку!

81
ответ дан Travis 16 August 2018 в 04:40
поделиться
  • 1
    Спасибо за это! Я также собирался собирать длинные данные – Someone Somewhere 29 June 2012 в 22:47
  • 2
    Нет проблем! Надеюсь, это помогло вам – Travis 3 July 2012 в 18:50
  • 3
    Вы потеряли последнюю строку в: int chunkCount = sb.length() / 4000; Используйте int chunkCount = sb.length() / 4000; if (chunkCount * 4000 < sb.length()) chunkCount++; – Timur Gilfanov 20 February 2013 в 18:55
  • 4
    добавьте else { Log.v(TAG, sb); }, чтобы также распечатать журнал, когда сообщение равно & lt; = 4000 символов – Bojan Radivojevic Bomber 26 April 2014 в 22:45
  • 5
    Этот ответ неверен для символов, отличных от ASCII. logcat поддерживает UTF8, а ограничение - 4k bytes , а не символы. – miguel 14 April 2015 в 23:46
for( String line : logMesg.split("\n") ) {
    Log.d( TAG, line );
}
10
ответ дан user2085092 16 August 2018 в 04:40
поделиться

Я не знаю какой-либо опции для увеличения длины logcat, но мы можем найти разные журналы, такие как основной журнал, журнал событий и т. д. Основной журнал обычно содержит все его длину до 4 Мб. Поэтому вы можете получить что вы потеряли в лог-терминале. Путь: \ data \ logger.

0
ответ дан Vins 16 August 2018 в 04:40
поделиться
Другие вопросы по тегам:

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