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

Вниз

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

Наверх





Память: 0.56 MB
Время: 0.05 c
14-1109682820
Ирина
2005-03-01 16:13
2005.03.20
Знак радиации


14-1109236007
dimonf
2005-02-24 12:06
2005.03.20
Работа в Москве от 1100$


10-1048328030
Guru
2003-03-22 13:13
2005.03.20
Клиент/серверное приложение с авторизацией


1-1110109405
TeNY
2005-03-06 14:43
2005.03.20
Clipboard.Formats[] непонятна логика.


14-1109255082
Ирина
2005-02-24 17:24
2005.03.20
Крис Касперский





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский