IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

> Обмен информацией в файлах.
Krjuger
сообщение 24.05.2011 21:09
Сообщение #1


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Собственно,начал подзабывать язык,решил возродить.
Есть задача.
Даны 2 текстовых файла с произвольной информацией внутри,произвести обмен информацией,что бы в первом была инфа второго,во втором- первого.Использовать ренейм нельзя.Собственно идея такая,завести 3 файл и через него, как буфер(аналогично обмену 2 переменных).Собсвенно интересует,есть ли вобможность незаводя 3 файла сделать такую операцию?
И еще Readblock и wrihteblock смогут отработать с sizeof(file)?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
2 страниц V  1 2 >  
 Ответить  Открыть новую тему 
Ответов(1 - 19)
IUnknown
сообщение 24.05.2011 23:13
Сообщение #2


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Цитата
Даны 2 текстовых файла с произвольной информацией внутри
Ну, текстовые-то они, если откроешь их как текстовые. Их ведь можно открыть и как file of byte, и как file of char... И как бестиповый в конце концов...

Цитата
Собсвенно интересует,есть ли вобможность незаводя 3 файла сделать такую операцию?
Собственно, почему бы и нет?

Ку? (Показать/Скрыть)


Цитата
И еще Readblock и wrihteblock смогут отработать с sizeof(file)?
sizeof(file) - это размер записи, представляющей информацию о файле, а не размер самого файла. Для получения размера файла - FileSize(f)... А Read/Writeblock работают с буфером. Какой выделишь - с тем и будут работать.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 25.05.2011 15:36
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +



seek(f, posg); truncate(f);
seek(g, posf); truncate(g);


Как я понимаю идея такова,что происходит чтение и запись в начало файла,а потом транкейтом отрезается все,что после позиции, указывающей на конец другого файла?Интересненько.
Еще 2 таких вопроса.
seek(f, filepos(f) - sizeof(item));
это мы как раз и втыкаем наш символ перед первым символом в файле?
И зачем нужна процеруда write_file,разве мы не можем write_file(f, read_file(g)); сделать с обычным write?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 25.05.2011 16:07
Сообщение #4


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Цитата
Как я понимаю идея такова,что происходит чтение и запись в начало файла,а потом транкейтом отрезается все,что после позиции, указывающей на конец другого файла?
Да, если этого не сделать - то более короткий файл перезапишется данными из более длинного, тут все будет в порядке. А вот тот, что был длиннее - будет хранить "хвост" из своих старых данных. Его надо убрать. В принципе, нужен только один Truncate - для более длинного изначально файла.
Цитата
seek(f, filepos(f) - sizeof(item));
это мы как раз и втыкаем наш символ перед первым символом в файле?
Это мы после того, как прочли из файла очередную порцию данных (если интересно - покажу, как сделать это же самое с бестиповым файлом, там можно вычислить наибольший общий делитель размеров, для того, чтобы минимизировать число операций чтения/записи, не всегда читать побайтно), возвращается назад, чтоб потом ТУДА ЖЕ, откуда прочли, записать данные, считанные с другого файла.

Цитата
И зачем нужна процеруда write_file,разве мы не можем write_file(f, read_file(g)); сделать с обычным write?
Можем. Но выглядит лучше - когда процедуры "парные". blockread/blockwrite, read/write, readln/writeln... И тут я буду использовать read_file/write? Нет, не буду.

Сообщение отредактировано: IUnknown - 25.05.2011 16:09
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 25.05.2011 16:22
Сообщение #5


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


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

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

Ну это уже принципи более менее понятно,т.к "порция" это абстрактная вещ.В текущем случае это char,а в бестипном, найдя НОД, будет nное кол-во байтов.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 25.05.2011 16:27
Сообщение #6


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Цитата
Ну это уже принципи более менее понятно
Хорошо... Понятно, говоришь? smile.gif Можно попросить тебя реализовать тот же самый алгоритм, но используя именно бестиповые файлы + НОД для того, чтобы (возможно) не читать байт за байтом, а читать максимально возможными порциями?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
TarasBer
сообщение 25.05.2011 17:00
Сообщение #7


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Зачем НОД? Почему мы берём именно фиксированный размер считываемой порции? Да можно сразу взять буфер на 64 килобайта и через него делать, а если после очередной считки буфер заполнился не до конца, то так и запомнить.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 25.05.2011 17:19
Сообщение #8


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Цитата
Зачем НОД? Почему мы берём именно фиксированный размер считываемой порции? Да можно сразу взять буфер на 64 килобайта и через него делать
Потому что МНЕ так хочется. Такой ответ устроит? Память - не резиновая, у меня НЕТ свободных 64К, чтобы прочесть в них 800 байт из файла.

Вот когда ты будешь писать - будешь делать так, как захочется тебе. Идея понятна?

Сообщение отредактировано: IUnknown - 25.05.2011 17:22
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 25.05.2011 18:05
Сообщение #9


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Ну чтож я попытался,но не все так прекрасно вышло))))Мне почти удалось переписаль содержимое файлов друг в дружку за исключением пары ньюансов mad.gif

Хотя не, вру,еще чуть чуть и будет более менее пристойный вариант.

В общем оно вроде работает smile.gif

function nod(x,y : longint):longint;
begin
if x<>0 then nod:=nod( y mod x, x) else nod:=y;
end;

var
f, g :file;
b,p : string;
posf, posg :longint;
ser: longint;
begin
assign(f, '01.txt'); reset(f,sizeof(byte));
posf :=filesize(f);
assign(g, '02.txt'); reset(g,sizeof(byte));
posg :=filesize(g);
ser:=nod(posf,posg);

while not eof(f) and not eof(g) do
begin
BlockRead(f,b,Sizeof(byte)*ser);
seek(f,filepos(f)-Sizeof(byte)*ser);
BlockRead(g,p,Sizeof(byte)*ser);
seek(g,filepos(g)-Sizeof(byte)*ser);
BlockWrite(f,p,Sizeof(byte)*ser);
BlockWrite(g, b,Sizeof(byte)*ser);
end;

if eof(f) then
while not eof(g) do
begin
BlockRead(g,b,sizeof(byte));
Blockwrite(f, b,sizeof(byte));
end;
if eof(g) then
while not eof(f) do
begin
BlockRead(f, b,sizeof(byte));
BlockWrite(g, b,sizeof(byte));
end;

seek(f,posg); truncate(f);
seek(g,posf); truncate(g);

close(f); close(g);
end.


Не пинайте сильно,принципи можно было бы как то и свести к тому,что мне показывали,но как передать чтобы функция возвращала нужную мне длинну я хз)))реч о read_file : item;

P.S.Несмотря на то,что последняя строчка вне тегов кода,у меня почему то отображается внутри.

Сообщение отредактировано: Krjuger - 25.05.2011 18:17
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 26.05.2011 0:03
Сообщение #10


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Цитата
  b,p : string;
// ...
BlockRead(f,b,Sizeof(byte)*ser);
Не делай так больше никогда. Ибо если размеры файлов будут кратны, друг другу, скажем, первый = 1010 байт, второй - 2020, то получишь "биг бада бум" (С) при попытке считать в строку (с максимальной длиной 255 символов) те же 1010 байт. Буфер надо выделять динамически. Кстати, когда будешь это делать - подумай над тем, что будет, если размер первого файла = 74184 байта, а второго - 222552 байт. Вот когда твоя программа будет отрабатывать и на таких файлах - тогда будем говорить дальше smile.gif Ты сам сказал, что
Цитата
Даны 2 текстовых файла с произвольной информацией внутри
, стало быть, размер файлов может быть тоже произвольным...



Сообщение отредактировано: IUnknown - 26.05.2011 0:04
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
TarasBer
сообщение 26.05.2011 9:18
Сообщение #11


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> Память - не резиновая, у меня НЕТ свободных 64К, чтобы прочесть в них 800 байт из файла.

64K - для примера. Можно и 4K, или любое удобное число. Поиск числа, на которое делится размер файла, не имеет никакого смысла, кроме как для учебной задачи.

> Потому что МНЕ так хочется. Такой ответ устроит?

Типа как доп.задание? Ну ладно... Главное понимать, что это всего лишь учебное задание, а реального смысла в этом нет.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 26.05.2011 12:34
Сообщение #12


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Цитата
Вот когда твоя программа будет отрабатывать и на таких файлах - тогда будем говорить дальше

А может лучше не надо дальше?)))
Я конешно постараюсь,что что то интузиазм угасает уже)

Цитата
Буфер надо выделять динамически

А тогда по какому принципу записывать в буфер информацию?Например у нас есть.

type
PerconPointer = ^PerconRecord;
PerconRecord = record
temp: string;
Next: PerconPointer
end;


В каждое поле записывать по 255 символов,либо temp будет чаром,но тогда мы недалеко уйдем от считывания по 1 байту.Получается что хоть у нас буфер и будет каким мы заходим,но его заполнение у меня упрется все равно в теже самые 255 символов,более того,если нельзя переписать сразу весь буфер(в данном случае я не знаю можно ли или нет) то наши труды будут весьма сомнительны.В общем то нужен вброс какой то информации,мои знания немного заканчиваются.

P.S.Если вспомнить откуда я брал задачку (методичка для 1 курса) то там решением задачи был бы самый первый код,дальше люди просто не проходили)

Сообщение отредактировано: Krjuger - 26.05.2011 12:48
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
TarasBer
сообщение 26.05.2011 13:13
Сообщение #13


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Динамический буфер делается не так.
Заводишь тип-указатель на массив максимально возможной длины (65534 байта), выделяешь для него нужное кол-во памяти через GetMem, потом, поработав с ним, освобождаешь через FreeMem


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 26.05.2011 14:23
Сообщение #14


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


То есть нечто подобное

Buf : array of Char;
FSize : LongWord;
FSize := FileSize(F);
SetLength(Buf, FSize);
BlockRead(F,Pointer(Buf)^, FSize);


ну только собственно в FSize пишеться НОД.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
TarasBer
сообщение 26.05.2011 14:33
Сообщение #15


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Я думал, у тебя ТурбоПас.
Если у тебя Дельфи, то да, примерно так. Только SetLength(Buf, FSize) - это немного опрометчиво, файлы и на два гига бывают.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 26.05.2011 14:42
Сообщение #16


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Цитата
Заводишь тип-указатель на массив максимально возможной длины (65534 байта), выделяешь для него нужное кол-во памяти через GetMem, потом, поработав с ним, освобождаешь через FreeMem
лучше не превышать 65528:
Цитата(GetMem function)
Restrictions:
The largest block that can be safely allocated on the heap at one time is 65,528 bytes (64K-$8).
Если у кого-то и где-то один раз получилось выделить все 65534 - он может считать, что ему повезло. Гарантированно выделяется не больше 65528, все остальное зависит от фазы Луны и разных других факторов. В любом случае, для написания надежной программы не стоит обходить то, что написано в документации. Даже если очень хочется... Но на эту темя я уже говорил, повторяться не буду. Хотите обходить правила - обходите. Потом - не жалуйтесь!!!

Сообщение отредактировано: IUnknown - 26.05.2011 14:42
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
TarasBer
сообщение 26.05.2011 14:49
Сообщение #17


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Хорошо, пусть будет 65528. Параметры типа ни на что всё равно не влияют в данном случае.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 26.05.2011 15:43
Сообщение #18


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Цитата

думал, у тебя ТурбоПас.
Если у тебя Дельфи, то да, примерно так.

У меня и то и то есть,но как сделать на турбо я вообще не знаю...Хотя сделать надо именно на турбо(
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
TarasBer
сообщение 26.05.2011 15:47
Сообщение #19


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Я же объяснил всё.

type
TBigArr = array [0 .. 65528] of byte;
PBigArr = ^TBigArr;

var
Buf: PBigArr;

...

GetMem(Buf, сколько надо);
...
работаем
...
FreeMem(Buf, сколько было надо, надо освободить ровно столько, сколько и заняли);



--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 26.05.2011 17:32
Сообщение #20


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Что я делаю не так.

type
TArr= array [0..65528] of byte;
PArr = ^TArr;

function nod(x,y : longint):longint;
begin
if x<>0 then nod:=nod( y mod x, x) else nod:=y;
end;

var
f, g :file;
b,p : PArr;
posf, posg :longint;
ser: longint;

begin
assign(f, '01.txt'); reset(f,Sizeof(byte));
posf :=filesize(f);
assign(g, '02.txt'); reset(g,Sizeof(byte));
posg :=filesize(g);
ser:=nod(posf,posg);

while not eof(f) and not eof(g) do
begin
GetMem(b,ser);
GetMem(p,ser);
BlockRead(f,b,ser);
seek(f,filepos(f)-Sizeof(byte)*ser);
BlockRead(g,p,ser);
seek(g,filepos(g)-Sizeof(byte)*ser);
BlockWrite(f,p,ser);
BlockWrite(g,b,ser);
FreeMem(b,ser);
FreeMem(p,ser);
end;

GetMem(b,ser);
GetMem(p,ser);
if eof(f) then
while not eof(g) do
begin
BlockRead(g,b,sizeof(byte));
Blockwrite(f, b,sizeof(byte));
end;
if eof(g) then
while not eof(f) do
begin
BlockRead(f, b,sizeof(byte));
BlockWrite(g, b,sizeof(byte));
end;
seek(f,posg); truncate(f);
seek(g,posf); truncate(g);

dispose(b);
dispose(p);
close(f); close(g);
end.


На строчке FreeMem(b,ser); Invalid pointer operation.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

2 страниц V  1 2 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 20.06.2025 10:00
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"