NULL-символ в файле с использованием StreamWriter - PullRequest
1 голос
/ 22 апреля 2020

Я хочу добавить простой регистратор в мое приложение. Для этой цели я хочу использовать StreamWriter.

Код:

private StreamWriter OutputStream;
OutputStream = new StreamWriter(this.LogFilePath, true);

// .... message - log from app

DateTime now = DateTime.Now;
message = string.Format("[{0:yyyy-MM-dd H:mm:ss}] {1}", now, message
if (OutputStream != null)
{
    OutputStream.WriteLine(message);
    OutputStream.Flush();
}

В результате все строки правильно перехвачены и выходные данные верны, но иногда он может написать пустую строку с невидимыми символами в конце:

образец:

 [1970-08-31 14:56:26] Command response -> !c:65:f9:1b:82:97

и если я проверю этот с помощью какого-либо инструмента, который может отображать невидимые символы , я могу видеть следующее:

enter image description here

В результате ~ 600 строк журнала - 125 МБ.

У меня найдено , что Причина может быть следующей:

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

Абсолютного решения этой проблемы не существует.

Также пытался

проверять символы с помощью isControl других подобных проверок;

пытался Trim последние символы;

проверял документы - выглядит все правильно

Любой совет?

1 Ответ

1 голос
/ 28 апреля 2020

В случае, если кто-то столкнулся с той же проблемой - причина для меня неизвестна, и я могу только догадываться .... но я переписываю logi c с системой журналов, и ошибка исчезает:

using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;

public class EventLogger : MonoBehaviour
{
    private string logFileName = "btlog.txt";
    public bool EchoToConsole = true;
    public bool AddTimeStamp = true;
    public bool EnableFileStorage = true;

    private string LogFilePath
    {
        get
        {
            return Path.Combine(Application.persistentDataPath, logFileName);
        }
    }

    private static EventLogger Singleton = null;
    const string format = "yyyy-MM-dd HH:mm:ss.fffffff";

    public static EventLogger Instance
    {
        get { return Singleton; }
    }

    void Awake()
    {
        if (Singleton != null)
        {
            UnityEngine.Debug.LogError("Multiple EventLogger Singletons exist!");
            return;
        }

        Singleton = this;

        if (this.EnableFileStorage)
        {
            if (File.Exists(LogFilePath))
            {
                long length = new FileInfo(LogFilePath).Length;
                int limit = 1024 * 1024 * 5; // 5mb
                if (length > limit)
                {
                    File.Delete(LogFilePath);
                    Log("log file removed");
                }
            }

            Log("-------------------");
            Log("NEW SESSION STARTED");
        }
    }

    private async Task Write(string message)
    {
        if (this.EnableFileStorage)
        {
            if (AddTimeStamp)
            {
                DateTime now = DateTime.Now;

                string strDate = now.ToString(format);
                string trimmed = new string(message.Where(c => !char.IsControl(c)).ToArray());
                message = string.Format("[{0}] {1}", strDate, trimmed);
            }

            using (StreamWriter outputStream = new StreamWriter(this.LogFilePath, true))
            {
                await outputStream.WriteLineAsync(message);
            }

            if (EchoToConsole)
            {
                UnityEngine.Debug.Log(message);
            }
        }
    }

    [Conditional("DEBUG"), Conditional("PROFILE")]
    public static void Log(string Message)
    {
        if (EventLogger.Instance != null)
        {
            _ = EventLogger.Instance.Write(Message);
        }
        else
        {
            UnityEngine.Debug.Log(Message);
        }
    }
}
...