C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: 一行上は実行されて、その下の行は実行されない


(過去ログ 115 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■68035 / inTopicNo.1)  一行上は実行されて、その下の行は実行されない
  
□投稿者/ Jimmy (1回)-(2013/09/17(Tue) 22:11:06)

分類:[Java] 

2013/09/17(Tue) 22:15:47 編集(投稿者)
はじめまして。Eclipse4.3でJavaを使っています。

<プログラムの内容>
あるディレクトリを監視して、そのディレクトリ内部に変更があれば、その情報を管理している変数を操作するというものです。
将来的には、2つのディレクトリが同期され、ディレクトリ内が同じ状態にできるプログログラムにしたいと思っています。


<バグ>
ですが、原因がわからないバグがあり、
それが起こるときは、
あるフォルダを消し、また、そのフォルダと同名のフォルダを作った時です。
このとき、最終更新時刻が変更された認識され、変数(Vector<File>)の情報の lastModify が変更されるようにします。
変更が見てわかるように、
files.get(i).lastModified();
System.out.println("更新");
のようにしても、"更新"と表示されません。
ですが、変数(Vector<File>)の情報は変更されているのが後で確認できます。


<出力結果>
動作結果はこんな感じです。

「新しいフォルダー」 更新日:Tue Sep 17 21:44:11 JST 2013
「新しいフォルダー (2)」 更新日:Tue Sep 17 21:44:15 JST 2013


「新しいフォルダー」 更新日:Tue Sep 17 21:44:11 JST 2013
「新しいフォルダー (2)」 更新日:Tue Sep 17 21:44:15 JST 2013
「新しいフォルダー (3)」 更新日:Tue Sep 17 21:44:19 JST 2013


「新しいフォルダー」 更新日:Tue Sep 17 21:44:11 JST 2013
「新しいフォルダー (2)」 更新日:Tue Sep 17 21:44:15 JST 2013
「新しいフォルダー (3)」 更新日:Tue Sep 17 21:44:19 JST 2013
「新しいフォルダー (2) - コピー」 更新日:Tue Sep 17 21:44:15 JST 2013
「新しいフォルダー (3) - コピー」 更新日:Tue Sep 17 21:44:19 JST 2013
「新しいフォルダー - コピー」 更新日:Tue Sep 17 21:44:11 JST 2013

ーーーーーー
初期状態として、2つのフォルダがあり、
その後1つ追加しました。
あとは全コピペして、フォルダ数が2倍に増えています。



<ソース>
ソースを載せます。2つのクラスでできています。

1つ目のクラスは、ディレクトリの中の変化を調べるもの。
2つ目クラスは、File配列です。Vectorを使っていて、今後、今以上にこれ独自のメソッドがいると思われるので、新しいクラスとして宣言しています。

C:\\Users\\****\\Desktop\\1となっているのは、変更が必要です。

<1つ目 DirectorySynchronize.java>
import java.io.File;
import java.util.Date;
import java.util.Scanner;


public class DirectorySynchronize extends Thread{
	// 同期元・先のデレクトリのパス
	static String sourceDirectoryPath = "C:\\Users\\****\\Desktop\\1";
	static String destinationDirectoryPath = "C:\\Users\\****\\Desktop\\2"; // まだこの変数は使われていません
	
	// 同期元・先のデレクトリのFileオブジェクト
	static File sourceDirectory = new File(sourceDirectoryPath);
	static File destinationDirectory = new File(destinationDirectoryPath);
	
	// 同期した情報を記録
	static SynchronizeData synData = new SynchronizeData();
	
	public static void main(String[] args) throws InterruptedException{
		
		while(true){
			new DirectorySynchronize().start();
			sleep(100);
		}
	}
	
	public void run(){
		File[] listFiles =sourceDirectory.listFiles();
		// System.out.println(listFiles.length);
		boolean hasAdded = false;
		for(File el: listFiles){
			if(synData.add(el)){
				hasAdded =true;
			}
		}
		if(hasAdded == true){
			System.out.println(synData);
		}
		
	}
}

<2つ目 SynchronizeData.java>
import java.io.File;
import java.util.Date;
import java.util.Vector;

public class SynchronizeData {
	Vector<File> files = new Vector<File>(0);
	
	boolean add(File addFile){
		String addFileName = addFile.getName();
		long addFileLastModify = addFile.lastModified();
		
		for(File el : files){
			if(el.getName().equals(addFileName)){
				if(el.lastModified() == addFileLastModify){
					return false;
				} else {
					el.setLastModified(addFileLastModify);
					System.out.println("更新"); //    <バグ> これが表示されないのにデータは正しく変更されている(つまりこの上の行は正しく動いている(?))
					return true;
				}
			}
		}
		files.add(addFile);
		return true;
	}
	static void myMethod(){
		System.out.print("Nnnn");
	}
	
	public String toString(){
		StringBuffer sb = new StringBuffer();
		for(File el: files){
			sb.append("「"+el.getName()+"」 更新日:"+new Date(el.lastModified())+"\n");
		}
		sb.append('\n');
		return sb.toString();
	}
}

