ファイルの検索エラーについて – プログラミング – Home

ファイルの検索エラーについて
 
通知
すべてクリア

ファイルの検索エラーについて

固定ページ 1 / 2

よっさん
 よっさん
(@よっさん)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

こんにちわ、よっさんと申します。

前にも同じような質問をさせていただいたのですが、
原因が追求できずに困っています。

開発環境:WIN2000 VC++6.0 WIN32コンソールアプリ

_findfirst()に、正しいパスを引数で渡しているのですが
ファイル名不正のエラーが出てしまいます。

指定したディレクトリに、指定した名前のファイルが
あるのにもかかわらず「EINVAL」のエラーが出てしまう、
このような場合にどのような事がエラーの原因に成り得る
のでしょうか。

 [処理の流れを以下に記します]

□指定したディレクトリのファイルは不定期にファイルが
 作成されます。

□その作成されたファイルを、_findfirst()で
 ファイルが作成されたかどうかを監視しています。

□ファイルが、_findfirstで取得できた場合には、
 そのファイルを削除します。

もしかしたら、ファイルが出来た瞬間?に_findfirstで
取得しに行ったときに、エラーしているではないのかと、
思っているのですが、そのようなことがあるのでしょうか。

どなたか分かる方がいらっしゃいましたら、
ご教授宜しくお願い致します。


引用解決済
トピックタグ
?
 ?
(@?)
ゲスト
結合: 23年前
投稿: 49
 

_findcloseのタイミングが悪いのでは?


返信引用
よっさん
 よっさん
(@よっさん)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

?さん返信有難うございます。

_findcloseの場所は、_findcloseのエラー処理
ではしていないですし、特に問題は無さそうです。


返信引用
?
 ?
(@?)
ゲスト
結合: 23年前
投稿: 49
 

http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200207/02070124.txt
だとすると

>ループで、findfirst関数を使用しているのですが、
>一回目は正常にファイル情報を取得して、正常値を
>返してきます。
>2回目のfindfirstで、エラー値を返してerrnoには
>EINVALを返してきます。

>_findcloseしている所は、_findfirst関数でエラー値が戻ってきた
>場合と、_findnext関数でエラー値が戻ってきた時です。

1回目のfindfirstの後、2回目のfindfirstの前にもfindcloseがいると思います。


返信引用
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
 

>指定したディレクトリに、指定した名前のファイルが
確認タイミングと確認方法を教えてください
方法とタイミングによっては本当に存在しないものが
あるように見えることがあります

できれば現物(ソース)を乗せてください
多少の省略は可能です


返信引用
よっさん
 よっさん
(@よっさん)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

?さん、woodさん返信有難うございます。
以下は、findfirst関数を使用したソースです。
この関数の呼び出し元は、常にループしています。
検索対象ファイルが見つかった場合に、その
ファイルを削除します。
検索対象ファイルは、不定期に作成しています。

#include dykxx000.h

