ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2017年11月21日(火) 20:45

All times are UTC+09:00




新しいトピックを投稿する  トピックへ返信する  [ 4 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2005年11月06日(日) 21:23 
オフライン

登録日時: 2005年5月31日(火) 10:52
記事: 264
住所: 高知
UNIX系のCに標準で入っているディレクトリ操作用の関数です。
Windows:VC++版と同等になるように設計したので問題は無いと思いますが
誤りがあった場合、書き込みして頂けると幸いです。

[hide=コードはこちら]
コード:
Const DIRMAGIC = &HDDAA

Type DIR
	_d_hdir As HANDLE
	_d_dirname As *Char
	_d_magic As DWord
	_d_nfiles As DWord
	_d_buf As WIN32_FIND_DATA
End Type

Function opendir(dirname As *Char) As *DIR
	Dim name As *Char
	Dim len As Long
	Dim dir As *DIR

	len = lstrlen(dirname)

	name = malloc(len+5)
	If name = NULL Then
		Exit Function
	End If

	lstrcpy(name,dirname)

	len=len-1
	If len>0 and name[len]<>Asc(":") and name[len]<>Asc("\") and name[len]<>Asc("/") Then
		lstrcat(name,"\*.*")
	Else
		lstrcat(name,"*.*")
	End If

	dir = malloc(SizeOf(DIR))
	If dir = NULL Then
		free(name)
		Exit Function
	End If

	dir->_d_hdir = FindFirstFile(name,dir->_d_buf)
	If dir->_d_hdir = INVALID_HANDLE_VALUE Then
		free(name)
		free(dir)
		Exit Function
	End If

	dir->_d_dirname = name
	dir->_d_magic = DIRMAGIC
	dir->_d_nfiles = 1
	opendir = dir
End Function

Sub rewinddir(dir As *DIR)

	If dir = NULL Then
		Exit Sub
	Else
		If dir->_d_magic <> DIRMAGIC Then
			Exit Sub
		End If
	End If

	FindClose(dir->_d_hdir)
	dir->_d_hdir = FindFirstFile(name,dir->_d_buf)
	If dir->_d_hdir = INVALID_HANDLE_VALUE Then
		free(name)
		free(dir)
		Exit Sub
	End If
	dir->_d_nfiles = 1
End Sub

Function readdir(dir As *DIR) As String

	If dir = NULL Then
		Exit Function
	Else
		If dir->_d_magic <> DIRMAGIC Then
			Exit Function
		End If
	End If

	If dir->_d_nfiles = 0 Then
		If FindNextFile(dir->_d_hdir,dir->_d_buf) = FALSE Then
			Exit Function
		End If
	End If
	dir->_d_nfiles = 0

	readdir = MakeStr(dir->_d_buf.cFileName)
End Function

Function closedir(dir As *DIR) As Long
	If dir = NULL Then
		closedir = -1
		Exit Function
	Else
		If dir->_d_magic <> DIRMAGIC Then
			closedir = -1
			Exit Function
		End If
	End If

	FindClose(dir->_d_hdir)
	free(dir->_d_dirname)
	free(dir)
End Function
[/hide]
[hide=詳しい情報はこちら]
DIRMAGIC(&HDDAA)
何の事だかさっぱり分かりませんがマジッククッキーなるものが
VCで調査した所、必ずこの値だったのでそのまま使用。
コード:
Const DIRMAGIC = &HDDAA

DIR構造体
全ての関数がこの構造体を介してディレクトリ内を列挙します。
_d_hdir ファイル検索ハンドル。
_d_dirname 現在検索中のディレクトリ名。
_d_magic ディレクトリのマジッククッキーらしいが何なのか不明。
_d_nfiles VCだとreaddirを呼ばない状態は1、呼んだ後は0。
_d_buf 本当はChar型の配列だったけど面倒なので移植時に仕様変更。
コード:
Type DIR
	_d_hdir As HANDLE
	_d_dirname As *Char
	_d_magic As DWord
	_d_nfiles As DWord
	_d_buf As WIN32_FIND_DATA
End Type

opendir関数
引数に指定したディレクトリを開いて列挙の準備をする。
戻り値はDIR構造体へのポインタ、関数が失敗すると0が返る。
ディレクトリの列挙が必要なくなった場合、必ずclosedir関数を呼んで検索ハンドルを破棄すること。
コード:
Function opendir(dirname As *Char) As *DIR

rewinddir関数
ディレクトリの列挙を最初からやり直す。
引数にはopendir関数の戻り値であるDIR構造体へのポインタを渡します。
この関数に戻り値はありません。
コード:
Sub rewinddir(dir As *DIR)

readdir関数
ディレクトリ内で列挙されたファイル名及びフォルダ名を取得します。
VCではdirent構造体へのポインタが返りますが、メモリの開放なんぞが面倒なので移植時にString型に仕様変更しました。
取得したファイル及びフォルダの追加情報がほしい場合はDIR構造体の_d_bufメンバWIN32_FIND_DATA構造体にアクセスしてください。
コード:
Function readdir(dir As *DIR) As String

closedir関数
ディレクトリの列挙を終了します。
無効なDIRへのポインタを渡した場合、関数は失敗して0以外(-1)を返します。
コード:
Function closedir(dir As *DIR) As Long
[/hide]
[hide=使用法はこちら]
ディレクトリ「C:\」内を列挙する場合は次のようにします。
コード:
#N88BASIC

/* ディレクトリを開く */
Dim dir As *DIR
dir=opendir("C:\")

/* ディレクトリの列挙をする */
Dim s As String
s=readdir(dir)

While s<>"" /* 列挙が終了すると空の文字列が返る */
	Print s
	s=readdir(dir)
Wend

/* ディレクトリを閉じる */
closedir(dir)
[/hide]


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年11月06日(日) 23:19 
オフライン

登録日時: 2005年5月31日(火) 17:59
記事: 895
住所: 東京都
こういうものを見るとクラス化したくなります。ということで作りました。
[hide]
コード:
Class FileEnumeration
Public
	Sub FileEnumeration(DirName As *Char)
		dir = opendir(DirName)
	End Sub
	
	Sub ~FileEnumeration()
		closedir(dir)
	End Sub

	Function Read() As String
		Read = readdir(dir)
	End Function

	Function ReadDetail() As *WIN32_FIND_DATA
		ReadDetail = VarPtr(dir->_d_buf)
	End Function

	Sub Rewind()
		rewinddir(dir)
	End Sub
Private
	dir As *DIR
End Class
[/hide]
このクラスを使ってNoWestさんの例と同じことを行うコードはこうなります。
コード:
#strict
#N88BASIC

' オブジェクトの作成(と同時に開く)
Dim dir As FileEnumeration("C:\")

' ディレクトリの列挙
Dim s As String
s = dir.Read()

While s <> ""
    Print s
    s = dir.Read()
Wend


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年11月07日(月) 00:06 
オフライン

登録日時: 2005年5月31日(火) 10:52
記事: 264
住所: 高知
引用:
> こういうものを見るとクラス化したくなります。ということで作りました。
確かにクラス化しておけば便利ですね。

ディレクトリ操作ついでにファイル操作も移植してみたり(笑

[hide=コードはこちら]
コード:
Type FILE
	curp As *Byte
	buffer As *Byte
	level As Long
	bsize As Long
	istemp As Word
	flags As Word
	hold As Word
	fd As Char
	token As Byte
End Type

Declare Function fopen CDECL Lib "crtdll" (__path As *Char, __mode As *Char) As *FILE
Declare Function fclose CDECL Lib "crtdll" (__stream As *FILE) As Long
Declare Function fflush CDECL Lib "crtdll" (__stream As *FILE) As Long
Declare Function fprintf CDECL Lib "crtdll" (__stream As *FILE, __format As *Char, ...) As Long
Declare Function fscanf CDECL Lib "crtdll" (__stream As *FILE, __format As *Char, ...) As Long
Declare Function feof CDECL Lib "crtdll" (__fp As *FILE) As Long
[/hide]

こんなのって需要あるんでしょうかね?
機会があればまた、新しいスレで公開しますか。。。


通報する
ページトップ
 記事の件名: おもしろい!
投稿記事Posted: 2010年6月07日(月) 04:09 
でもね、何でもクラスにしてまうのは愚の骨頂


通報する
ページトップ
   
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 4 件の記事 ] 

All times are UTC+09:00


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[1人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
cron
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by KONISHI Yohsuke