Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.11.11;
Скачать: CL | DM;

Вниз

TStream   Найти похожие ветки 

 
pathfinder   (2007-10-18 20:34) [0]

Добрый вечер.
Подскажите пожалуйста, каким образом лучше сохранить данные из TMemoryStream в файл? Но не все содержимое, а только конец определенного размера.
У меня получилось что-то такое:

 FData: TMemoryStream;
 FLimit: Integer;
 Stream: TFileStream;
 StartPos: PByte;

 StartPos := FData.Memory;
 Inc(StartPos, FData.Size - FLimit);
 Stream := TFileStream.Create(FileName, fmCreate);
 Stream.WriteBuffer(StartPos^, FLimit);
 Stream.Free;


 
Jump   (2007-10-18 21:22) [1]

Передвинь указатель к нужной тебе позиции, и скопируй:

Count := 1024; // длина "хвоста" в байтах
MemoryStream.Seek(Сount, soFromEnd);
FileStream.CopyFrom(MemoryStream, Сount);


 
pathfinder   (2007-10-18 21:25) [2]


> Jump   (18.10.07 21:22) [1]


Спасибо!


 
pathfinder   (2007-10-18 22:16) [3]

Почему-то у меня с аналогичным кодом компилятор выдает ошибку Stream Read Error.


 
Anatoly Podgoretsky ©   (2007-10-18 22:19) [4]

Точное сообщение компилятора, с номером строки.


 
pathfinder   (2007-10-18 22:28) [5]

"Project ... raised exception class EReadError with message "Stream read error" "

возникает на строке Stream.CopyFrom(FData, FLimit);

 FData.Seek(FLimit, soFromEnd);
 Stream := TFileStream.Create(FileName, fmCreate);
 Stream.CopyFrom(FData, FLimit);
 Stream.Free;

И я не совсем понял почему в методе Seek к размеру потока прибавляется смещение в случае сдвига от конца..

function TCustomMemoryStream.Seek(Offset: Longint; Origin: Word): Longint;
begin
 case Origin of
   soFromBeginning: FPosition := Offset;
   soFromCurrent: Inc(FPosition, Offset);
   soFromEnd: FPosition := FSize + Offset;
 end;
 Result := FPosition;
end;


 
pathfinder   (2007-10-18 22:31) [6]

Причем если  Stream.CopyFrom(FData, 0); то ошибки нет..


 
Anatoly Podgoretsky ©   (2007-10-18 22:35) [7]

soFromEnd Offset is from the end of Memory. Offset must be <= 0 to indicate a number of bytes before the end of the memory buffer.


 
pathfinder   (2007-10-18 22:39) [8]


> Anatoly Podgoretsky ©   (18.10.07 22:35) [7]


Мда..как всегда меня подвела невнимательность.

Спасибо!


 
pathfinder   (2007-10-19 09:53) [9]

Добрый день!
А как лучше обрезать содержимое потока, так чтобы взять тоже его "хвост" определенной длины?
Пришло в голову только это:

procedure TLog.DecreaseData;
var
 Stream: TMemoryStream;
begin
 if FData.Size > FLogSizeLimit then begin
   FData.Seek(-FLogSizeLimit, soFromEnd);
   Stream := TMemoryStream.Create;
   Stream.CopyFrom(FData, FLogSizeLimit);
   FData.LoadFromStream(Stream);
   Stream.Free;
 end
end;

Как бы сделать это более оптимально?


 
pathfinder   (2007-10-19 09:54) [10]


> А как лучше обрезать содержимое потока, так чтобы взять
> тоже его "хвост" определенной длины?


Точней оставить только "хвост" определенного размера, а все что до этого удалить.


 
Reindeer Moss Eater ©   (2007-10-19 09:56) [11]

Как бы сделать это более оптимально?

изначально не писать в этот стрим ничего кроме "нужного хвоста".


 
pathfinder   (2007-10-19 10:02) [12]


> изначально не писать в этот стрим ничего кроме "нужного
> хвоста".


В стрим пишется лог. Мысль в том, чтобы при записи смотреть не превышает ли размер данных лимит и если превышает, то оставлять только "хвост" от данных в размере лимита.


 
Reindeer Moss Eater ©   (2007-10-19 10:05) [13]

Если текушая позиция + новая строка превысят лимит,  сместить указатель вначало и писать по старым записям.


 
pathfinder   (2007-10-19 10:23) [14]


> Если текушая позиция + новая строка превысят лимит,  сместить
> указатель вначало и писать по старым записям.


Получится не очень читабельно. Хотелось чтобы последние записи были в конце и их можно было сразу найти, а самые старые удалялись.


 
Reindeer Moss Eater ©   (2007-10-19 10:41) [15]

Получится не очень читабельно

У тебя люди непосредственно мемористрим читают?
Сила!


 
pathfinder   (2007-10-19 10:45) [16]


> У тебя люди непосредственно мемористрим читают?
> Сила!


Ну нет уж конечно:) Я его в файл сохраняю.


 
ЮЮ ©   (2007-10-19 10:46) [17]

> а самые старые удалялись

А у тебя самое старое место - начало лога - затретcя только тогда когда лог в памяти превысит отведенное место на диске. Во всех остальных случаях (по достижении максимально размера на диске) будет затираться самые свежие данные, которые всегда будут в конце лога.

P/S/ Или у тебя сохраняемый лог всегда больше отведенного места на диске?


 
Reindeer Moss Eater ©   (2007-10-19 10:49) [18]

Ну нет уж конечно:)

Тогда в чем проблема?
тем более если не хочется колбасить весь стрим после добавления очередной строки лога?


 
pathfinder   (2007-10-19 11:00) [19]

Я хотел сделать так:
1. Запуск программы и загрузка лога из файла в мемористрим.
2. Работа программы и запись событий лога в конец мемористрима.
3. Завершение работы программы и сохранение лога из мемористрима в файл. Здесь решение понятно.

> Count := 1024; // длина "хвоста" в байтах
> MemoryStream.Seek(Сount, soFromEnd);
> FileStream.CopyFrom(MemoryStream, Сount);

Но на случай длительной работы программы я хотел еще предусмотреть возможность контролировать размер мемористрима, чтобы он не разрастался слишком. Поэтому подумал делать проверку при записи нового события в лог. Только вот мой вариант не очень удачный, слишком медленно будет работать.


 
pathfinder   (2007-10-19 11:01) [20]


> Reindeer Moss Eater ©   (19.10.07 10:49) [18]


Так придется тогда перед сохранением в файл собирать лог по кусочкам.


 
Reindeer Moss Eater ©   (2007-10-19 11:13) [21]

Нафик вообще такой лог?


 
pathfinder   (2007-10-19 11:20) [22]


> Нафик вообще такой лог?


А какой лучше?


 
Reindeer Moss Eater ©   (2007-10-19 11:22) [23]

1. Запуск программы и загрузка лога из файла в мемористрим.

А зачем программе грузить лог из файла?
Она его что, почитывает сидя в кресле, когда заняться нечем?
:)


 
pathfinder   (2007-10-19 11:23) [24]


> А зачем программе грузить лог из файла?
> Она его что, почитывает сидя в кресле, когда заняться нечем?
>
> :)


Она его дешифрует. А перед записью в файл шифрует. Вот:)


 
Reindeer Moss Eater ©   (2007-10-19 11:24) [25]

Так она это уже сделала когда в прошлый раз шифровала.
Нафик грузить-то?


 
pathfinder   (2007-10-19 11:26) [26]


> Так она это уже сделала когда в прошлый раз шифровала.


Простите, не понял.


 
Reindeer Moss Eater ©   (2007-10-19 11:29) [27]

Есть файл лога, который бы зашифрован ранее.
Нафига программе грузить этот файл лога.
Зачем он ей?


 
pathfinder   (2007-10-19 11:29) [28]


> Нафик грузить-то?


Если вы имеете в виду, что лучше писать в другой файл, то хотелось бы их плодить.


 
Reindeer Moss Eater ©   (2007-10-19 11:30) [29]

Чувак, проснись!
Зачем программе старый лог?
Можешь ответить?


 
pathfinder   (2007-10-19 11:35) [30]


> Есть файл лога, который бы зашифрован ранее.
> Нафига программе грузить этот файл лога.
> Зачем он ей?
>


Чтобы дописать в него новые данные.
Программа шифрует/дешифрует все содержимое мемористрима xor-ом с ключом.
Если шифровать каждую строку и потом записывать, то как потом дешифровать файл? Как найти где конец каждой строки?


 
Reindeer Moss Eater ©   (2007-10-19 11:37) [31]

сняли задачу аварийно. лога нет.
зачем такой лог?


 
pathfinder   (2007-10-19 11:38) [32]


> сняли задачу аварийно. лога нет.
> зачем такой лог?


А какие варианты?


 
Reindeer Moss Eater ©   (2007-10-19 11:41) [33]

варианты есть, но они расчитаны на неизвращенное представление о логах.
тебе они не подойдут.


 
korneley ©   (2007-10-19 11:44) [34]


> Программа шифрует/дешифрует все содержимое мемористрима
> xor-ом с ключом
Ничего не понял... :( зачем "шифровать"  лог, да еще таким "уникальным" способом? Дабы непуганного пользователя в заблужбение ввести?


 
pathfinder   (2007-10-19 12:02) [35]


> зачем "шифровать"  лог, да еще таким "уникальным" способом?
>  Дабы непуганного пользователя в заблужбение ввести?


Ну примерно так.


 
pathfinder   (2007-10-19 12:25) [36]

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


 
Reindeer Moss Eater ©   (2007-10-19 12:28) [37]

шифровать потом кодировать в текст


 
Reindeer Moss Eater ©   (2007-10-19 12:32) [38]

либо шифровать цезарем


 
pathfinder   (2007-10-19 12:48) [39]


> шифровать потом кодировать в текст


Это как?


> либо шифровать цезарем


Ну это уж слишком просто. Так не интересно:)


 
pathfinder   (2007-10-19 14:01) [40]

А если программа будет добавлять записи лога непосредственно а файл через TFileStream, то как тогда лучше в ходе работы программы не допускать превышения размера файла?


 
Reindeer Moss Eater ©   (2007-10-19 14:08) [41]

Файл растет, если в него писать.
Как не допустить чтобы файл рос?


 
pathfinder   (2007-10-19 14:18) [42]


> Как не допустить чтобы файл рос?


Как я понимаю: 1) Не писать. 2) По мере превышения отрезать от него лишний кусочек.

Может есть лучшие варианты?


 
Reindeer Moss Eater ©   (2007-10-19 14:45) [43]

А может тебе лучше купить гуся и уже ему парить мозг?


 
Reindeer Moss Eater ©   (2007-10-19 14:46) [44]

По мере превышения отрезать от него лишний кусочек.

Умеешь "отрезать от файла кусочки"?
Вперед. Отрезай.


 
pathfinder   (2007-10-19 15:07) [45]


> Умеешь "отрезать от файла кусочки"?


В том то и дело, что нет:)


> Reindeer Moss Eater ©   (19.10.07 10:05) [13]
>
> Если текушая позиция + новая строка превысят лимит,  сместить
> указатель вначало и писать по старым записям.


Тогда придется запоминать позицию указателя при выходе из программы, чтобы при следующем запуске начать с того же места?


 
pathfinder   (2007-10-19 15:08) [46]


> > Умеешь "отрезать от файла кусочки"?


Я думал может кто-нибудь умеет:)


 
Сергей М. ©   (2007-10-19 15:16) [47]


> pathfinder   (19.10.07 15:08) [46]


Файл протокола у тебя структурированный ?
Или содержит записи переменной длины ?


 
pathfinder   (2007-10-19 15:20) [48]


> Файл протокола у тебя структурированный ?
> Или содержит записи переменной длины ?


Переменной.


 
Сергей М. ©   (2007-10-19 15:28) [49]

Тогда откуда тебе известен тот самый "определенный размер", который ты хотел оттяпать от файла или наоборот оставить в файле ?


 
pathfinder   (2007-10-19 15:34) [50]


> Тогда откуда тебе известен тот самый "определенный размер",
>  который ты хотел оттяпать от файла или наоборот оставить
> в файле ?


Текущий размер файла - максимально допустимый размер.


 
pathfinder   (2007-10-19 15:41) [51]

Подскажите пожалуйста, какие есть проверенные(шаблонные) методы для работы с лог файлами? Как обычно делают в нормальных программах?


 
Сергей М. ©   (2007-10-19 16:01) [52]


> Текущий размер файла - максимально допустимый размер


Скажем, размер файла 10 байт, ты хочешь записать в него протокольную запись размером 11 байт.

Куда девать 1 байт ? Оттяпать его от записи, чтобы запись влезла в файл ? Ну и нафих, спрашивается, нужет такой покоцаный протокол ? Что в нем можно прочитать после таких вот "оттяпываний" ради следования требованиям непревышения предельного размера ?


 
pathfinder   (2007-10-19 16:11) [53]


> Скажем, размер файла 10 байт, ты хочешь записать в него
> протокольную запись размером 11 байт.


Ну это слишком утрированный пример. Зачем же ограничивать размер лога десятью байтами? Я понимаю еще 10 мб.
Разве обычно не так делают?


 
Сергей М. ©   (2007-10-19 16:35) [54]


> Я понимаю еще 10 мб


А по барабану какой размер)

Ты обозначил некий предельный размер, а что делать, если очередная протокольная запись влазит в файл лишь частично ?

Подумай ..


 
pathfinder   (2007-10-19 16:46) [55]

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


 
Сергей М. ©   (2007-10-19 16:57) [56]


> сохранить заново в файл только например 75 процентов от
> этих данных


А если эти 75% придутся не на целое число протокольных записей ?

И в этом случае покоцаные данные в протоколе окажутся)

Думай ..


 
Leonid Troyanovsky ©   (2007-10-19 17:00) [57]


> pathfinder   (19.10.07 16:46) [55]

>  Но такой вариант мне не очень нравится..

Есть такой IStorage {StgCreateDocFile}, в коем можно
хранить данные как IStream, например, за один день (час).
А если оные устарели, то их можно и удалить.

Но, как оно коррелирует с размером файла -
я никогда не интересовался.

--
Regards, LVT.


 
pathfinder   (2007-10-19 17:05) [58]


>
> А если эти 75% придутся не на целое число протокольных записей
> ?
>
> И в этом случае покоцаные данные в протоколе окажутся)


Ну да.. это побочный эффект) Типизированный файл я не хотел, потому что у меня много коротких записей, но есть и весьма длинные. Но это не самое неприятное. Мне больше всего не нравится, что надо его полностью загружать и сохранять заново. А можно с помощью методов TFileStream обрезать файл без его загрузки и сохранения?


 
Anatoly Podgoretsky ©   (2007-10-19 19:37) [59]

> pathfinder  (19.10.2007 12:02:35)  [35]

Ну так назови файл - "Не открывать, убьет"


 
Anatoly Podgoretsky ©   (2007-10-19 19:38) [60]

> pathfinder  (19.10.2007 12:48:39)  [39]

А кто просил совсем простой, не ты ли?


 
Anatoly Podgoretsky ©   (2007-10-19 19:38) [61]

> pathfinder  (19.10.2007 14:18:42)  [42]

А эти чем плохи?


 
Anatoly Podgoretsky ©   (2007-10-19 19:39) [62]

> pathfinder  (19.10.2007 16:11:53)  [53]

Обычно так не делают.


 
pathfinder   (2007-10-19 21:55) [63]


> Ну так назови файл - "Не открывать, убьет"


Это мысль:)


> А кто просил совсем простой, не ты ли?


Нет, не я.. Я просил не очень сложный:)


> А эти чем плохи?


Невозможностью реализации.


> Обычно так не делают.


А как делают?


 
Jump   (2007-10-19 22:25) [64]

А можно с помощью методов TFileStream обрезать файл без его загрузки и сохранения?

Представь себе веревку длиной 2 метра, привязанную к потолку, а с другого конца - привязана гиря. Высота потолка - 3 метра. Задание: обрезать веревку до длины в 1 метр таким образом, чтобы гиря продолжала висеть на высоте 1 метра от пола.

Вот это где-то приблизительно то, что ты хочешь сделать с файлом - обрезать его начало, но так, чтобы конец файла не переместился.

Удачи...


 
pathfinder   (2007-10-19 22:46) [65]


> Jump   (19.10.07 22:25) [64]


Намек понял:) Спасибо за разъяснения.



Страницы: 1 2 вся ветка

Текущий архив: 2007.11.11;
Скачать: CL | DM;

Наверх




Память: 0.62 MB
Время: 0.02 c
2-1192457940
foreverDelphi
2007-10-15 18:19
2007.11.11
как вывести текст


2-1192701788
dumka
2007-10-18 14:03
2007.11.11
Скины


15-1191811318
Slider007
2007-10-08 06:41
2007.11.11
С днем рождения ! 8 октября 2007 понедельник


8-1168752381
9903
2007-01-14 08:26
2007.11.11
Компоненты для работы c wma mp3


2-1192180654
Ega23
2007-10-12 13:17
2007.11.11
Как убить объект из его же метода?