int serchfile (char *pchBuf_File, char *pchBkCsv_Buf, time_t *Create_Time)
{
int inResult; /*
タイムスタンプの比較 */
int inRet_Findnext; /*
findnextの戻り値 */
int inGet_Flg; /*
新しいファイルの存在有無 */
int inMem_Ret;
/* memcmpの戻り値 */
struct _finddata_t c_File; /* _finddata_t 構造
体の宣言 */
long hlFile; /*
ハンドルの戻り値 */
time_t Save_Time; /*
一時保持時間 */

inGet_Flg = 0; /*
フラグの初期化 */
inResult = 0; /*
関数の戻りの初期化 */
Save_Time = 0; /*
一時保持時間の初期化 */
inRet_Findnext = 0; /*
findnextの戻り値を初期化 */
hlFile = 0;
/* ハンドルの初期化 */
inMem_Ret = 0; /*
memcmpの戻り値を初期化 */
errno = 0;
/* エラーnoの初期化 */

/* ファイル1件目の情報を取得する
*/
hlFile = _findfirst(pchBuf_File, &c_File);
if (hlFile != DYKXX_RET_ERR) /* ファイルが存在する場合
*/
{
/* 取得したファイル名がディレクトリ名でない場合
*/
if (c_File.attrib != DYKXX_DIR_PARM)

{
/* 初期時間より取得時間が新しい場合
*/
if (*Create_Time < c_File.time_write)
{
/* 一時保持時間に取得時間を格納する
*/
Save_Time = c_File.time_write;
/* 領域の初期化

*/
memset (pchBkCsv_Buf, (char)NULL, sizeof
(pchBkCsv_Buf));
/* バックアップCSV保管
*/
strcpy (pchBkCsv_Buf, c_File.name);
/* フラグを立てる

*/
inGet_Flg = DYKXX_FLG_ON;
}
}
}
else if(hlFile == DYKXX_RET_ERR)/* ファイルが存在しない場合
*/
{
if (errno == ENOENT) /* ファイルが存在し
ない場合 */
{
/* 呼び出し元に1(正常)を返す
*/
return (DYKXX001_NO_EXIST);
}
else if (errno == EINVAL) /* ファイル名が無効である場合
*/
{
return (DYKXX001_ERROR);/* 呼び出し元に-1(異常)を返す
*/
}
}
/* 次のファイルを取得する
*/
inRet_Findnext = _findnext(hlFile, &c_File);
/* 次ファイルが存在する場合
*/
while (inRet_Findnext != DYKXX_RET_ERR)
{
/* 取得したファイル名がディレクトリ名でない場合
*/
if (c_File.attrib != DYKXX_DIR_PARM)
{
/* 初期時間より取得時間が新しい場合
*/
if (*Create_Time < c_File.time_write)
{
/* フラグがONでない場合
*/
if (inGet_Flg != DYKXX_FLG_ON)
{
/* 時間を保管

*/
Save_Time = c_File.time_write;
/* 領域の初期化

*/
memset (pchBkCsv_Buf, (char)NULL,
sizeof(pchBkCsv_Buf));
/* バックアップCSV保管
*/
strcpy (pchBkCsv_Buf,
c_File.name);
inGet_Flg = DYKXX_FLG_ON; /*
フラグを立てる */
}
/* 一時保持時間より取得時間が古い場合
*/
if (Save_Time > c_File.time_write)
{
/* 一時保持時間に取得時間を格納する
*/
Save_Time = c_File.time_write;
/* 領域の初期化

*/
memset (pchBkCsv_Buf, (char)NULL,
sizeof(pchBkCsv_Buf));
/* バックアップCSV保管
*/
strcpy (pchBkCsv_Buf,
c_File.name);
}
}
}
/* 次のファイルを取得する
*/
inRet_Findnext = _findnext( hlFile, &c_File);
inMem_Ret = 0;
}
_findclose( hlFile); /* ファイ
ルクローズ */
*Create_Time = Save_Time; /* 取得時間を初期設
定時間に格納 */

if (inGet_Flg == DYKXX_FLG_OFF) /* フラグがOFFの場合
*/
{
return (DYKXX001_NO_EXIST); /* 呼び出し元に1(正
常)を返す */
}
return (DYKXX001_EXIST); /* 呼び出し元に0(正
常)を返す */
}

それでは、宜しくお願い致します。


返信引用
よっさん
 よっさん
(@よっさん)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

コメントが、怪しいぐらいに
見づらくなってしまいました。
申し訳ありません。


返信引用
ku
 ku
(@ku)
ゲスト
結合: 25年前
投稿: 312
 

根本的な問題解決とは別ですけど、こんなAPIもありますってことで
ご参考までに
FindFirstChangeNotification
FindNextChangeNotification
FindCloseChangeNotification
WaitForSingleObject

ファイル名が固定なら
HANDLE h = CreateFile(~, OPEN_EXISTING, ~)
if (h != INVALID_HANDLE_VALUE) {
BY_HANDLE_FILE_INFORMATION Info;
GetFileInformationByHandle(h, &Info);
CloseHandle(h);
}
なんて方法もあります(未確認です)


返信引用
よっさん
 よっさん
(@よっさん)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

kuさん返信有難うございます。

検索ファイルパスは、ワイルドカード指定も
できることが前提になっています。

参考までに紹介していただいたAPIも、
調べてみようと思います。


返信引用
よっさん
 よっさん
(@よっさん)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

エラーコードが32で落ちているみたいです。
32の場合は、ファイル共有アクセス違反ですよね。
_FindFirstがFileを掴んだまま離していないのか
と思うのですが、分かる方いらっしゃいましたら
ご教授お願い致します。


返信引用
よっさん
 よっさん
(@よっさん)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

_findfirst、_findnextと、
FindFirstFile、FindNextFileの
2パターンでやってみましたが、
やはり1ファイル取得して、
そのファイルを削除して、
ファイル取得を再度行うと落ちて
しまいます。

対象ディレクトリに、何もファイルが
ない場合は正常に無限ループしています。

FindFirstFileで、検索すること自体が
いけないのでしょうか?
あまり信用できないAPIなのでしょうか?
もし、知っている方がいれば教えて
頂きたいのですが、宜しくお願いします。


返信引用
?
 ?
(@?)
ゲスト
結合: 23年前
投稿: 49
 

しつこいようだけどCloseするタイミング
自分はCFileFindしか使わないので はずれかもしれないけど

DYKXX_RET_ERRというのは見たことがないけど
hlFile != INVALID_HANDLE_VALUE なら
Closeしてもいいのでは?
MSDNのFindFirstFileの頁のサンプルもそうだし
ソースを探すとCFileFind::~CFileFind() でもそうしてるし。

それでだめならCFileFindを使うか
ファイルの削除のほうに問題がないかしらべてみるとか・・・。


返信引用
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
 

MSDNに
>_findfirst が返したハンドルは、_findfirst へ渡されるパスに含まれるディリクトリ
>の上で(削除などの)変更作業を行う前に、_findclose に渡されなければなりません。

こんな記述ありますけど関係ありませんかね~?
VC++5.0のヘルプ索引「_find、_wfind 系関数」ですけど・・・


返信引用
よっさん
 よっさん
(@よっさん)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

?さん返信有難うございます。

_findclose()のタイミングは以下のような
ところで良いと思うのですが。
どうでしょうか?

--------------------------------------------
struct _finddata_t finddata;
long lHANDLE = 0L;
int iRet = 0;
int iReturn = 0;

lHANDLE = _findfirst(*.*, &finddata);
iRet = _findnext(lHANDLE, &finddata);
while( iRet != INVALID_HANDLE_VALUE ){
remove(取得ファイルパス);
iRet = _findnext(lHANDLE, &finddata);
}
_findclose(finddata);
return iReturn;
--------------------------------------------
↑すごく内容を省いたコードですが・・・。

> hlFile != INVALID_HANDLE_VALUE なら
> Closeしてもいいのでは?
hlFile == INVALID_HANDLE_VALUE っていう
事ですよね。

確かにどこのサンプルを見ても、errnoまで
判定しているのは見かけないですね。

ファイルを削除させた後に、もう一度上の関数を
CALLするとファイルの共有違反で落ちてしまう
のですが、ファイル削除をしてすぐにその
ディレクトリを検索しにいくと、共有違反になる
というのはあるのでしょうか?

特にスレッドを使用した処理はしてはいないので、
処理は順番に流れると思うのですが、どなたか
分かる方返信宜しくお願い致します。


返信引用
よっさん
 よっさん
(@よっさん)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

woodさん、返信有難うございます。

すみません、上のソースコードremove()のタイミングがぜんぜん違いました。
remove()するタイミングは、この関数で1つのファイルを取得して、
呼び出し元で消します。
※上のソースは、_findclose()の位置の確認の為、という形でお願いします。

>_findfirst が返したハンドルは、_findfirst へ渡されるパスに含まれるディリクトリ
>の上で(削除などの)変更作業を行う前に、_findclose に渡されなければなりません。

この事なんですけど、_findfirst()で対象にしているディレクトリ内の
ファイルの変更作業は、_findclose()した後で行えば良いという事ですよね?

削除のタイミングは、_findclose()の後に行っている為、問題無いと思います。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました