memfile

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

memfile

Сообщение Mayor » 06.09.2007 08:58:33

как создать файлы не на диске, а в памяти?
Mayor
новенький
 
Сообщения: 20
Зарегистрирован: 04.09.2007 16:55:14

Сообщение v-t-l » 06.09.2007 17:23:03

В смысле воссоздать файловую систему в памяти?
Зачем?
v-t-l
энтузиаст
 
Сообщения: 740
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Сообщение Cheb » 06.09.2007 19:50:38

TMemoryStream ?
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Сообщение Mayor » 06.09.2007 20:03:45

Cheb писал(а):TMemoryStream ?


а без классов никак?

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

да еще когда со стандарнтного ввода данные поступают не могу конец файла поймать

while not eof do - не срабатывает - чем можно заменить?
Mayor
новенький
 
Сообщения: 20
Зарегистрирован: 04.09.2007 16:55:14

Сообщение Cheb » 06.09.2007 20:38:16

со стандартного ввода поступают данные, за один заход боюсь что их не смогу обработать,

Тогда более разумного решения чем TMemoryStream и быть не может.

да еще когда со стандарнтного ввода данные поступают не могу конец файла поймать

А он там вообще бывает, этот конец?
И вообще - кто пишет данные, которые ты получаешь через стандартный ввод?
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Сообщение shade » 06.09.2007 21:26:08

Mayor писал(а):while not eof do - не срабатывает - чем можно заменить?

Попробуй заменить на while not seekeof do, только учти, что слово seek там не случайно... он пропускает все пробельные символы...
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/

Сообщение Mayor » 07.09.2007 07:05:16

shade писал(а):
Mayor писал(а):while not eof do - не срабатывает - чем можно заменить?

Попробуй заменить на while not seekeof do, только учти, что слово seek там не случайно... он пропускает все пробельные символы...


а вата, а никак стандартный ввод не приравнять к file of byte переменной?

я уже просто начал работать с filepos(f) > filesize(f)
что нарушает условия задачи - программа должна читать со стандартного канала ввода, а не из файла на диске
Mayor
новенький
 
Сообщения: 20
Зарегистрирован: 04.09.2007 16:55:14

Сообщение v-t-l » 07.09.2007 21:02:07

а никак стандартный ввод не приравнять к file of byte переменной?

Попробуй так:
Код: Выделить всё
  Reset(f);
  FileRec(f).Handle := StdInputHandle;

Но тип FileRec описан в filerec.inc, который не включен в интерфейс модуля system.
Поэтому его придется описать в своей проге или включить filerec.inc.
Но Eof все равно выдает ошибку.
Если прога не кроссплатформенная, то лучше попробуй использовать прямые системные вызовы.
v-t-l
энтузиаст
 
Сообщения: 740
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Сообщение v-t-l » 07.09.2007 21:09:37

Или попробуй поэспериментировать с другими полями FileRec(f).
v-t-l
энтузиаст
 
Сообщения: 740
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Сообщение v-t-l » 08.09.2007 12:14:14

Такая схема работает получше
Код: Выделить всё
program project2;
{$APPTYPE CONSOLE}
{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes
  { add your units here };

var
  si, so: THandleStream;
  sm: TMemoryStream;
begin
  si := THandleStream.Create(StdInputHandle);
  so := THandleStream.Create(StdOutputHandle);
  sm := TMemoryStream.Create;
 
  sm.LoadFromStream(si); // грузим в память
 
  so.CopyFrom(sm, sm.Size); // выводим в stdout
 
  sm.Free;
  so.Free;
  si.Free;
end.

но все равно не так, как нужно.
Если подать на вход файл с диска - все замечательно,
а если вывод другой проги - получается максимум 17 кбайт (под WinXP).
v-t-l
энтузиаст
 
Сообщения: 740
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Сообщение SAK » 08.09.2007 13:38:06

Зачем всё усложнять? Создаём динамический массив из строк и сохраняем туда входные данные, потом его обрабатываем как угодно.
Код: Выделить всё
program Project1;

{$mode objfpc}{$H+}

var ss: array of string;
    n: LongInt;
begin
  SetLength (ss, 0);
  n:=0;
  while not eof(Input) do
   begin
     SetLength(ss, n+1);
     Readln(ss[n]);
     inc(n)
   end;
   
  for n:=0 to High(ss) do Writeln(ss[n]);
 
end.


Если явно не указан файл, то процедура readln читает данные из файла Input, поэтому и проверять на конец файла надо его. Если данные вводятся с клавиатуры, то признаком конца файла является нажатие Ctrl+Z.

Кстати, если явно не указан файл, то write/writeln выводят в файл Output.
SAK
постоялец
 
Сообщения: 158
Зарегистрирован: 18.02.2006 00:45:14
Откуда: Тим

Сообщение shade » 08.09.2007 14:55:08

Если нужно прочесть точ-в-точ то что передали (без замены \r\n -> \n), то обрати внимание на SetTextLineEnding - иначе может просто удалить соответствующую строчку - под Windows вроде работает...
Код: Выделить всё
program test;

var
  s: string;
  ch: char;
begin
  s := '';
  SetTextLineEnding(input, #13);
  while not eof do
  begin
    read(ch);
    s := s + ch;
  end;
  writeln(s);
end.


PS: только конструкция s := s + ch; скорее всего вызовет тормоза на больших файлах, потому нужно заюзать что-то типа SetLength(s); s[len] := ch; inc(len); Причем SetLength вызывать по реже, например SetLength(s, Length(s) + Length(s) div 4 + 1);

Позже дописал:
короче я бы попробовал так:
Код: Выделить всё
program test;

{$mode objfpc}

function ReadInput: AnsiString;
var
  s: array of char;
  capacity: longint;
  RealLength: longint;
begin
  RealLength := 0;
  capacity := 1024;
  SetLength(s, capacity);
  SetTextLineEnding(input, #13);
  while not eof do
  begin
    if RealLength = capacity then
    begin
      SetLength(s, capacity + capacity div 4 + 1);
    end; // if
    read(s[RealLength]);
    Inc(RealLength);
  end;
 
  SetString(Result, @s[0], RealLength);
end;

var
  text: AnsiString;
begin
  text := ReadInput;
  writeln('Input size in bytes: ', Length(text));
  writeln('content:');
  write(text);
  writeln('----------------- end ---------------');
end.
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/

Сообщение v-t-l » 08.09.2007 15:14:51

2shade
В WinXP не работает.
Бинарные данные проходят не полностью.
А автору вопроса, как я понял, нужно именно двоичные, а не текстовые данные, обрабатывать.
v-t-l
энтузиаст
 
Сообщения: 740
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Сообщение Mayor » 08.09.2007 18:42:11

да еще когда со стандарнтного ввода данные поступают не могу конец файла поймать


стандарт posix позволяет даже под виндой :
prog < file.bin

перенаправить на стандартный канал ввода файл или стандартный вывод другой программы

А он там вообще бывает, этот конец?
И вообще - кто пишет данные, которые ты получаешь через стандартный ввод?


естественно бывает ^D его посылает даже с клавиатуры, или ситема когда пайпе прога закрывается или файл заканчивается ..


а да респект всем особенно за анси стринг оказалось то что нада :)
Mayor
новенький
 
Сообщения: 20
Зарегистрирован: 04.09.2007 16:55:14

Сообщение shade » 09.09.2007 12:23:35

v-t-l писал(а):2shade
В WinXP не работает.
Бинарные данные проходят не полностью.

Приведи пример. Что именно не проходит? какие символы?
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/

След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

Рейтинг@Mail.ru