仕事を頑張る人のおしりトラブル対策

はじめまして。
初心者ですが、今非常に困っております。
RandomAccessFileを使用して、ファイルの排他をしたいのですが・・・。具体的に言うと、AがAAA.xmlをOPEN中にBがAAA.xmlをOPENしようとするとAがOPEN中なので、例外処理に飛ばしたいのです。いくら試みても例外処理に飛びません。

<例>(java version "1.3.1.05")
try
{
raf = new RandomAccessFile("AAA.xml","rw"); // OPEN
raf.writeBytes(111); // WRITE1
raf.writeBytes(222); // WRITE2
raf.writeBytes(333); // WRITE3
raf.writeBytes(444); // WRITE4
raf.writeBytes(555); // WRITE5
raf.close(); // CLOSE
}
catch(IOException e)
{
// 排他制御に失敗. リトライしたい
System.out.println("別のプロセス?が使用中")
}


 心当たりのある方がいらしゃいましたら、ご協力お願い致します。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

JDK1.3 で排他制御を行うなら、参考URLにある「Singleton」パターン辺りを応用して、


こんな感じで自前で実装されてはいかがでしょうか?

なお、実際に動かしたわけではないですし、あくまで
簡単な例です。使うときには、もっと考えてください。。。

public FileLock {
 private static RandomAccessFile raf = null;

 synchronized static public RandomAccessFile open(String file, String mode)
 throws IOException {
  if( raf == null ) {
   raf = new RandomAccessFile(file, mode);
   return raf;
  }
  else {
   throw new IOException("別プロセスが利用中");
  }
}

synchorized public static void close() {
  raf.close();
  raf = null;
 }
}

参考URL:http://www.dmz.hitachi-sk.co.jp/Java/Tech/patter …
    • good
    • 0

RandomAccessFile を使ってファイルを読み書きするだけでは、ファイルをロックしたことにはなりません。

これは、FileInputStream や FileOutputStream などを使っても同じです。

Java のバージョン 1.4 では、ファイルの排他制御に関するクラスが提供されています。

RandomAccessFile#getChannel() で FileChannel オブジェクトを取得し、その lock() メソッドを使ってロックします。

バージョン 1.3 では、残念ながらファイルの排他制御はできません。
    • good
    • 0

JavaはOSやプラットフォームに依存しないように設計された言語ですが、ファイルの指定はOS固有の方法に依存します。

また現時点でファイルに対する排他制御(ロック)の機能は提供されていません。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QBufferedWriter(OutPutStream).write(String)で追記がしたい

環境
windowsXP+tomcat4.0.1

Servlet内でExceptionをcatchし、ファイルに書き出したいのですが、追記が出来ません。上書きされてしまって困っています。

コード:
FileOutputStream fos = new FileOutputStream(String);
OutputStreamWriter osw = new OutputStreamWriter(fos,"M932");
BufferedWriter bw = new BufferdWriter(osw);
bw.write(String);

最後のwrite()を追記型で起動したいのですが、参考書にBufferedWriterクラスに関することがほとんど載っていないため、どうしたらいいのやら。
ご存知の方がいましたら、ご回答お願いいたします。

Aベストアンサー

new FileOutputStream(String, true)で追記されます。

Javaのプログラムを組むときはAPIリファレンスは必須です。HTML形式のものがsunのサイトからダウンロードできますので不明な点があったらまずAPIリファレンスを見ましょう。

Qファイル読み込み/書き込み速度を上げるには

下記のようなファイルの読み込み/書き込み処理において、もっと効率よく(速く)読み込み・書き込みをしたい場合どのような工夫をすれば良いでしょうか?

BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("sample2.data"));
BufferedInputStream in = new BufferedInputStream(new FileInputStream("sample1.data"));
int c ;
while((c = in.read()) != -1)
{
out.write(c);
}
in.close();
out.flush();
out.close();

Aベストアンサー

速くなるかどうかは環境によって微妙に違うと思いますが、効率よくやる方法が2つあります。

1. 1バイトづつ読み書きするのではなくて byte[] で1000バイトとかの塊を読んでそのまま塊を書くようにする。(こうすると read, write をする回数が減るので少し速いと思います)。

2. FileInputStream と FileOutputStream のインスタンス双方から getChannel() で java.nio.channels.FileChannel のインスタンスを取り出し、FileOutputStream 側から取り出した FileChannel のインスタンスに対して transferFrom() で FileInputStream 側から取り出した FileChannel のインスタンスを指定する。

例) in は FileInputStream のインスタンス, out が FileOutputStream のインスタンスの場合。

FileChannel fcin = in.getChannel(), fcout = out.getChannel();
fcout.transferFrom(fcin, 0, fcin.size());

速くなるかどうかは環境によって微妙に違うと思いますが、効率よくやる方法が2つあります。

1. 1バイトづつ読み書きするのではなくて byte[] で1000バイトとかの塊を読んでそのまま塊を書くようにする。(こうすると read, write をする回数が減るので少し速いと思います)。

2. FileInputStream と FileOutputStream のインスタンス双方から getChannel() で java.nio.channels.FileChannel のインスタンスを取り出し、FileOutputStream 側から取り出した FileChannel のインスタンスに対して transferFrom()...続きを読む

QJDialogを閉じた時の処理

 初めまして
 
 JDialogを継承してOutputDialogと言うクラスを作り、モーダルなダイアログを作りました。上の×ボタンで閉じるだけではなく、閉じやすいようにJButtonでも閉じられるようにしたいと思ったのですが、×ボタンと同じ処理をするには何の処理を呼び出したらよいのでしょうか。

 dispose()やsetVisible(false)だと、モーダルなままで消えてしまいましたので、setModal(false)とsetVisible(false)を両方使ったのですが、これで問題ないでしょうか。どなたか教えて下さい。
 

Aベストアンサー

すみません。こちらの環境で確認したところ WindowEvent.WINDOW_CLOSEDではダイアログが閉じずにWindowEvent.WINDOW_CLOSINGの場合だとダイアログが閉じました。WindowEvent.WINDOW_CLOSINGで閉じるかどうか確認していただけないでしょうか?

以下、動作確認したソース

import java.awt.Toolkit;
import java.awt.event.WindowEvent;

public class OutputDialog extends javax.swing.JDialog {

public OutputDialog(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();
}
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
jButton1.setText("jButton1");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});

jPanel1.add(jButton1);
jButton2.setText("jButton2");
jPanel1.add(jButton2);
getContentPane().add(jPanel1, java.awt.BorderLayout.NORTH);
pack();
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
}

public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new OutputDialog(new javax.swing.JFrame(), true).setVisible(true);
}
});
}
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JPanel jPanel1;
}

すみません。こちらの環境で確認したところ WindowEvent.WINDOW_CLOSEDではダイアログが閉じずにWindowEvent.WINDOW_CLOSINGの場合だとダイアログが閉じました。WindowEvent.WINDOW_CLOSINGで閉じるかどうか確認していただけないでしょうか?

以下、動作確認したソース

import java.awt.Toolkit;
import java.awt.event.WindowEvent;

public class OutputDialog extends javax.swing.JDialog {

public OutputDialog(java.awt.Frame parent, boolean modal) {
super(parent, modal);...続きを読む

Qファイルロック後の書き込みについて

ファイルAをロックしファイルBを読み込み
ファイルAに書き込むプログラムを作成しています。
単体起動では問題無く動くのですが
複数起動するとファイルの書き込みが行われなくなってしまいます。
ロックしたプログラム以外はロックエラーになり
ロックについては正常に動いているように見えます。
なぜ書き込みが行われなくなってしまうかご教授いただけますか?

import java.io.* ;
import java.nio.*;
import java.nio.channels.*;

public class CopyFile {
public static void main(String[] args) throws Exception {
try{
FileInputStream fis = null;
FileOutputStream output = null;
FileChannel outChannel = null;
FileLock outFileLock = null;

byte buf[] = new byte[2048];
int len;
int count = 0;

if (args.length != 2) {
System.out.println("使用法: java CopyFile ファイル名1 ファイル名2");
System.exit(0);
} //if
String source= args[0];
String target= args[1];
File sourceFile = new File(source);
File targetFile = new File(target);
fis = new FileInputStream(sourceFile);
output = new FileOutputStream(targetFile);
outChannel = output.getChannel();
outFileLock = outChannel.tryLock();

if (outFileLock == null) {
System.out.println("rock error!!");
System.exit(0);
} else {

while ((len = fis.read(buf)) != -1) {
output.write(buf, 0, len);
count += len;
}
Thread.sleep(5000);
output.flush();
output.close();
fis.close();
}
}catch(Exception e){
System.out.println(e);
}
}
} // Class CopyFile

ファイルAをロックしファイルBを読み込み
ファイルAに書き込むプログラムを作成しています。
単体起動では問題無く動くのですが
複数起動するとファイルの書き込みが行われなくなってしまいます。
ロックしたプログラム以外はロックエラーになり
ロックについては正常に動いているように見えます。
なぜ書き込みが行われなくなってしまうかご教授いただけますか?

import java.io.* ;
import java.nio.*;
import java.nio.channels.*;

public class CopyFile {
public static void main(String[] a...続きを読む

Aベストアンサー

#3です
2つ目のプログラムを起動し、FileOutputStreamのオブジェクトを
生成した時点で新規作成してしまっています(ファイルが空)
その後でロックのチェックをしているので「ロック中」と判断されます。
したがって1番目のプログラム終了時には2番目のプログラムによって
クリアされてしまい、書き込まれていないように見えるようです。
とりあえず原因はコレではないかと思います。
対策は...どうしましょう?(苦笑

Q描画処理が実行されない

while(gameflag==true){
(数値設定)   
repaint();
long start = System.currentTimeMillis();
while(System.currentTimeMillis()<start+1000){
}
}

上記のようにwhileループの中で数値などの設定を行い、描画をし、遅延をしているのですが他の処理はちゃんと実行されるのになぜか描画処理だけが行われません。また、whileループ外でも描画を行っていますがその時点ではきちんと描画されます。描画されない原因はどのようなことが考えられるでしょうか?描画はpaintComponent(Graphics g) メソッドで描画しています。

Aベストアンサー

>描画されない原因はどのようなことが考えられるでしょうか?

Swingの描画はダブルバッファを使っている関係上、描画メソッドを呼び出したときではなく、その後、もっとも早く再描画できるタイミングで表示を更新します。このため、while内で描画を行っている場合には、そのwhileを抜け、処理が終了した頃で表示が更新されるため、while中で行っている描画処理は見えません。(途中の描画は見えず、最終的に描画された状態だけが表示される)

この処理は、別スレッドを使って実行していますか? メインスレッドでは、上のような理由で途中の更新は見えませんから、マルチスレッドで実行し、描画ごとに強制的にrepaintするなどしてみてはいかがでしょう。


人気Q&Aランキング

おすすめ情報