简体   繁体   English

使用 StreamWriter 的文件中的 NULL 符号

[英]NULL symbol in file using StreamWriter

I want to add simple logger in to my app.我想在我的应用程序中添加简单的记录器。 For this purpose I want to use StreamWriter .为此,我想使用StreamWriter

Code:代码:

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

As result all strings are correctly captured and output is correct, but sometimes it can write empty string with invisible characters at the end:结果所有字符串都被正确捕获并且 output 是正确的,但有时它可以在末尾写入带有不可见字符的空字符串:

sample:样本:

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

and if i check this with some tool that can show invisible characters , I can see next:如果我用一些可以显示不可见字符的工具检查这个,我可以看到下一个:

在此处输入图像描述

As result ~600 lines of log - 125 mb.结果 ~600 行日志 - 125 mb。

I have found that reason could be next:发现原因可能是下一个:

That happens.那个会发生。 When you append a file first its size is corrected in the directory (and that's transactional in NTFS) and then the actual new data is written.当您 append 时,首先在目录中更正文件的大小(这在 NTFS 中是事务性的),然后写入实际的新数据。 There's good chance that if you shut down the system you end up with a file appended with lots of null bytes because data writes are not transactional unlike metadata (file size) writes.很有可能,如果您关闭系统,您最终会得到一个附加大量 null 字节的文件,因为与元数据(文件大小)写入不同,数据写入不是事务性的。

There's no absolute solution to this problem.这个问题没有绝对的解决办法。

Also tried to也尝试过

check characters with isControl other similar checks;isControl其他类似的检查检查字符;

tried to Trim last characters;试图Trim最后一个字符;

checked docs - looks like all correct检查文档- 看起来都正确

Any advice?有什么建议吗?

In case someone faced with same issue - reason for me unknown and i may only guess.... but I rewrite logic with log system and bug disappear:万一有人遇到同样的问题-我的原因未知,我可能只能猜测....但是我用日志系统重写逻辑并且错误消失了:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM