Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.11.11;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.6 MB
Время: 0.05 c
8-1168871218
olegnik
2007-01-15 17:26
2007.11.11
сжатия изображения bitmap.


4-1178388982
buben
2007-05-05 22:16
2007.11.11
Application.Handle


2-1192799860
Friz
2007-10-19 17:17
2007.11.11
ShellExecute


15-1191966748
Petr V. Abramov
2007-10-10 01:52
2007.11.11
действительно сломалось все


15-1191770712
TUser
2007-10-07 19:25
2007.11.11
Как поставить Symantec под Vista





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский