ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Javaの課題丸投げコミュの課題・ファイルコピーの中断要求

  • mixiチェック
  • このエントリーをはてなブックマークに追加
はじめまして、ヨロシクお願い致します。

【 課題 】
* FileCopy2.javaファイルコピー中に中断要求
* yまたはY が入力された場合ファイルコピーを中断
その後 次のファイル名入力作業へ移る
* yまたはY以外の文字が、入力された場合コピーを継続、
コピー完了後、次のファイル名入力作業へ移る

現在ファイルのコピーまで作っております。
qでプログラムを中止できるのですが、yで
cp.join()でスレッドの制御をしようと思ったのですが、
うまく出来てません。よろしくお願い致します。

【ソース】
import java.io.*;
import java.util.*;

class FileCopy extends Thread{
String srcFile;
String dstFile;
// コンストラクタ(コピー元、コピー先ファイル名を受け取る)
FileCopy(String srcFile, String dstFile){
this.srcFile = srcFile;
this.dstFile = dstFile;
}

public void run(){
this.setName( srcFile + "→" + dstFile);
try {
// 入力ストリームを作成。
FileReader fr = new FileReader(srcFile); // srcFileは入力ファイル名。
BufferedReader br = new BufferedReader(fr);
// 出力ストリームを作成。
FileWriter fw = new FileWriter(dstFile); // dstFileは出力ファイル名。
BufferedWriter bw = new BufferedWriter(fw);

// 読込みループ。
String line; // 読み込まれた1行。
while( (line = br.readLine()) != null ) {
bw.write(line); bw.newLine();
}
// 入力・出力ストリームを閉じる。
br.close(); fr.close();
bw.close(); fw.close();
}
catch (FileNotFoundException e){
System.err.println("▲例外 : ファイルが無い▲");
}
catch (IOException e) {
System.err.println("●入出力例外●");
e.printStackTrace();
return;
}
if (srcFile.equals("y")){
System.err.println("????");
return;
}
if (dstFile.equals("y")){
System.err.println("????");
return;
}

try{
Thread.sleep(10000);
}catch(InterruptedException e){
}
System.out.println("["+ this.getName() + "] コピー完了");
System.out.println();
}
}

public class FileCopy2{
public static void main(String[] args){
String srcFile;
String dstFile;
while(true){
Scanner stdln = new Scanner(System.in); // キーボードで入力
System.out.println("ファイル名を入力してください(拡張子まで)");
System.out.print("コピー元:");
srcFile = stdln.next();//入力待ち
if(srcFile.equals("q")){
System.out.println("終了します");
return;
}
System.out.print("コピー先:");
dstFile = stdln.next();//入力待ち
if(srcFile.equals("q")){
System.out.println("終了します");
return;
}
FileCopy cp = new FileCopy(srcFile, dstFile);
cp.start();
if(dstFile.equals("y")){
System.out.println("途中終了します");
//cp.join(); ※ここが上手くいってないです…他が原因かも
return;
}
System.out.println();
}
}
}

コメント(8)

cp.join()という呼び出しは、スレッドcpが終了するまで、現在のスレッドをブロックすることを意味します。
なので、joinしても、途中でスレッドの実行を止めることは出来ません。
そのような用途では、stopメソッドが使用できますが、APIリファランスを見れば分かるように、このメソッドの呼び出しは推奨されません。

安全に止めるのであれば、

1. Threadの継承クラス内に、実行を継続するかどうかを表すメンバーを作成する。
2. スレッドの実行中にそれを定期的に確認し、終了を表す値であれば、終了処理を行う。
3. 外部からスレッドを止める場合には、そのメンバーの値を書き換える。

という手順が必要になります。
あと、srcFile, dstFileの扱いを根本的に勘違いしている気がします。
全体像としては以下のようになるはずです。

class FileCopy extends Thread{
 String srcFile;
 String dstFile;

 private boolean alive = true;

 FileCopy(String srcFile, String dstFile){
  this.srcFile = srcFile;
  this.dstFile = dstFile;
  this.setName( srcFile + "→" + dstFile);
 }

 public void setAlive(boolean alive) { this.alive = alive; }
 public boolean getAlive() {return alive;}
 
 public void run(){
  //ファイルコピーの準備
  while(){
   if(!alive) break;
   //ファイルコピーの処理

  }
  //クローズ処理
  //コピー終了の出力
 }
}

publicクラス宣言は省略

void main(String[] argv){
 
 //srcFile, dstFileの入力処理
 
 white(true){
 
  FileCopy cp = new FileCopy(srcFile, dstFile);
  cp.start();
 
  //srcFile, dstFileの入力処理
  
  if(dstFile.equals("y")){
   cp.setAlive(false);
   System.out.println("途中終了します");
  }
  cp.join(); //このjoinはなくても良いが、間違いではない。
 }
}
それから言い忘れましたが、ファイルコピーなら基本的には、FileInputStream/FIleOutputStreamを使って、byte配列をバッファに使って転送するべきだと思います。Reader/Writerを使うとバイナリファイルでの動作が保証されません。

大ざっぱに言うと以下のような感じ。

class TransferStream extends Thread{
 InputStream in;
 OutputStream out;

 public TransferStream(InputStream in, OutputStream out, String name){
  this.in = in;
  this.out = out;
  this.setName(name);
 }
 public void run() {
  byte[] buf = new byte[1024];
  try{
   try{
    int len = 0;
    while((len = in.read(buf)) >=0){
     out.write(buf, 0, len);
    }
   }
   catch(IOException e1){
    //e1.printStackTrace(System.out);
   }
   out.close();
   in.close();
   
  }
  catch(Exception e2){
   e2.printStackTrace(System.out);
  }
 }
}
皆様、ありがとうございます。
何とか上手く出来そうです。
後は表示に関することなので、もう少し頑張ってみます。

本当にありがとうございました(^0^)

//FileCopier2.java

import java.io.*; //入出力ストリームのため
import java.util.*;//Scannerクラスのため

class Copier extends Thread{

String srcFile;
String dstFile;
private boolean alive = true;

// コンストラクタ(コピー元、コピー先ファイル名を受け取る)
Copier(String srcFile, String dstFile){
this.srcFile = srcFile;
this.dstFile = dstFile;
this.setName( srcFile + "→" + dstFile);
}

public void setAlive(boolean alive) { this.alive = alive; }
public boolean getAlive() {return alive;}

// Threadクラスのrunメソッドをオーバーライド
public void run(){
this.setName( srcFile + "→" + dstFile);
// ファイル入力ストリーム
FileInputStream fis = null;
// ファイル出力ストリーム
FileOutputStream fos = null;
try{
/* ストリームopen処理 */

// ファイル入力ストリームopen
fis = new FileInputStream( srcFile );
// ファイル出力ストリームopen
fos = new FileOutputStream( dstFile );

/* 読み込み・書き込み処理 */
int tmpInt = 0; //temp tmp 一時的な

while( (tmpInt = fis.read()) != -1 ){
fos.write( tmpInt );// 読み書きの間はストリームはオープン
if(!alive) break;
}

fis.close();
fos.close();

// 例外処理
} catch (FileNotFoundException e){
System.err.println("▲例外 : ファイルが無い▲");
} catch (IOException e) {
System.err.println("●入出力例外●");
e.printStackTrace();
return;
}
try{
Thread.sleep(1000);
}catch(InterruptedException e){
}

System.out.println("["+ this.getName() + "] コピー完了");
System.out.println();
}
}


public class FileCopier2{

public static void main(String[] args){

String srcFile;
String dstFile;


Scanner stdln = new Scanner(System.in); // キーボードで入力
System.out.println("ファイル名を入力してください(拡張子まで)");
System.out.print("コピー元:");
srcFile = stdln.next(); //入力待ち

if(srcFile.equals("q")){
System.out.println("終了します");
return;
}

System.out.print("コピー先:");
dstFile = stdln.next(); //入力待ち
if(dstFile.equals("q")){
System.out.println("終了します");
return;
}



while(true){


Copier cp = new Copier(srcFile, dstFile);
cp.start();

Scanner stdln2 = new Scanner(System.in); // キーボードで入力
System.out.println("ファイル名を入力してください(拡張子まで)");
System.out.print("コピー元:");
srcFile = stdln2.next(); //入力待ち

if(srcFile.equals("q")){
System.out.println("終了します");
return;
}

System.out.print("コピー先:");
dstFile = stdln2.next(); //入力待ち
if(dstFile.equals("q")){
System.out.println("終了します");
return;
}

if(srcFile.equals("y")){
cp.setAlive(false);
System.out.println("途中終了します");
continue;
}

if(dstFile.equals("y")){
cp.setAlive(false);
System.out.println("途中終了します");
continue;
}

System.out.println();
}
} //end of main()
}// end of class definition

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

Javaの課題丸投げ 更新情報

Javaの課題丸投げのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング