Как я могу использовать StreamWriteAsText () для записи данных типа Number? - PullRequest
1 голос
/ 14 мая 2019

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

Для этого я пытаюсь многократно записывать одномерное изображение в поток файлов во времени, используя функцию ImageWriteImageDataToStream().Для этого я присоединяю объект Listener к виду, который я читаю, и этот слушатель выполняет функцию, которая записывает изображение в поток файлов, используя ImageWriteImageDataToStream() каждый раз, когда данные изменяются (messagemap = "data_changed:MyFunctiontoExecute").

Мой вопрос: есть ли способ также записать отметку времени в этот же поток файлов?

Все, что я могу найти, это StreamWriteAsText (), который принимает тип данных String.Могу ли я преобразовать время типа Number в тип String?

У кого-нибудь есть лучший способ сделать это?

Мое решение на данный момент состоит в том, чтобы создать отдельный файл одновременно и записать время с помощью WriteFile (), чтобы не использовать поток файлов.

//MyFunctiontoExecute, where Img is the 1D image at the current time
My_file_stream.StreamSetPos(2,0)
ImageWriteImageDataToStream(Img, My_file_stream, 0)

//Write the time to the same file
Number tmp_time = GetHighResTickCount() - start_time
My_file_stream.StreamSetPos(2,0)

My_file_stream.StreamWriteAsText(0,tmp_time) //does not work

//instead using a different file
WriteFile(My_extrafileID,tmp_time+"/n")

1 Ответ

1 голос
/ 14 мая 2019

Я думаю, что ваша концепция потоковой передачи неверна. При потоковой передаче в файл в конце команд toStream() позиция потока уже находится в конце . Таким образом, вы не устанавливаете позицию.

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

Команда StreamSetPos () нужна вам только тогда, когда вы хотите перепрыгнуть через некоторые разделы во время чтения (полезно, например, при определении скриптов импорта для определенных форматов файлов. Или для извлечения только определенных подмножеств из файла. ).

Если все, что вы хотите сделать, - это "вывести некоторые необработанные данные" , вы делаете именно это: просто вызывайте команды друг за другом:

void WriteDataPlusDateToStream( object fStream, image img, string dateStr )
{
    number endian = 0
    number encoding = 0
    img.ImageWriteImageDataToStream(fStream,endian)
    fStream.StreamWriteAsText(encoding,dateStr) 
}

Точно так же вы просто «впускаете» , просто следуя той же последовательности:

void ReadDataPlusDateFromStream( object fStream, image img, string &dateStr )
{
    number endian = 0
    number encoding = 0
    img.ImageReadImageDataFromStream(fStream,endian)
    fStream.StreamReadTextLine(encoding,dateStr)    
}

Здесь важны две вещи:

  • в ImageReadImageDataFromStream это размер и тип данных изображения img, который определяет, сколько байтов считывается из потока и как они интерпретируются. Следовательно, img должно быть предварительно создано и имеет подходящий размер и тип файла.

  • в StreamReadTextLine поток будет считываться в как текст , пока не встретится символ конца строки (\n) или конец поток. Поэтому убедитесь, что записываете этот символ конца строки при потоковой передаче. Кроме того, вы можете убедиться, что строки всегда имеют определенный размер, а затем использовать StreamReadAsText с соответствующей указанной длиной.

Используя два вышеуказанных метода, вы можете использовать следующий тест-скрипт в качестве отправной точки:

void WriteDataPlusDateToStream( object fStream, image img, string dateStr )
{
    number endian = 0
    number encoding = 0
    img.ImageWriteImageDataToStream(fStream,endian)
    fStream.StreamWriteAsText(encoding,dateStr) 
}
void ReadDataPlusDateFromStream( object fStream, image img, string &dateStr )
{
    number endian = 0
    number encoding = 0
    img.ImageReadImageDataFromStream(fStream,endian)
    fStream.StreamReadTextLine(encoding,dateStr)    
}


void writeTest(string path)
{
    Result("\n Writing to :" + path )
    image testImg := RealImage("Test",4,100)
    string dateStr;
    number loop = 5;

    number doAutoClose = 1
    object fStream = NewStreamFromFileReference( CreateFileForWriting(path), doAutoClose )
    for( number i=0; i<loop; i++ )
    {
        testImg = icol * random()
        dateStr = GetDate(1)+"@"+GetTime(1)+"|"+Format(GetHighResTickCount(),"%.f") + "\n"
        fStream.WriteDataPlusDateToStream(testImg,dateStr)
        sleep(0.33)
    }
}

void readTest(string path)
{
    Result("\n Reading form :" + path )
    image testImg := RealImage("Test",4,100)
    string dateStr;
    number doAutoClose = 1
    object fStream = NewStreamFromFileReference( OpenFileForReading(path), doAutoClose )
    while ( fStream.StreamGetPos() < fStream.StreamGetSize() )
    {
        fStream.ReadDataPlusDateFromStream(testImg,dateStr)
        result("\n time:"+dateStr)
        testImg.ImageClone().ShowImage()
    }
}

string path = "C:/test.dat"
ClearResults()
writeTest(path)
readTest(path)

Обратите внимание, что при потоковой передаче «двоичных данных», подобных этой, you определяет формат файла. Вы должны убедиться, что код записи и чтения совпадает.

...