procedure TForm1.Button1Click(Sender: TObject);
var
F1, F2: TextFile;
Ch: Char;
begin
if OpenDialog1.Execute then begin
AssignFile(F1, OpenDialog1.Filename);
Reset(F1);
if SaveDialog1.Execute then begin
AssignFile(F2, SaveDialog1.Filename);
Rewrite(F2);
while not Eof(F1) do
begin
Read(F1, Ch);
Write(F2, Ch);
end;
CloseFile(F2);
end;
CloseFile(F1);
end;
end;
Как узнать его структуру файла
У меня старичок Siemens S65 так вот проблема такая: у меня на компьютере установлена программа Mobile Phone Manager которая шла вместе с телефоном. Данная программа позволяет выполнять с телефоном разные операции (запись картинок, музыки и т.д.) и среди них есть возможность отправлять SMS и MMS прямо с компьютера, набирая текст на клавиатуре. Только у меня почему то можно отправлять только SMS, а MMS нет (кнопка не активна). Читал инструкцию – должно быть, ан нет. Облазил все настройки – бесполезно. Т.е. MMS с компьютера отправить нельзя.
А в последнее время меня очень привлекает возможность отправлять по MMS много текста (до 1000 знаков как говорят), а не так что SMS разбивается на 3-4 sms-ки и ты платишь за каждую.
Когда отправляешь MMS с телефона, то текст можно «забить» вручную или вставить из предварительно созданного файла. Файл можно создать только в самом телефоне, телефон создает его с расширением .tmo. Я хочу сделать следующее: в программе где-нибудь в Memo печатаешь текст, нажимаешь кнопку и сохраняешь это всё в файл с расширением .tmo. Ведь большой обьем текста на клавиатуре набрать проще чем на телефоне. Затем закидываем файл в телефон и прикрепляем к MMS.
Проблема в том что я не знаю структуру tmo файла. Через Блокнот он не открывается. Т.е. текст хранится в каком то собственном формате. Можно ли имея только сам файл узнать его структуру. Или другими словами как его прочитать и как в него записать?
Посмотрел в «Энциклопедия расширений файлов» там сказано:
.TMO - ZTG global optimizer default output file ;Zortech C++
Т.е. типа файл не несет никакой смысловой нагрузки. И что? Как его прочесть? Телефон же как то читает.
Попробывал вот так:
Код:
Если сохранить в txt формат, то вроде как текст получается (с небольшими закорючками правда). Но этого мало. На форумах по siemens никто не знает и программы для конвертации txt в tmo нет, поэтому решил сам взяться.
Итак подводя итог: Есть файл. Как узнать его структуру, как его прочитать и как в него записать?
Прикрепляю сам файл. Я создал его в телефоне и написал в нем одно слово-«Dima». Хотя можно и по русски, но это не важно.
[color=red]Для оформления кода используй теги. Модератор.[/color]
P.S. просматривать файлы удобнее будет не Блокнотом, а каким либо HEX редактором или просмотрщиком TotalComander`a
Попробуй сделать несколько таких файлов - с разным текстом, разной длины. Потом можно будет поискать закономерность. Потому как мне пока не понятно, почему в конце вместо символа "а" стоит "0♦t♦". Возможно это окончание зависит от длины текста. Увы, под рукой нет Siemens`a.
В Unicode все организовано элементарно просто и логично: если первый байт
равен нулю, то второй соответствует начертанию символа из таблицы ASCII
(или, что то же самое, английскому языку). Если же, к примеру, первый байт
равен 4, то это кириллица. Русские буквы в таблице располагаются подряд,
начиная со значения младшего байта, равного 16, "Ё" и "е", как всегда, от-
отдельно. Всякие фигурные кавычки и прочие длинные тире выбираются из отдельных таблиц со своим значением первого байта.
В принципе, если вы имеете некий Unicode-шрифт со всеми мыслимыми на-
начертаниями знаков, то можете писать многоязычный текст на всех языках
вперемешку. Правда, такой шрифт известен пока только один: это Arial
Unicode MS, который имеет объем более 13 Мбайт, и оттого может еще и за-
заработать не на всяком компьютере. Но на практике выше головы хватает и
десятка заполненных национальных страниц — что и наблюдается в ходовых
TTF-шрифтах.
В этой же книге есть пример как прочитать Unicode и переделать в txt (см. исходник).
Но он читает с небольшими «крякозяблами» т.е. получаем не чистый текст, хотя читать можно.
Все равно не пойму как записать такой файл если у меня есть txt (т.е. txt --> tmo). Как не пытался телефон твердит «Невозможно открыть файл». Чего то ему еще не хватает, но чего?
странно, а Lister (из TC который) при установке опций просмотра Unicode отображает чисто Dima с непечатаемым символом в начале слова и в конце
2Михаил, странно, я смотрел Hiew'ом и наблюдал картину, почти идентичную второму скриншоту.
Файл и что в нем написано:
Кузнец 1.tmo - В траве сидел
Unic.tmo - В Юникод всё организовано просто и логично: если
первый байт равен нулю, то второй соответствует
начертанию из таблицы
Unic 1.tmo - В Юникод всё организовано просто и логично: если
первый байт равен нулю
Unic 2.tmo - В Юникод всё организовано просто и логично
Точек в конце фраз нет.
Zbyszek похоже ты прав насчет длинны. Обрати внимание на Unic.tmo, Unic 1.tmo и Unic 2.tmo. Если открыть через блокнот, то сразу видно, что к фразе что то добавляется вначале и в конце. Я думаю это какой то идентификатор и если его нет телефон отказывается читать файл.
Может телефон считает длинну строки и добавляет к файлу, а потом при открытии проверяет длинну и очень длинные фразы не открывает (памяти мало). Ну это так предположение.
[QUOTE="Штирлиц"]Кузнец 1.tmo - <новая строка>В траве сиделi
Unic.tmo - vВ Юникод всё организовано просто и логично: если первый байт равен нулю, то второй соответствует начертанию из таблицыС
Unic 1.tmo - GВ Юникод всё организовано просто и логично: если первый байт равен нулюю
Unic 2.tmo - *В Юникод всё организовано просто и логично<непечатный символ>
TmoFile.tmo - <непечатный символ>Dimаt[/QUOTE]
Видимо, первые и последние байты - что-то вроде контрольной суммы, и если она не сходится, то телефон отказывается открывать файл. Если для файлов со строками одинаковой длины но разного содержания эти байты будут разными, то, скорее всего, будет очень сложно понять, как написать конвертор txt->tmo.:(
Кузнец.tmo - В траве стоял
Кузнец 1.tmo - В траве сидел
Метро.tmo - Думал в метро
Байты в начале и в конце одинаковые у всех файлов. Контрольная сумма? Что с ней делать? По какому алгоритму посчитать?
Цитата: mr_smit
Три файла одинаковой длинны:
Кузнец.tmo - В траве стоял
Кузнец 1.tmo - В траве сидел
Метро.tmo - Думал в метро
Байты в начале и в конце одинаковые у всех файлов. Контрольная сумма? Что с ней делать? По какому алгоритму посчитать?
Кузнец.tmo - В траве стоял
Кузнец 1.tmo - В траве сидел
Метро.tmo - Думал в метро
Байты в начале и в конце одинаковые у всех файлов. Контрольная сумма? Что с ней делать? По какому алгоритму посчитать?
первый байт это длина сообщение, т.е. количество символов, про последний пока не знаю
Hullo.tmo - Hullo !!! )))
Первый – длина строки
Второй – нулевой байт
Предпоследний - ???? не пойму как считается
Последний – при нечетной длинне строки 4, при четной длинне строки 0.
На картинке представлены некоторые мои эксперименты, всё более наглядно (см. прикрепл. изображение). Предпоследний байт каким то образом связан с регистром букв (большая или маленькая). Но каким образом известно одному Сименсу. Может у кого есть соображения на этот счет.
Не открывает. "Невозможно открыть файл".
первые 2 байта это длина сообщения, далее идет текст в формате UTF-16LE, затем наверное контрольная сумма, ты попробуй создать сообщение из одного символа, затем из 2 таких же и так далее и проследи за изменением последних байт
10 файлов. В первом одна буква ‘н’, во втором две, в третьем три и т. д. Предпоследний байт (контрольная сумма) в десятичной системе (‘н’ в десятичной системе 61):
1. 60
2. 2
3. 62
4. 4
5. 56
6. 6
7. 58
8. 8
9. 52
10. 10
Ещё 10 файлов. В первом одна буква ‘а’, во втором две, в третьем три и т. д. Предпоследний байт (контрольная сумма) в десятичной системе (‘а’ в десятичной системе 48):
1. 49
2. 2
3. 51
4. 4
5. 53
6. 6
7. 55
8. 8
9. 57
10. 10
Ну если ‘а’ ещё хоть на что то похоже, то ‘н’, особенно нечетное количество, вообще не понятно.
Да кстати я напортачил в самом первом файле. Там последняя 'а' русская. Исправленный файл в архиве.
вот так:
Код:
var fs:TFileStream;
l,crc,i,t:word;
begin
fs:=TFileStream.Create('tmofile.htm',fmOpenRead);
try
fs.Read(l,2);
if l<>0 then
begin
fs.Read(crc,2);
crc:=crc xor l;
for i:=1 to l-1 do
begin
fs.Read(t,2);
crc:=crc xor t;
end;
ShowMessage(IntToHex(crc,4));
end;
finally
fs.Free;
end;
l,crc,i,t:word;
begin
fs:=TFileStream.Create('tmofile.htm',fmOpenRead);
try
fs.Read(l,2);
if l<>0 then
begin
fs.Read(crc,2);
crc:=crc xor l;
for i:=1 to l-1 do
begin
fs.Read(t,2);
crc:=crc xor t;
end;
ShowMessage(IntToHex(crc,4));
end;
finally
fs.Free;
end;
Код:
...
const
Byte04: Byte = $04;
Byte00: Byte = $00;
var
Form1: TForm1;
ff:file;
implementation
{$R *.dfm}
procedure TForm1.N1Click(Sender: TObject);
var i:integer;
s:string;
t: byte;
begin
if SaveDialog1.Execute then
begin
assignfile(ff,SaveDialog1.FileName+'.tmo');
rewrite(ff,1);
s:=Memo1.Text;
for i:=1 to length(s) do
begin
case s of
'а': t:=$30;
'б': t:=$31;
'в': t:=$32;
'г': t:=$33;
'д': t:=$34;
'е': t:=$35;
'ё': t:=$51;
'ж': t:=$36;
'з': t:=$37;
'и': t:=$38;
'й': t:=$39;
'к': t:=$3A;
',': t:=$2C;
'.': t:=$2E;
' ': t:=$20;
'?': t:=$3F; // и т.д.
else t:=$3F; // если что то другое - знак вопроса ?
end;
blockwrite(ff, t,1);
if (t=$2C) or (t=$2E) or (t=$20) or (t=$3F) then begin
blockwrite(ff,Byte00,1);
end
else begin
blockwrite(ff,Byte04,1);
end;
end;
closefile(ff);
end;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
memo1.Text:='ёж, газ, бак.';
end;
...
const
Byte04: Byte = $04;
Byte00: Byte = $00;
var
Form1: TForm1;
ff:file;
implementation
{$R *.dfm}
procedure TForm1.N1Click(Sender: TObject);
var i:integer;
s:string;
t: byte;
begin
if SaveDialog1.Execute then
begin
assignfile(ff,SaveDialog1.FileName+'.tmo');
rewrite(ff,1);
s:=Memo1.Text;
for i:=1 to length(s) do
begin
case s of
'а': t:=$30;
'б': t:=$31;
'в': t:=$32;
'г': t:=$33;
'д': t:=$34;
'е': t:=$35;
'ё': t:=$51;
'ж': t:=$36;
'з': t:=$37;
'и': t:=$38;
'й': t:=$39;
'к': t:=$3A;
',': t:=$2C;
'.': t:=$2E;
' ': t:=$20;
'?': t:=$3F; // и т.д.
else t:=$3F; // если что то другое - знак вопроса ?
end;
blockwrite(ff, t,1);
if (t=$2C) or (t=$2E) or (t=$20) or (t=$3F) then begin
blockwrite(ff,Byte00,1);
end
else begin
blockwrite(ff,Byte04,1);
end;
end;
closefile(ff);
end;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
memo1.Text:='ёж, газ, бак.';
end;
...
Но не понимаю как записать в начало файла длинну строки. Если использовать
IntToHex(Length(Memo1.Text))
то получаем строку (string) и записать в файл её нельзя, компилятор ругается. А по твоему алгоритму, Михаил, контрольная сумма считается правильно, только когда в начале файла указана длинна строки.
Мой исходник в архиве.
длину записать можно при помощи BlockWrite
Михаил тебе огромное спасибо за код, без него я конечно ничего бы не сделал.
Ну и собственно исходник для тех кому интересно. (Правда его нужно немного доработать, добавить поддержку заглавных букв, но это уже мелочи).
Цитата: mr_smit
Всё, сделал. Код конечно не претендует на идеальный. Но главное работает. Телефон открывает без проблем. Единственное ограничение это то что можно набрать не более 400 символов, свыше 400 телефон отказывается читать. Но и в редакторе телефона тоже больше 400 не набирается. Видно это как то связано с памятью, незнаю.
Михаил тебе огромное спасибо за код, без него я конечно ничего бы не сделал.
Ну и собственно исходник для тех кому интересно. (Правда его нужно немного доработать, добавить поддержку заглавных букв, но это уже мелочи).
Михаил тебе огромное спасибо за код, без него я конечно ничего бы не сделал.
Ну и собственно исходник для тех кому интересно. (Правда его нужно немного доработать, добавить поддержку заглавных букв, но это уже мелочи).
гораздо проще использовать StringToWideChar, чем переводить в Unicode самому
Цитата: Михаил
гораздо проще использовать StringToWideChar, чем переводить в Unicode самому
Достаточно
Код:
var
S: string;
W: WideString;
begin
S := 'мама';
W := S; // тут компилятор вставляет вызов MultiByteToWideChar
// работаем с W
end;
S: string;
W: WideString;
begin
S := 'мама';
W := S; // тут компилятор вставляет вызов MultiByteToWideChar
// работаем с W
end;