<バグを確認する手順>
1 同期元の中のフォルダを1つします(「新しいフォルダー」だけにします)。
2 ここで、プログラムを実行させ、「新しいフォルダー」 更新日:Tue Sep 17 21:58:58 JST 2013 のようなことがでるのを確認します。
3 そして、「新しいフォルダー」を消し、0個にします。
4 「新しいフォルダー」をまた作ります。
5 「新しいフォルダー(2)」を作ります。

すると、出力結果は追加され、結果的に、


「新しいフォルダー」 更新日:Tue Sep 17 21:58:58 JST 2013


「新しいフォルダー」 更新日:Tue Sep 17 22:01:52 JST 2013
「新しいフォルダー (2)」 更新日:Tue Sep 17 22:01:54 JST 2013
となります。

よくみると、2つの「新しいフォルダー」の更新時刻は、 21:58:58と22:01:52で異なっています。
つまり、変数(Vector<File>)がしっかりと更新されたことがわかります。
ですが、"更新"と表示はされません。

一体何が起こっているのですか?
お力を貸してください!
</pre></pre>

引用返信 編集キー/
■68036 / inTopicNo.2)  Re[1]: 一行上は実行されて、その下の行は実行されない
□投稿者/ 魔界の仮面弁士 (346回)-(2013/09/17(Tue) 22:23:16)
2013/09/17(Tue) 22:27:16 編集(投稿者)

No68035 (Jimmy さん) に返信
> あるディレクトリを監視して、
コード中のコメントが、「ディレクトリ」→「デレクトリ」になってしまっていますよ。

> あるフォルダを消し、
現行OSでは、「フォルダー」が正式名称ですね。


> また、そのフォルダと同名のフォルダを作った時です。
レジストリ エディター等で、
 HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\
のキーの下に、"MaximumTunnelEntries" という DWORD 項目を作り、
そこに値 0 をセットして OS を再起動すれば解消するかも知れません(未確認)。
http://support.microsoft.com/kb/172190
引用返信 編集キー/
■68037 / inTopicNo.3)  Re[1]: 一行上は実行されて、その下の行は実行されない
□投稿者/ Azulean (213回)-(2013/09/17(Tue) 22:45:59)
2013/09/17(Tue) 22:46:46 編集(投稿者)

No68035 (Jimmy さん) に返信
> よくみると、2つの「新しいフォルダー」の更新時刻は、 21:58:58と22:01:52で異なっています。
> つまり、変数(Vector<File>)がしっかりと更新されたことがわかります。
> ですが、"更新"と表示はされません。

File クラスはあなたが作ったものではなく、クラスライブラリとして用意されているものですよね?
そうだとすると、「更新」の場所を通ったのではなく、単に toString が実行されたときの最新の情報をドライブから読み込んでいるだけでは?

1.新しいフォルダ 21:58 ができる。→ files に記録される。
2.新しいフォルダが消される。 → files には残っている。
3.新しいフォルダ 22:01 ができる。 → files に残っているものと比較しようとするが、同じものを比較するので更新しない。


File クラスって、結局 lastModified を実行する時点でその場所にある更新日時を採るのではないのでしょうか。
そうだとすれば、if(el.lastModified() == addFileLastModify) は必ず同じものになります。
なので、あなたが考えるものを作るためには、File クラスではなく、自分で新しく「ファイルパス」と「最後にチェックしたときの日時」を保持するクラスを作り、使う必要があるでしょう。
引用返信 編集キー/
■68049 / inTopicNo.4)  Re[2]: 一行上は実行されて、その下の行は実行されない
□投稿者/ Jimmy (2回)-(2013/09/18(Wed) 16:52:58)
魔界の仮面弁士さん、Azuleanさんご回答感謝します。
問題の原因が理解出来ました。


魔界の仮面弁士さん
>■No68035 (Jimmy さん) に返信
> あるディレクトリを監視して、
>コード中のコメントが、「ディレクトリ」→「デレクトリ」になってしまっていますよ。

> あるフォルダを消し、
>現行OSでは、「フォルダー」が正式名称ですね。

ご指摘ありがとうございます。あまり考えずに打ってました。
フォルダーが正式名称とはしりませんでした。

コンピュータ コンピューター
プログラマ プログラマー
とかもどちらが一般的ぐらいはおそらくあるのでしょうね。

> HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\
>のキーの下に、"MaximumTunnelEntries" という DWORD 項目を作り、
>そこに値 0 をセットして OS を再起動すれば解消するかも知れません(未確認)。
>http://support.microsoft.com/kb/172190

聞きなれない言葉ばかりで、よくわかりませんでした。
ごめんなさい。


Azuleanさん
理解出来ました。
java.io.Fileクラスの仕様を勘違いしていました。
更新日を記録する変数を用意して、自作のクラスを作ってみます。

魔界の仮面弁士さん、Azuleanさんも調べてみると、かなりヒットして、有名なお方ということがわかりました。
そんな方に解答がいただけて嬉しいです。

回答してくださったかた以外に、私の読みづらい説明とソースを読んでいただいた方にも感謝します。
ありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -