Как я нахожу длину ассоциативного массива в ActionScript 3.0?

После некоторого поиска я обнаружил, что FileSystemWatcher вызывает событие только после закрытия файла, как показано в этой статье . В статье упоминается только дата изменения NotifyFilter, но в моем тестировании я обнаружил, что все Notifyfilters срабатывают после закрытия файла и никогда, пока он еще открыт.

По этой причине, похоже, что следит за , файл возможен только с помощью зацикленной функции, которая непрерывно отслеживает файл на наличие дополнительных строк. Я использовал код этой ссылки в качестве примера.

Вот мой рабочий код:

[TestClass]
public class FileWriteTests
{

    [TestMethod]
    public void TestMethodAfterClose_filetailing()
    {

        var currentDir = Environment.CurrentDirectory;
        var fileToMonitor = "test.txt";
        File.Delete(Path.Combine(currentDir, fileToMonitor));
        List output = new List();
        using (var watcherTest = new PersonalFileTail(currentDir, fileToMonitor))
        {
            watcherTest.StartTail(delegate (string line) { output.Add(line); });
            using (var writer = new StreamWriter(Path.Combine(currentDir, fileToMonitor), true))
            {
                writer.WriteLine($"test");
                writer.Flush();
            }
            System.Threading.Thread.Sleep(200);
            watcherTest.StopTail();
        }
        System.Threading.Thread.Sleep(10);
        Assert.AreEqual(1, output.Count);
        Assert.AreEqual("test", output[0]);
    }

    [TestMethod]
    public void TestMethodAfterFlush_filetailing()
    {
        // initiate file
        var currentDir = Environment.CurrentDirectory;
        var fileToMonitor = "test.txt";
        File.Delete(Path.Combine(currentDir, fileToMonitor));
        FileInfo info = new FileInfo(Path.Combine(currentDir, fileToMonitor));

        List output = new List();
        using (var watcherTest = new PersonalFileTail(currentDir, fileToMonitor))
        {
            watcherTest.StartTail(delegate (string line) { output.Add(line); });
            using (var writer = new StreamWriter(Path.Combine(currentDir, fileToMonitor), true))
            {
                try
                {
                    writer.WriteLine($"test");
                    writer.Flush();
                    System.Threading.Thread.Sleep(1000);
                    Assert.AreEqual(1, output.Count);
                    Assert.AreEqual("test", output[0]);
                }
                catch
                {
                    Assert.Fail("Test failed");
                }
            }
            watcherTest.StopTail();
        }
    }

    public class PersonalFileTail : IDisposable
    {
        private string filename;
        private string directory;
        private Task fileTailTask;
        private Action handleResults;
        private volatile bool runTask;
        private long lastFilePosition;
        public string FileName
        {
            get { return Path.Combine(directory, filename); }
        }
        public PersonalFileTail(string directory, string filename)
        {
            this.directory = directory;
            this.filename = filename;
            this.runTask = false;
            lastFilePosition = 0;
        }

        public void StartTail(Action handleResults)
        {
            this.handleResults = handleResults;
            runTask = true;
            fileTailTask = Task.Run(() => MonitorFileTask());
        }

        public void StopTail()
        {
            runTask = false;
            fileTailTask.Wait();
        }

        public IEnumerable ReadLinesFromFile()
        {
            using (StreamReader reader = new StreamReader(new FileStream(FileName,
            FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
            {
                string line = "";
                while ((line = reader.ReadLine()) != null)
                {
                    yield return line;
                }
                lastFilePosition = reader.BaseStream.Length;
            }
        }

        public void MonitorFileTask()
        {
            StreamReader reader = null;
            FileStream stream = null;
            try
            {
                using(stream = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                using (reader = new StreamReader(stream))
                {
                    do
                    {
                        //if the file size has increased do something
                        if (reader.BaseStream.Length > lastFilePosition)
                        {
                            //seek to the last max offset
                            reader.BaseStream.Seek(lastFilePosition, SeekOrigin.Begin);

                            //read out of the file until the EOF
                            string line = "";
                            while ((line = reader.ReadLine()) != null)
                            {
                                handleResults(line);
                            }

                            //update the last max offset
                            lastFilePosition = reader.BaseStream.Position;
                        }
                        // sleep task for 100 ms 
                        System.Threading.Thread.Sleep(100);
                    }
                    while (runTask);
                }
            }
            catch
            {
                if (reader != null)
                    reader.Dispose();
                if (stream != null)
                    stream.Dispose();
            }
        }

        public void Dispose()
        {
            if(runTask)
            {
                runTask = false;
                fileTailTask.Wait();
            }
        }
    }
}

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

10
задан Matt Dillard 12 November 2008 в 18:53
поделиться

4 ответа

Необходимо включить их для цикла, как Вы делаете. Конечно, Вы могли сделать класс и придерживаться к циклу в том классе.

Для некоторого большого implmentations Наборов в AS3 проверьте этих парней.

Отредактируйте 2013 Не удивительно, ссылки действительно повреждаются после времени. Попробуйте этот новый: http://www.grindheadgames.com/get-the-length-of-an-object.

9
ответ дан 3 December 2019 в 20:07
поделиться

Выполнение нескольких тестов на этом на самом деле удивило меня. Вот нормальная эксплуатация Массива:

var things:Array = [];
things.push("hi!");
trace(things.length);
// traces 1
trace(things);
// traces hi!

Вот то, если мы устанавливаем значение к строке:

var things:Array = [];
things["thing"] = "hi!";
trace(things.length);
// traces 0
trace(things);
// traces an empty string
trace(things["thing"]);
// traces hi!

В основном, если Вы добавляете вещи с помощью строк, Вы устанавливаете свойства вместо того, чтобы на самом деле добавить к массиву. Заставляет меня задаться вопросом, почему Массив является динамическим таким образом.

Так... да считайте объекты с для... в цикле!

4
ответ дан 3 December 2019 в 20:07
поделиться
var count:int; 
var key:String; 

for (key in myObject)
{ 
    count++; 
} 

trace ("myObject has this many keys in it: " + count);

или, альтернативно, для - каждый синтаксис (я не протестировал для наблюдения, который быстрее),

for each (var o:* in myObject)
{
    count++;
}
3
ответ дан 3 December 2019 в 20:07
поделиться

Я думаю, что Вы застреваете с подсчетом их "вручную".

Опция состояла бы в том, чтобы перенести все это в класс и сохранить отдельную переменную, которую Вы обновляете, как Вы добавляете/удаляете.

3
ответ дан 3 December 2019 в 20:07
поделиться
Другие вопросы по тегам:

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