jar内部のファイルは変更できない、させない。
javaプログラムのテキストファイルなどはjavaのIDEで実行した場合、ファイルの中身を書き換えることは可能なのだが、jarを作成しその内部のファイルはセキュリティの問題から書き換えはできない。またこのプログラムを配布する場合、実行ファイル(exeファイル)は当然、プログラムフォルダーに作成される。基本、プログラムファイル内部のデーターの変更はしないことになっている。
次のような場合を想定する。
jarの中にテキストファイルを入れる。このファイルにはcsv形式でデーターが入っている。このデーターをもとにJtableにDefaultTableModelの票を作成する。ユーザーは票のデーターを削除、追加することが可能である。
この場合、票のRowの追加と削除は簡単にできるのだが、jar内部のcsvファイルを書き換えることはできない。このため、次のような解決方法がある。
内部を書き換えたいtxtファイルやメディアファイルはwindowsの場合、ユーザーホームのAppData/Local/フォルダー内部に保管する。jarのリソースからファイルの中身をコピーし、AppDataのユーザーフォルダー内に新たにファイルを作成して、コピーしたデーターを書き込む。
jarリソース内部のデーターファイルをAppData内に新たに作成する。
ユーザーAppDatanフォルダーパスをStringで得たい場合、次のように書く。フォルダーは事前に作成しておく。
String strFolder = System.getProperty("user.home") + "\\AppData\\Local\\UserFolder";
File createFolder = new File(strFolder);
if(createFolder.exists() == false){
createFolder.mkdir();
}
またファイルのパスを作成する。
String strFilePath = strFolder + "\\csv.txt";
次にjarファイル内のtxtファイルを読み込む。これにはgetClass().getResourceAsStream()でinputStreamを得てからBufferedInputStreamクラスを利用してファイルにアクセスする必要がある。次のように書く。この時、フォルダーの分岐は必ず/
を使う。
BufferedInputStream bInput = new BufferedInputStream(getClass().getResourceAsStream("image/csv.txt"));
txtファイルのバッファをすべてコピーする。これはjpegなどの画像ファイルでも同じだ。最後にFileOutputStreamでAppDataのユーザーフォルダーに作成するファイルにバッファーを書き込む。
byte[] read = bInput.readAllBytes();
FileOutputStream outStream = new FileOutputStream(scanf.getPath());
outStream.write(read);
outStream.close();
一連の流れを関数にすると以下のようになる。
String strAppPath = System.getProperty("user.home") + "\\AppData\\Local\\UserFolder";
//フォルダーはFile関数で事前に作成する
String strFilePath = strAppPath + "\\csv.txt";
public int createList(){
File appDataFile = new File(strFilePath); //コピーする先のファイルを作成する。
BufferedInputStream bInput = new BufferedInputStream(getClass().getResourceAsStream("image/csv.txt"));
try {
byte[] read = bInput.readAllBytes();
FileOutputStream outStream = new FileOutputStream(appDataFile.getPath());
outStream.write(read);
outStream.close();
} catch (IOException e) {
// TODO: handle exception
return -1;
}
return 0;
}