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

Вниз

EInOutError - Invalide File Name   Найти похожие ветки 

 
Германн ©   (2005-03-04 01:16) [0]

Возвращаюсь к более раннему моему топику. Нашел способ уточнить подробности сего исключения. И вижу, что имя файла - полностью нормальное! Никаких "запрещенных символов" не содержит.

Теперь вопрос. Если кто знает :(
Может ли эта ошибка(исключение) генерироваться из-за того, что ограничены права данного юзера на создание файла в некоей директории(папке)?
ОС точно не знаю. Но думаю, что это либо 2k, либо XP.


 
Gero ©   (2005-03-04 01:19) [1]

Может.


 
Германн ©   (2005-03-04 01:25) [2]

2 Gero ©   (04.03.05 01:19) [1]

Вы уверены?
Тогда Спасибо!


 
Gero ©   (2005-03-04 08:33) [3]


> Германн ©   (04.03.05 01:25)

Тем не менее, оно может генерироваться и не из-за этого.


 
Anatoly Podgoretsky ©   (2005-03-04 08:54) [4]

Германн ©   (04.03.05 01:16)  
Это означает, что не смогло работать с таким именем, а конкретная причина неизвестна, в том числе и права. Проверяется через проводник и проверяется дважды в той папке и папке где гарантированы права. Еще может мешать антивирус и другие подобные бяки.
А что за код?


 
Германн ©   (2005-03-04 12:55) [5]

2 Anatoly Podgoretsky ©   (04.03.05 08:54) [4]
Код совершенно обычный:
 AssignFile(FDest,SndName);
  {$I-}
 Reset(FDest,1);
  {$I+}
 if (IOResult <> 0) or (not Loop) then begin
   FInspMain.SaveLog(nil,SndName,"TSndData.Create");
   Rewrite(FDest,1);
   Move(CWaveStruct,FDestHeader,SizeOf(TWaveStruct));
   BlockWrite(FDest,FDestHeader,SizeOf(TWaveStruct));
 end else begin
   BlockRead(FDest,FDestHeader,SizeOf(TWaveStruct));
   Seek(FDest,FileSize(FDest));
 end;

Этот код работает уже лет 8. И без проблем.
А вот теперь на одном объекте:
03.03.2005 12:59:29-C:\INSPECT\SOUND\TEMP\1314.WAV
03.03.2005 12:59:29-EInOutError : Invalid filename
**************************************************
Первая строка записана в лог функцией SaveLog. Вторая записана в обработчике Application.OnException.
Сегодня обещали на том объекте проверить все права.


 
Anatoly Podgoretsky ©   (2005-03-04 13:21) [6]

И где код обработчика, где код SaveLog?
Почему после ошибки открытия делаются попытки записи?
Почему не используется более совершенная технология исключений, а вместо ее устаревшая из ДОС и та не правильно используется.

Не надо пока ни какие права проверять, надо сначала привести код программы.


 
Германн ©   (2005-03-05 01:03) [7]

2 Anatoly Podgoretsky ©   (04.03.05 13:21) [6]
Код не мой. Код был написан другим человеком где-то в 95-96 годах. Еще на Д1. Позже он был портирован сначала на Д3 потом, может быть был изменен для Д4. И только два дня назад его(исходник) "вытрясли" из разработчика для того, чтобы выяснить причину ошибки EInOutError : Invalid filename.
Для этого во все места, где происходила работа с файлами, тем или иным способом, был вставлен вызов функции SaveLog. Её код:

procedure TFInspMain.SaveLog(E: Exception; EStr, PlaceSt: String);  
var
 i : Integer;
 FT : TextFile;
 St : String;
begin
 St:=ChangeFileExt(Application.ExeName,"."+FormatDateTime("yymm",Now)+".log.txt");
 AssignFile(FT,St);
 if FileExists(St) then Append(FT) else ReWrite(FT);
 if E <> nil then begin
   St:=DateTimeToStr(Now)+"-"+ E.ClassName+" : "+E.Message;
   Writeln(FT,St);
   //LogMemo.Lines.Add(St);
   if (E is EDBEngineError) then begin
     for i:=0 to EDBEngineError(E).ErrorCount-1 do begin
       St:=IntToStr(i)+": "+EDBEngineError(E).Errors[i].Message;
       Writeln(FT,St);
       //LogMemo.Lines.Add(St);
       St:="ErrorCode="+IntToStr(EDBEngineError(E).Errors[i].ErrorCode)+
         "  Category="+IntToStr(EDBEngineError(E).Errors[i].Category)+
         "  SubCode="+IntToStr(EDBEngineError(E).Errors[i].SubCode);
       Writeln(FT,St);
       //LogMemo.Lines.Add(St);
     end;
     if EDBEngineError(E).Errors[0].ErrorCode = DBIERR_INDEXOUTOFDATE then begin
       St:=EDBEngineError(E).Errors[1].Message;
       St:=Copy(St,Pos("Table:",St)+8,Length(St));
       St:=ExtractFileName(St);
       if Pos(".",St) <> 0 then St:=Copy(St,1,Pos(".",St)-1);
       CheckTbl(St);
     end;
   end;
   if EStr <> "" then Writeln(FT,EStr);
   if PlaceSt <> "" then Writeln(FT,PlaceSt);
 end else begin
   if EStr <> "" then begin
     St:=DateTimeToStr(Now)+"-"+EStr;
     Writeln(FT,St);
     if PlaceSt <> "" then Writeln(FT,PlaceSt);
   end else if PlaceSt <> "" then begin
     St:=DateTimeToStr(Now)+"-"+PlaceSt;
     Writeln(FT,St);
   end;
 end;
 Writeln(FT,"*****************************************************************");
 CloseFile(FT);
end;


Код обработчика:
procedure TFInspMain.AppEvents1Exception(Sender: TObject; E: Exception);
begin
 SaveLog(E,"","");
end;

>Почему после ошибки открытия делаются попытки записи?
Потому что файл, о котором идет тут речь - временный. Создаваемый программой тогда, когда это нужно. Точнее - это WAV-файл который "собирается по кусочкам" из других, уже имеющихся, WAV-файлов, для озвучивания произошедшего в системе события. Но! События могут быть двух типов: ординарные и особенные. В первом случае их достаточно озвучить однократно и затем замолчать. Во втором - их надо постоянно повторять до тех пор, пока ситуация не исправится или оператор не нажмет специльную кнопку, подтверждая, что он тревогу принял и осознал. В этом втором случае файл уже может существовать, если предыдущая тревога еще не снята. И тогда новое сообщение прибавляется к старому. Во всех остальных случаях файл, по умолчанию" не существует, поскольку его имя - содержимое автоикрементного поля DB.


 
GuAV ©   (2005-03-05 01:31) [8]

Германн ©   (05.03.05 1:03) [7]

>  Точнее - это WAV-файл который "собирается по
> кусочкам" из других, уже имеющихся


А почему бы не проигрывать их ("кусочки") синхронно в отдельном потоке, а имена или IDы их передавать через postmessage ?

Или собирать их из "кусочков" в памяти ? (у PlaySound / sndPlaySound есть флаг SND_MEMORY)


 
GuAV ©   (2005-03-05 01:43) [9]


> потоке, а имена или IDы их передавать через
> postmessage ?

т.е. PostThreadMessage. выбирать их PeekMessage с pm_remove, если нечего проигрывать ждать WaitMessage


 
Германн ©   (2005-03-05 01:53) [10]

2 GuAV ©   (05.03.05 01:31) [8]
Если бы это писАл я, да еще сейчас, а не 10 лет назад, я бы вообще пошел бы другим путем. Например, использовал бы что-то из SpeechAPI. Гораздо удобнее, чем WAV-файлы.
Но кто мне это оплатит?

А вот "разбираться с ошибками" уже существующей программы, блин! Хочу уйти из этой конторы. Ищу другую. Но это - offtopic!

Но, кстати.
>А почему бы не проигрывать их ("кусочки") синхронно в отдельном потоке, а имена или IDы их передавать через postmessage ?
А что бы это изменило? Причем тут "отдельный поток"? Мне вроде как и основного хватало?

>Или собирать их из "кусочков" в памяти ? (у PlaySound / sndPlaySound есть флаг SND_MEMORY)
Эт-да, да вот только разница будет, "если файл уже есть в памяти", а если его ещё нужно "собрать из кусочков"?


 
GuAV ©   (2005-03-05 02:02) [11]

Германн ©   (05.03.05 1:53) [10]
Эт-да, да вот только разница будет, "если файл уже есть в памяти", а если его ещё нужно "собрать из кусочков"?


Так можете собирать в памяти, заменив например BlockWrite на TMemoryStream.Write

Германн ©   (05.03.05 1:53) [10]
А что бы это изменило? Причем тут "отдельный поток"? Мне вроде как и основного хватало?

То что никакого "сбора" бы не было. Проигрываете один, затем другой, в перерывах проверяеете не изменился ли "плейлист". Я бы так попробовал бы перед тем как "склеивать". В прочем учитывая [10] это отпадает.


 
Германн ©   (2005-03-05 02:37) [12]

2GuAV ©   (05.03.05 02:02) [11]
>То что никакого "сбора" бы не было. Проигрываете один, затем другой, в перерывах проверяеете не изменился ли "плейлист".

Я, конечно не прав, что не изложил полностью идеологию данной функции. Данная функция формирует Wav-файл, в который включен "номер датчика" в диапазоне от 1 до 99.
"Склеивание" в том числе преполагало и "склеивание" для "вразумительного" произношения числа "девяносто девять" файлов "90.wav" и "9.wav".


 
GuAV ©   (2005-03-05 02:39) [13]

Работоспособный пример, поясняющий идею с потоком. В ListBox1 несколько полных путей к WAV файлам.

uses MMSystem;

var ThdID: DWORD;

const
 WM_PLAY_ONCE   = WM_USER + 0;
 WM_PLAY_ADD    = WM_USER + 1;
 WM_PLAY_REMOVE = WM_USER + 2;
 WM_PLAY_QUIT   = WM_USER + 3;

function WaveThd(Parameter: Pointer): Integer;
var
 Msg: TMsg;
 L: TList;
 I: Integer;
 sounds: TStrings;
begin
 sounds := Parameter;
 L := Tlist.Create;
 while True do
   if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
     case Msg.message of
       WM_PLAY_ONCE:
         PlaySound(PChar(sounds[Msg.lParam]), 0, SND_SYNC or SND_FILENAME);
       WM_PLAY_ADD:
         L.Add(Pointer(Msg.lParam));
       WM_PLAY_REMOVE:
         L.Remove(Pointer(Msg.lParam));
       WM_PLAY_QUIT, WM_QUIT: Break;
     end
   else
     if L.Count = 0 then
     begin
       if not WaitMessage then Break
     end
     else
     begin
       for I := 0 to L.Count - 1 do
         PlaySound(PChar(sounds[Integer(L[I])]), 0, SND_SYNC or SND_FILENAME);
     end;
 Result := Msg.wParam;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 BeginThread(nil, 0, WaveThd, ListBox1.Items, 0, ThdID);
end;

// проиграть один раз выбранный в LisbBox1 файл
procedure TForm1.Button1Click(Sender: TObject);
begin
 PostThreadMessage(ThdID, WM_PLAY_ONCE, 0, ListBox1.ItemIndex);
end;

// поставить выбранный в LisbBox1 файл на постоянное воспроизведение
procedure TForm1.Button2Click(Sender: TObject);
begin
 PostThreadMessage(ThdID, WM_PLAY_ADD, 0, ListBox1.ItemIndex);
end;

// снять выбранный в LisbBox1 файл с постоянного воспроизведенич
procedure TForm1.Button3Click(Sender: TObject);
begin
 PostThreadMessage(ThdID, WM_PLAY_REMOVE, 0, ListBox1.ItemIndex);
end;


 
GuAV ©   (2005-03-05 02:42) [14]

Германн ©   (05.03.05 2:37) [12]
Склеивание" в том числе преполагало и "склеивание" для "вразумительного" произношения числа "девяносто девять" файлов "90.wav" и "9.wav".


Всё равно не понятно зачем в файл клеить. Можно склеивать в памяти. Самый удобный способ - через TMemoryStream.


 
Германн ©   (2005-03-05 02:46) [15]

Предлагаю всем желающим ознакомиться с вариантом GuAV ©   (05.03.05 02:39) [13]
Принять или не принять сей вариант - Ваше дело.
Я - пас. Поскольку мой сабж - не об этом!


 
GuAV ©   (2005-03-05 02:55) [16]


> Германн ©   (05.03.05 2:46) [15]

Когда писал [13], [12] не видел, сори...

Хотя его легко до вида когда 90 и 9 будут произносится правильно.
PlaySound(IntToShr((N div 10)*10)+".wav", 0, SND_SYNC or SND_FILENAME);
PlaySound(IntToShr((N mod 10))+".wav", 0, SND_SYNC or SND_FILENAME);
если N равно 99 то будет сказано сначало 90.wav, а потом 9.wav.


 
Германн ©   (2005-03-05 03:09) [17]

2 GuAV ©   (05.03.05 02:55) [16]
В твоем варианте вполне может быть "сказано" так, что будет "воспринято" заказчиком или покупателем, как "основание для неплатежа" или как "основание еще чего-нибудь". Ведь вторая функция PlaySound выполнится БГ знает когда после выполнения первой функции PlaySound! А произношение "девяносто....................девять" - очень плохо звучит.


 
Германн ©   (2005-03-05 03:24) [18]

Да бог ним. С вариантом.
Меня сейчас интересует только "EInOutEroor : Invalid filename"
Как оно может возникнуть? и Как с ним бороться?
Жду сообщений с объекта.


 
Defunct ©   (2005-03-05 04:10) [19]

Германн ©   (05.03.05 03:24) [18]
> Меня сейчас интересует только "EInOutEroor : Invalid filename"


Меняйте на
GuAV ©   (05.03.05 02:42) [14]
> Самый удобный способ - через TMemoryStream.


и больше этот вопрос Вас не будет волновать.

или учитывая, что
Германн ©   (05.03.05 01:03) [7]
> Потому что файл, о котором идет тут речь - временный.

Замените каталог временных файлов на более подходящий с всегда разрешенными правами на создание и запись, пишем:

function ValidateFileName( AFileName: String ):String;
var
  TempName   : PChar;
begin
  GetMem( TempName, 1024);
  try
     GetTempPath( 1024, TempName );
     Result := TempName + ExtractFileName(AFileName)
  finally
     FreeMem( TempName, 1024)
  end
end;


и

Германн ©   (04.03.05 12:55) [5]
> AssignFile(FDest, SndName );


Заменяем все SndName на ValidateFileName(SndName)

Вариант?


 
Германн ©   (2005-03-06 02:03) [20]

2 Defunct ©   (05.03.05 04:10) [19]
>Меняйте на
>GuAV ©   (05.03.05 02:42) [14]
>> Самый удобный способ - через TMemoryStream.

>и больше этот вопрос Вас не будет волновать.

Поменяю, но не на вариант GuAV ©   (05.03.05 02:42) [14], а на тот, что я высказал в Германн ©   (05.03.05 01:53) [10].
Вот только найти бы того, кто это оплатит!

>или учитывая, что
>Германн ©   (05.03.05 01:03) [7]
>> Потому что файл, о котором идет тут речь - временный.
>Замените каталог временных файлов на более подходящий с всегда ?>разрешенными правами на создание и запись, пишем:

Именно это сейчас и делается! Т.е. люди на том объекте  сейчас именно и обещали "разобраться с правами пользователей!" И навести в этом отношении порядок, если что не так!" Жду от них ответа в виде лог-файла!

А Вы можете указать на что-то "неправильное" в сообщении
Германн ©   (04.03.05 12:55) [5] по поводу записей в логе?


 
Defunct ©   (2005-03-06 02:43) [21]

> А Вы можете указать на что-то "неправильное" в сообщении
> по поводу записей в логе?

Могу сказать, что исключение возникло либо на строке ReWrite(F) либо вообще не в этой процедуре, не более того.


 
Германн ©   (2005-03-06 02:59) [22]

2 Defunct ©   (06.03.05 02:43) [21]
Оно  где-то там.
Если это не так, то прошу меня расстрелять при первой возможности, и, плииз, максимально безболезненно. :)


 
Anatoly Podgoretsky ©   (2005-03-06 11:52) [23]

Все тоже самое, reset в проверке, а затем rewrite уже без проверки. Либо делается проверка на каждом шаге, или что лучше делается в защищенном блоке. А при такой реализации даже узнать где произошла ошибка не получится, даже отладка не поможет, нельзя читать IOResult в отладчике.
Надо просто переписать программу, а еще лучше вообще сменить алгоритм, ряд вариантов подсказали.

При этой реализации лог будет показывать температуру где то там.
Не используй  
{$I-}
Reset(FDest,1);
{$I+}

пиши с помощью защищенны[ блоков
AssignFile(FDest,SndName);
try
  Reset(FDest,1);
  ...
  ...
except
  Обработка ошибки
end;


Тоже если вздумаешь при ошибки перезаписывать файл.


 
Defunct ©   (2005-03-06 20:55) [24]

Defunct ©   (06.03.05 02:43) [21]

Добавлю, токое исключение может возникнуть в случае, если файл с атрибутом Read-Only был открыт в блоке {$i-} Reset(F) {$i+}


 
Германн ©   (2005-03-07 02:38) [25]

2 Anatoly Podgoretsky ©
2 Defunct ©
Мужики!

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

Таким образом, если сия проблема может быть решена "Какой-либо "установкой "Каких-либо прав юзеров"", то я буду "ну очень рад!"

Пока, отключаюсь. Жду сообщений от юзеров с объекта. Результат сообщу.
Как только, так сразу :)


 
Anatoly Podgoretsky ©   (2005-03-07 11:20) [26]

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


 
Германн ©   (2005-03-08 01:55) [27]

2 Anatoly Podgoretsky ©   (07.03.05 11:20) [26]
>Тогда какого черты ты спрашиваешь, без изменения кода удачи не >видать. Приходи тогда, когда будет предложено.

Простите напомню:
Германн ©   (04.03.05 12:55) [5]
2 Anatoly Podgoretsky ©   (04.03.05 08:54) [4]
Этот код работает уже лет 8. И без проблем.

И это без обмана. Программа с этим кодом работает уже 8 лет. На разных объектах. И нигде такой проблемы не было!
Но! Как правило, до сих пор никто или почти никто не занимался "установкой прав юзеров".

Таки вот и задал я свой вопрос, потому что не понял из-за чего возникает ошибка EInOutError : Invalid File Name?
Потому что в в логе, имя файла совершенно нормальное!

Анатолий!
А Вы, когда постируете свои ответы всегда глядите лишь на последнее сообщение? Или иногда учитываете всю ветку?


 
Gero ©   (2005-03-08 01:59) [28]


> Германн ©   (08.03.05 01:55)

Так что с правами?
Какие NTFS-разрешения/запреты стоят?


 
Palladin ©   (2005-03-08 02:13) [29]


> Код совершенно обычный:
>  AssignFile(FDest,SndName);
>   {$I-}
>  Reset(FDest,1);
>   {$I+}
>  if (IOResult <> 0) or (not Loop) then begin
>    FInspMain.SaveLog(nil,SndName,"TSndData.Create");
>    Rewrite(FDest,1);
>    Move(CWaveStruct,FDestHeader,SizeOf(TWaveStruct));
>    BlockWrite(FDest,FDestHeader,SizeOf(TWaveStruct));
>  end else begin
>    BlockRead(FDest,FDestHeader,SizeOf(TWaveStruct));
>    Seek(FDest,FileSize(FDest));
>  end;

Ничуть не обычный.

Во первых: IOResult считывается имеено в рамках {$I+} {$I-},
вне, оно не имеет смысла. Во вторых, его значение отнюдь не лишено смысла, и стоит его проанализировать прежде чем гадать, что же происходит.


 
Германн ©   (2005-03-08 02:42) [30]

2 Gero ©   (08.03.05 01:59) [28]
 Отвечу как только, так сразу :) Но ес-сно только после праздников.

2 Palladin ©   (08.03.05 02:13) [29]
>Во первых: IOResult считывается имеено в рамках {$I+} {$I-},
>вне, оно не имеет смысла.
Извини Тимур, но кто тебе сказал такую чушь?

Насчет "во-вторых" я уже говорил. Именно о том что оно стоит. А пока добавлены лишь весьма дешевые строки с записью в лог.


 
Palladin ©   (2005-03-08 02:55) [31]

Да в общем то оно очевидно как из определения, так и из документации (советую к прочтению F1, как знаете, еще из TP3 эта тема тянется). Как только IOResult принимает значение отличные от нуля вне границ {$I+} {$I-} возникает исключение. Для того {$I-} {$I+} и созданны вообще то...


 
Германн ©   (2005-03-08 03:25) [32]

2 Palladin ©   (08.03.05 02:55) [31]

