Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

BufferedWriter、IOとスレッドと出力について

現在、スレッドを使って処理を分散させるプログラムで
出力を行っています。
ソースコードは以下(少々書いたままにしておくと支障
の出るところは省いています)

private void complementMoveDatas() {        //
データを補完して別の場所に!
        // TODO 自動生成されたメソッド・ス
タブ
        File picked_f = 
FilePathUtil.getPickedDataDir();
        ac_dirs = picked_f.listFiles();
        int ac_num = ac_dirs.length;
        
        -------------------1ここから-----
-----------
        
        File test_dir = 
FilePathUtil.getTestDir();
        File f = new File(test_dir, 
"notData.txt");
        BufferedWriter ndo=null;
        try {
            ndo = 
FileUtils.getBufferedWriter(f, false);
            if(ndo==null){
                Log.d("ndo", 
"null");
            }
        } catch (FileNotFoundException e) 
{
            // TODO 自動生成された 
catch ブロック
            e.printStackTrace();
        }
        if(!test_dir.exists()){
            test_dir.mkdirs();
        }
        -------------------1ここまで-----
----------
        int ar = 
Runtime.getRuntime().availableProcessors();
        
System.out.println("availableProcessors: " + ar);
        ExecutorService exec = 
Executors.newFixedThreadPool(1);
        long time1 = 
System.currentTimeMillis();
        File comp = 
FilePathUtil.getComplementedFilesDir();
        if(!comp.exists()){
            comp.mkdirs();
        }
        for(int ac_count = 0; ac_count < 
ac_num; ac_count++){
            Log.d("ac: "+ 
ac_dirs[ac_count].getName());
            for(int day = 0; day<6; 
day++){
                File id = 
getImageFileDir(day);
                if(!id.exists()){
                    
id.mkdirs();
                }
                int count_num = 
(new 
File(ac_dirs[ac_count]+"/MoveData/"+DAYS[day]+"/en
rollment/").listFiles().length) + 1;
                for(int count = 1; 
count<count_num; count++){

                    for(int 
action = 0; action<ACTION_NUM; action++){
                        
final int a_c = ac_count;
                        
final int phase = action;
                        
final int c = count;
                        
final int d = day;

                        
exec.execute(new Runnable() {
                            
@Override
                            
public void run() {
                                
// TODO 自動生成されたメソッド・スタブ
                                
Log.d("ac: "+ ac_dirs[a_c].getName()+" "+c +" 
"+d);
                                
//Log.d(f);
                                
String user_name = ac_dirs[a_c].getName();
                                
File mdf = getMoveDataFile(ac_dirs[a_c], d, c, 
phase);
                                
//System.out.println("mdf: " + mdf);
                                
MoveData md = new MoveData(mdf);
                                
File out_dir = new 
File(FilePathUtil.getComplementedFilesDir(), 
user_name);
                                
if(!out_dir.exists()){
                                    
out_dir.mkdirs();
                                
}
                                
mdf = new File(out_dir, "original-"+d+"-"+c+"-
"+phase+".txt");
                                
//mdf = new File(FilePathUtil.getTestDir(), 
"test.txt");
                                
-------------2ここから---------------
                                
if(md.comfirmIsData(AppUtils.getFingerNumber(phase
))){
                                    
try {
                                        
md.outputMoveData(mdf);
                                        
md = new MoveData(mdf);
                                        
if(1<phase && phase < 23 || phase>28){
                                            
md.complementTouchPointDatas();
                                            
mdf = new File(out_dir, "comp-"+d+"-"+c+"-
"+phase+".txt");
                                            
//mdf = new File(FilePathUtil.getTestDir(), 
"test2.txt");
                                            
md.outputMoveData(mdf);
                                            
md = new MoveData(mdf);
                                            
md.setStartEnd(AppUtils.getFingerNumber(phase));
                                            
md.setpId_();
                                            
mdf = new File(out_dir, "processed-"+d+"-"+c+"-
"+phase+".txt");
                                            
md.outputMoveData(mdf);
                                            
File image_dir = 
FilePathUtil.getComplementedImagesDir();
                                            
if(!image_dir.exists()){
                                                
image_dir.mkdirs();
                                            
}
                                            
File image = new File(image_dir, phase+"-
"+user_name+"-"+d+"-"+c+".png");
                                            
//File image = new File(FilePathUtil.getTestDir(), 
"test.png");
                                            
//                                            
ImageIO.write(md.getBufferedImage(), "png", 
image);
                                            
mdf = new File(out_dir, "statistics-"+d+"-"+c+"-
"+phase+".txt");
                                            
md.writeStatisticsAuthValues(mdf);
                                        
}else if(phase<2){
                                            
md.setStartEnd(AppUtils.getFingerNumber(phase));
                                            
md.setpId_();
                                            
mdf = new File(out_dir, "seted-"+d+"-"+c+"-
"+phase+".txt");
                                            
md.outputMoveData(mdf);
                                            
md.complementTouchPointDatas();
                                            
md.setStartEnd(AppUtils.getFingerNumber(phase));
                                            
md.setpId_();
                                            
mdf = new File(out_dir, "processed-"+d+"-"+c+"-
"+phase+".txt");
                                            
md.outputMoveData(mdf);
                                            
//md.writeStatisticsAuthValues(mdf);
                                            
File image_dir = 
FilePathUtil.getComplementedImagesDir();
                                            
mdf = new File(out_dir, "statistics-"+d+"-"+c+"-
"+phase+".txt");
                                            
md.writeStatisticsAuthValues(mdf);
                                        
}
                                    
} catch (FileNotFoundException e) {
                                        
// TODO 自動生成された catch ブロック
                                        
e.printStackTrace();
                                    
} catch (IOException e) {
                                        
// TODO 自動生成された catch ブロック
                                        
e.printStackTrace();
                                    
}
                                    
--------------2ここまで--------------
                                
}else{
                                
---------------3ここから-----------------
                                    
String str = out_dir.getName()+"-"+d+"-"+c+"-
"+phase+StringProperty.getLS();
                                    
try {
                                        
BufferedWriter memo = FileUtils.getBufferedWriter(                    
                                                
FilePathUtil.getIsDataMemo(),
                                                
true);
                                        
memo.write(str);
                                        
memo.flush();
                                        
memo.close();
                                    
} catch (IOException e) {
                                        
// TODO 自動生成された catch ブロック
                                        
e.printStackTrace();
                                    
}
                                
}
                                
                                
//System.out.println("run: "+phase);
                                
--------------3ここまで-----------------
                            
}
                        
});
                    }
                }
            }
        }

        try{
            exec.shutdown();

            
if(!exec.awaitTermination(Long.MAX_VALUE, 
TimeUnit.SECONDS));
        } catch (InterruptedException e){
            
System.out.println("awaitTermination interrupted: 
" + e);
            exec.shutdownNow();
        }
        long time2 = 
System.currentTimeMillis();
        System.out.println(time2 - time1);
    }
    
 ※「-----1ここから------」といったように書いた
部分は説明のためのもので、実際のコードには存在しま
せん。
 仕組みとしては,1でログファイルを
BufferedWriter(変数名ndo)で開きます.これはミスで
開きっぱなしになっていました.
 そして,2の部分でログファイルとは違うファイルを
読み込み,オブジェクトを生成.そのオブジェクトが
「処理すべきデータ」であれば
(if(md.comfirmIsData(AppUtils.getFingerNumber(pha
se))) 部分で判定)しかるべき処理を行い,ログファ
イルとは違うファイルに処理を施したものを書き出しま
す.このファイルは生成されるオブジェクトごとに決ま
る名前のファイルになります。
 3では2でオブジェクトが「処理すべきデータ」でな
い場合は,ログファイルFilePathUtil.getIsDataMemo()
に出力します。これは1で開いたものと同じログファイ
ルをどのスレッドでも開きます.
 このコードを書いてからあとで気づいたのですが、3
にて,ログファイルを開くタイミングなどが競合した場
合,どうなるのでしょうか。そのまま同時に書き込まれ
るか,処理がストップするのでしょうか。2で出力され
るべきファイル群に影響は出ますでしょうか.
 ちなみに、このあと1にてndoがクローズされ,また
ログファイルがない場合はフォルダも含めて作成される
ように書き換え,またFilePathUtil.getIsDataMemo()で
もスレッドごとに個別のログファイルに書きだすように
変えましたが,この場合に2で出力されるべきファイル
群が修正前より変化するということはありえるでしょう
か?

 別に修正前に競合していても、処理が止まらず、修正
後と同じデータが出ていればいいのですが、生憎実行す
るためには時間のかかる作業が別途必要になります.
 申し訳ありませんが、皆様のお知恵から、アドバイス
をお願い致します。

5

回答

7847

閲覧

5件の回答

評価

0

「時間がない」てのは、本来理由にならない。
質問者の周りにいる人間ならともかく、ネットの向こうの
人間にはそれが本当なのか、言い訳なのか判断できない。
何より、その「時間のかかる作業」を赤の他人に無償で
肩代わりさせようとしてるのが問題だ。

気になっているのはファイル出力なのだから、このコードを
そのまま使うのではなく、ファイル出力だけのコードを
書いてマルチスレッドで流してみればいい。

評価

0

申し訳ありません。
一般的なスレッド処理とBufferedWriterの効果につい
て、お聞きしたかっただけなのです。
当方強迫神経症を患っておりまして、ファイル出力だけ
のコードを書いて流してみても、おそらくこのコードを
実行しなければ、と考えてしまうのです。
また、このコードに読み込んでいるだけの元データにも
なにかこのコードにより問題が発生していたら…などと
わけもわからない不安に因われるばかりで。

要するに、IOでの知識、判断力が現在無いために、
1.IOで特にロックなどかけずに読み込むだけだと、書
き込みのメソッドをどうにもしない限り元データはキズ
つかないか2.別スレッドで同じものに書き込んでも
1.のように元データに傷がつかないか
といった判断ができない状態です。

最低限、1.さえ自分で確信できればこのコードを確か
めることもできるのですが。
自分の情けなさと甘さに後悔するばかりです。申し訳あ
りません。

もし、1.にでもお答え頂けるのでしたら、どうか何卒
お願いします。

評価

30

だからそういう、確かめようもないし他人に関係もないことを書いても仕方ないんだって。
たとえ本当に病気だとしても、それを斟酌する必要はないんだし。

>IOで特にロックなどかけずに読み込むだけだと、書
>き込みのメソッドをどうにもしない限り元データはキズ
>つかないか

「元データ」が何を示していて、「キズつ」くがどういう状態なのか判らんので、一般的なところで。

読むのと書くのとが別のリソースであれば、読み書きは相互に何の関係もない。
同じリソースに対して同時に読み込みする場合も関係がない。
同じリソースに対して同時に読み書きまたは書き込みする場合は、壊れるかもしれないし、壊れないかもしれない。一瞬でも遅かった方がエラーになるかもしれない。

これはその他のコードには関係なく、読み書き自体のタイミングと構造の話だ。
複数スレッドでも、システム的に同時アクセスがあり得ないか、またはタイミングが制御できるなら、ロックなんぞ無くても期待どおり動作する。
ロックが必要なのは、そのリソースに対して同時にアクセスが発生するのを防げないからだ。

ミニマムコードでの結果は、同一のコードが入ったより大きなコードでも適用される。
上っかぶせするコードにタイミングを制御する機構があれば別だが、無いからこその質問なんだろう。

そもそも、本当にそのコード自体でなければダメだと思うなら、それこそこんなところで回答を待つ時間を使って確認すべき。
繰り返しになるが、「時間のかかる作業」を、赤の他人を使って回避しようなんぞ思わないことだ。

評価

0

ありがとうございます。
だいぶん自分の判断力が落ちていたことに気づき、目の覚め
る思いです。
回答者様の言葉をしっかり学んで学習して行きます。
ありがとうございました。

評価

0


今日は超嬉しかった!!通信販売で素敵な名ブランドバックを購入した。価額は1万円ぐらいしか使っていなかった。代金を支払って、5日後商品が着きました。
鞄の質がとてもいいですね。私は大変好きです。
この店にの商品は市場のと比べると、価格が安いですよ。
では、この店のウェブサイトを皆に教えます。
www.roiexjp.biz皆速く買いに行ってくださいね。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。