问题 在文件流方面寻求帮助

威兹巴格德

新成员
已加入
2018年10月12日
留言内容
1
编程经验
10+
我正在尝试通过GitHub向现有项目添加其他功能,该功能已被其创建者放弃,并已获得MIT许可。
目的:
-Monitor DayZServer_x64.ADM进行更改
-抓住最后2nd最后一行(最后一行始终为空行)
-检查字符串是否包含单词"被玩家杀死"
-将括号内的任何东西剥离(包括在内)并清理多余的空间
-发送要宣布的字符串到播音员方法

我的主要问题是对文件流和Steamreader的了解不足。我还遇到一些问题,需要找出初始化日志读取器的正确方法。

任何帮助将不胜感激。我花了一个星期的时间尝试许多方法,但是我得到的最接近的方法严重延迟了(由于触发的方法触发得不够频繁),而且只有部分代码行。

我的仓库的分支可以在这里找到:
//github.com/Wizbaggd/DaRT

我的补充是:

Program.cs:第117行至128行-创建实例(并启动阅读器)
Classs / RCon.cs-行-1008-1022(从日志文件中接收最新行,并确定是否需要将其作为管理员消息发送出去)
Classes / ADMReader.cs-整个文档(不确定在这里是否做过任何事情)

Settings.Default。*包含设置,例如admFile是DayZServer_x64.ADM文件的完整文件路径,并且已设置"using"在Program.cs,ADMReader.cs和RCon.cs中。

C#:
// From Program.cs: Line 117-128
#region ADM Reader
ADMReader myADMReader = new ADMReader();
if (Settings.Default.admFile.Contains("DayZServer_x64.ADM")) {
    myADMReader.Start(Settings.Default.admFile);
    if (myADMReader.hasUpdated) {
        rcon.HandleKillFeed(myADMReader.currentLineRead);
        myADMReader.hasUpdated = false;
    }
}
#endregion

C#:
// From Classes\RCon.cs Line 1008
public void HandleKillFeed(string killfeedinput) {
    if (Settings.Default.killFeed) {
        if (killfeedinput.Contains("被玩家杀死")) {
            killfeedinput = Regex.Replace(killfeedinput, @"\(.*\)", "");
            // Remove extra spaces.
            killfeedinput = Regex.Replace(killfeedinput, @"\s+", " ");
            //_form.Log("Kill Feed Message: " + killfeedinput, LogType.Debug, true);
            _client.SendCommand(BattlEyeCommand.Say, "-1 " + killfeedinput);
        }
    }
}

C#:
// File Classes\ADMReader.cs - entire file.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DaRT.Properties; //Contains Settings.Default.*


namespace ADMLogReader {
    class ADMReader {
        static private string _currentLineRead;
        static private bool _hasUpdated;


        public string currentLineRead {
            get {
                return _currentLineRead;
            }
        }


        public bool hasUpdated {
            get {
                return _hasUpdated;
            } set {
                _hasUpdated = value;
            }
        }


        public void Start(string file) {
            hasUpdated = false;
            Watch(file);
        }


        private static void Watch(string file) {
            string admFileName = Path.GetFileName(file);
            string admFileDir = new DirectoryInfo(file).Name;


            var watch = new FileSystemWatcher();
            watch.Path = admFileDir;
            watch.Filter = admFileName;
            watch.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.CreationTime; //more options
            watch.Created += new FileSystemEventHandler(OnChanged);
            watch.Changed += new FileSystemEventHandler(OnChanged);
            watch.EnableRaisingEvents = true;
        }


        private static void OnChanged(object source, FileSystemEventArgs e) {
            if (e.FullPath == Settings.Default.admFile) {
                _hasUpdated = true;
                ReadMyFile();
            } else {
                _hasUpdated = false;
            }
        }


        private static void ReadMyFile() {
            // if you want to read more lines change this to the ammount of lines you want
            const int LINES_KEPT = 2;
            string emptyLineRemover = "";


            Queue<string> meQueue = new Queue<string>();
            using (var fs = new FileStream(Settings.Default.admFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 16384))
            using (var sr = new StreamReader(fs, Encoding.Default)) {
                string lineIn = string.Empty;
                while ((lineIn = sr.ReadLine()) != null) {
                    if (meQueue.Count == LINES_KEPT)
                        meQueue.Dequeue();
                    meQueue.Enqueue(lineIn);
                }
                _currentLineRead = meQueue.Dequeue();
                emptyLineRemover = meQueue.Dequeue();
            }
        }
    }
}

FileStream是必需的,因为文件在服务器运行时被服务器写锁定。不幸的是,File.ReadLine()不是一个选项,因为它会使整个过程变得更加容易。
 
Last edited:
最佳 底部