Ну и... ?
Вы привели часть опубликованного мной кода:
>Palladin ©   (08.03.05 02:13) [29]

>> Код совершенно обычный:
>>  AssignFile(FDest,SndName);
>>   {$I-}
>>  Reset(FDest,1);
>>   {$I+}
>>  if (IOResult <> 0) or (not Loop) then begin

Я, лично на TP3 не работал.
Имхо, врядли кто из участников сего форума на ТР3 смог поработать! Ну максимум Юрий Зотов и то врядли. В те времена в СССР просто не было компьютеров на которых можно было бы пользоваться ТР3, а если такие и были, то они были в распоряжении "солидных людей"!
Но в работах на TP4 уже принимал участие. А уж на TP5 мною сделано много.

А Опции компиллятора {$I-} и {$I+} созданы для того, чтобы имелась возможность "отключить стандартную реакцию" системы на ошибку ввода/вывода. Ранее это - сообщение системы об ошибке, сейчас это - возбуждение исключения (что вообщем-то одно и то же).



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

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

Наверх




Память: 0.58 MB
Время: 0.033 c
14-1109445673
mordush
2005-02-26 22:21
2005.03.20
имена процов


14-1109578928
AlexG
2005-02-28 11:22
2005.03.20
Обреченность вида - Человек


14-1109866422
kaif
2005-03-03 19:13
2005.03.20
Вопрос[2]. О власти


14-1109839065
Agent13
2005-03-03 11:37
2005.03.20
Тормозит интернет!


3-1108552389
atruhin
2005-02-16 14:13
2005.03.20
Вопрос про репликацию данных