使用 StreamWriter 的文件中的 NULL 符号

Posted

技术标签:

【中文标题】使用 StreamWriter 的文件中的 NULL 符号【英文标题】:NULL symbol in file using StreamWriter 【发布时间】:2020-08-05 02:51:55 【问题描述】:

我想在我的应用中添加简单的记录器。 为此,我想使用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

如果我检查这个with some tool that can show invisible characters,我可以看到下一个:

结果 ~600 行日志 - 125 mb。

我有 found 这个原因可能是下一个:

会发生这种情况。当您首先附加文件时,其大小会在 目录(在 NTFS 中是事务性的),然后是实际的 写入新数据。很有可能如果你关闭 系统你最终会得到一个附加了很多空字节的文件,因为 与元数据(文件大小)写入不同,数据写入不是事务性的。

这个问题没有绝对的解决办法。

也试过

isControl其他类似的检查检查字符;

尝试Trim最后一个字符;

检查docs - 看起来都正确

有什么建议吗?

【问题讨论】:

你如何阅读文件? 我不会,只是写,追加新行OutputStream.WriteLine 不,你必须这样做。如果您不阅读该文件,您怎么知道该文件包含空字符? 我从移动设备下载它并通过glogg在电脑上打开本地。对于写作,我想我不应该读它,因为new StreamWriter(this.LogFilePath, true); - 附加文件和OutputStream.WriteLine 简单的附加流(如果我从docs.microsoft.com/en-us/dotnet/api/… 理解正确的话) @0xBFE1A8 我测试了您的建议,但没有任何帮助.. 但我更新了一些逻辑,现在看起来它正在创建大小正确的日志文件 - 请检查我的答案以获取参考,并感谢您的帮助跨度> 【参考方案1】:

如果有人遇到同样的问题 - 我的原因未知,我可能只能猜测....但是我用日志系统重写逻辑并且错误消失了:

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

【讨论】:

以上是关于使用 StreamWriter 的文件中的 NULL 符号的主要内容,如果未能解决你的问题,请参考以下文章

c#中文件读写StreamWriter问题

StreamWriter 输出 ... 在 .txt 文件的末尾

使用 StreamWriter 将行附加到文件

C# 使用从 FileStream 创建的 StreamWriter 覆盖文件

关闭窗体后,利用StreamWriter保存控件里面的数据

FileStream读写文件StreamWriter 和 StreamReader