◆PROCESSING 逆引きリファレンス
カテゴリー:ファイル操作
ファイル共有(SMB)を利用するには
【概要】
WindowsやLinuxでは、ファイル共有をサポートしています。
WindowsとLinux、あるいはWindows同士のファイル共有には、通常はSambaが利用されます。WindowsではSMB(Server Message Block)ですね。
PROCESSINGでは残念ながら、標準でSMBを利用したファイル共有エリアへのアクセスは行なえません。しかしPROCESSINGにJava用のライブラリを追加する事で、これを実現することが可能となります。
SMBにはSMB1(Samba3.4以前)、SMB2、SMB3と、2019年11月現在3つの大きなバージョンが存在します。
参考URL:@IT様:第7回 ファイル共有プロトコルSMBの概要
Windowsでは長らく互換性維持のために、新しいOSでもSMB1を利用する事が可能でしたが、Windows10では、ついにデフォルト状態でSMB1の利用ができなくなりました。
JavaからSMBを利用するライブラリとして有名なものにjCIFS(Java CIFS Client Library)があります。
古くからある有名なライブラリであるため、今でもネットを検索するとjCIFSのサンプルや事例が多く見つかります。
ところがこのjCIFSは、SMB1のみをサポートしています。公式サイトにも「jCIFS does not support the newer SMB2/3 variants of the SMB protocol」とある通り、SMB2/SMB3はサポートされていません。
つまりファイル共有を提供するホストがWindows10などの場合、デフォルトではjCIFS を使ってファイル共有エリアにアクセスすることができなくなりました。
jCIFSに代わるSMB2/SMB3をサポートするライブラリには
などがあります。※
※ 2019/12現在、smbj はSMB3をサポートしていません。SMB2のみになります。
今回は jCIFSの後継となるjcifs-ngを利用して、ファイル共有エリアにアクセスする方法を紹介したいと思います。
【詳細】
最新のライブラリを入手する
EclipseやIntelliJ Ideaを利用している人は、jcifs-ngのライブラリを Mavn Repository からGradleやMaven経由で入手するのが便利です。
jcifs-ngは、2019年12月現在Version 2.1.3 が公開されています。
標準エディタを利用している人は、jarファイルを自力で探し出すか、git-hubに公開されているソースを元にコンパイルして作成します。
例えばjarファイルがダウンロードできるサイトとしては、jar-download.com 様などがあります。自己責任でダウンロードしてください。
jcifs-ngの動作には以下のライブラリも必要となるため、合わせて入手しておきましょう。
最後の「slf4j-simple」は入手しなくても動作しますが、ライブラリがない状態で実行するとコンソール領域に警告MSGが表示されてしまいます。
PROCESSINGで利用できるようにする
まずPROCESSINGの標準エディタから「新規プロジェクト」を作成し、空で良いので一度保存します。
なお保存前に「ファイル→設定」で、スケッチブックの場所に「わかりやすいパス」が指定されている事を確認してください。
上記例なら、スケッチを保存すると「D:\processing-3.5.3\src」に「sketch_191123a」などのフォルダが作成され、空のプログラムソースファイルができあがります。
このフォルダ(D:\processing-3.5.3\src\sketch_191123a)配下に、code フォルダを作成してください。
続いて、上記でダウンロードした jarファイルを、code フォルダの中に複写します。
これでライブラリの準備は完了です。標準エディタを開いている人は、一度PROCESSINGを終了して、標準エディタを再起動してください。
ファイル共有サーバを準備する
ファイル共有を行うわけですから、共有エリアを提供してくれるサーバが必要ですね。
以下の解説では、Windows10(MSLABO-PC)をファイル共有サーバとし、その共有エリアが share という名前で公開されている前提とします。またshareにはgirl.jpg、boy.pngという画像ファイルと、SubFolderという名前のフォルダがあるものとします。
(画像URL:illust-AC 様:わことさん、猫島商会さん)
ファイル共有エリアへのアクセスには
- 接続先ホストのアドレス※
- ユーザ名
- パスワード
が必要となります。事前に用意をしておいてください。(※IPアドレス、またはドメイン名)
jcifs-ngでは、匿名(anonymous)にてファイル共有エリアにアクセスする事も可能なようですが、手元の環境では何故かエラーとなり成功しませんでした。
よって、ファイル共有サーバを自分で用意する場合には、該当OS上に、ファイル共有を許可するユーザとパスワードの準備もしておく必要があります。
接続情報を準備する
ファイル共有エリアを利用するには、認証情報を作成し、該当サーバの共有エリアに接続する必要があります。
jcifs-ngでは、サーバに接続するために
- 認証情報(NtlmPasswordAuthenticator)
- 基本コンテキスト(BaseContext)
- 接続コンテキスト(CIFSContext)
の各情報を作成します。
認証情報を作成する
userName:ユーザ名
passWord:パスワード
ユーザ名とパスワードを指定して認証情報を作成します。パスワードなしのユーザは許可されませんので、注意してください。
1 2 3 4 5 |
final String userName="userName"; final String passWord = "passWord"; NtlmPasswordAuthenticator authenticator = new NtlmPasswordAuthenticator(userName, passWord); |
こんな感じで利用します。
基本コンテキストを作成する
基本コンテキストを作成するBaseContext bc = new BaseContext(Configuration config);
bc:基本コンテキスト
config:接続パラメータ
共有エリアに接続するための基本となるコンテキスト情報を作成します。作成するためには、接続用のパラメータを定義したConfigurationクラスを実装したインスタンス(config)が必要となります。
jcifs-ngで用いるConfigurationクラスを実装したクラスには、PropertyConfigurationクラスがあります。
.
プロパティを作成するPropertyConfiguration pc = new PropertyConfiguration(Properties p);
pc:Configurationクラスを実装したクラス
p:Javaのプロパティクラス
PropertyConfigurationのインスタンスを作成するためには、Javaのプロパティクラスを利用します。
あらかじめJavaのPropertyクラスに接続に必要となるパラメータをセットしておき、PropertyConfigurationクラスを作成し、出来上がったPropertyConfigurationインスタンスをBaseContextの生成に利用します。
1 2 3 4 5 6 7 8 9 10 11 |
//プロパティを準備する Properties prop = new Properties(); prop.setProperty("jcifs.smb.client.minVersion", "SMB202"); prop.setProperty("jcifs.smb.client.maxVersion", "SMB311"); try { //基本コンテキストを作成する BaseContext baseContext = new BaseContext(new PropertyConfiguration(prop)); } catch (CIFSException e) { e.printStackTrace(); } |
こんな感じです。
jcifs-ng で利用する代表的なプロパティには、以下のようなものがあります。
プロパティ | 説明 | |
---|---|---|
1 | jcifs.smb.client.minVersion | 利用するSMBの最小バージョン |
2 | jcifs.smb.client.maxVersion | 利用するSMBの最大バージョン |
3 | jcifs.smb.client.connTimeout | 接続タイムアウト値(ミリセカンド:初期値35秒) |
4 | jcifs.smb.client.responseTimeout | SMB応答タイムアウト値(ミリセカンド:初期値30秒) |
5 | jcifs.smb.client.enableSMB2 | SMB2/3を利用するか否か。初期値はtrue |
6 | jcifs.smb.client.disableSMB1 | SMB1を利用するか否か。初期値はfalse |
この他にも多数、利用可能なプロパティがあります。詳しくは公式ドキュメントを参照してください。
利用するSMBのバージョンには、以下の範囲の文字列から指定を行うことが可能です。
指定可能な値 | 説明 | |
---|---|---|
1 | SMB1 | SMB1を利用する |
2 | SMB202 | SMB 2.02を利用する(Windows Vista以降) |
3 | SMB210 | SMB 2.1を利用する(Windows 7/Server 2008R2) |
4 | SMB300 | SMB 3.0を利用する(Windows 8/Server 2012) |
5 | SMB302 | SMB 3.0.2を利用する(Windows 8.1/Server 2012R2) |
6 | SMB311 | SMB 3.1.1を利用する(Windows 10/Server 2016) |
接続コンテキストを作成する
接続コンテキストを作成するCIFSContext cifsCon = baseContext.withCredentials(NtlmPasswordAuthenticator auth);
auth:認証情報
cifsCon:作成された接続用のコンテキスト
上記で作成した基本コンテキストがもつメソッドに認証情報を与えることで、接続用のコンテキストを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//プロパティを準備する Properties prop = new Properties(); prop.setProperty("jcifs.smb.client.minVersion", "SMB202"); prop.setProperty("jcifs.smb.client.maxVersion", "SMB311"); try { //認証情報を作成する NtlmPasswordAuthenticator authenticator = new NtlmPasswordAuthenticator(userName, passWord); //基本コンテキストを作成する BaseContext baseContext = new BaseContext(new PropertyConfiguration(prop)); //接続コンテキストを作成する CIFSContext cifsContext = baseContext.withCredentials(authenticator); } catch (CIFSException e) { e.printStackTrace(); } |
一連の流れをコーディングすると、こんな感じになります。
接続する
ファイル共有エリアに接続するには、上記で作成した接続用のコンテキストと接続先情報を用いて、SmbFileクラスのインスタンスを作成する事で実現します。
接続するSmbFile sf = SmbFile(String url, CIFSContext ct);
sf:SmbFile インスタンス
url:接続先(ファイル共有サーバ)情報
ct:接続用のコンテキスト
接続に失敗するとMalformedURLException例外が発生します。
接続先となるサーバーの代表的な指定方法は、以下の書式になります。
¥記号はバックスラッシュ(/)に置き換えてください。
今回の例であれば、公開サーバ名はMSLABO-PC、共有フォルダ名はShareになります。
この書式以外にも様々な書き方が可能ですので、詳しくは公式ドキュメントを参照してください。
接続できたらSmbFile クラスのインスタンスを用いて、ファイル共有エリアの操作を行います。
操作が終わったあとは、SmbFile クラスのclose()メソッドで資源を開放しておきましょう。
.
sf:SmbFile インスタンス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
final String remoteFile = "smb:\\\\MSLABO-PC\\Share\\"; SmbFile smbFile = null; public void setup() { //接続用情報を作成する ……… //接続する try { String url = remoteFile.replace("\\", "/"); smbFile = new SmbFile(url, cifsContext); //なにかの処理 } catch( MalformedURLException e){ e.printStackTrace(); return ; } finally { //接続を解放 smbFile.close(); } } |
接続処理部分だけを書き出すと、上記のようになります。
ファイル一覧を取得する
それでは共有エリアにあるファイル一覧を表示してみましょう。
接続した共有エリアにあるファイル一覧は、SmbFileクラスのlistFiles()メソッドで取得します。
listFiles()には、一覧化したいファイルの条件を指定可能です。
ファイル一覧を取得SmbFile[] list = sf.listFiles(String wildcard);
sf:SmbFile インスタンス
list :得られたファイル一覧
wildcard:収集条件(例:”*.png”なら拡張子がpngのものだけを集める)
得られたファイル一覧はSmbFileの配列で戻されます。特に条件を指定しない場合、一覧はファイル・フォルダに関係なく集められます。
収集された情報がファイルなのかフォルダなのかを識別するためには、wildcardで適切な条件を指定するか、収集された情報から判定する必要があるので注意してください。
以下は共有エリアに接続した後で、ファイル一覧を取得する例です。
1 2 3 4 5 6 7 8 9 10 11 12 |
//ファイル一覧を取得 SmbFile[] fileList = smbFile.listFiles("*"); for( SmbFile file : fileList ){ println( "--------------------------" ); println( "ファイル名 = [" + file.getName() + "]"); println( "読めるか?:"+ file.canRead() ); println( "書けるか?:"+ file.canWrite() ); println( "ファイルか?:"+ file.isFile() ); println( "フォルダか?:"+ file.isDirectory() ); println( "隠し項目か?:"+ file.isHidden() ); file.close(); } |
<出力例>
上記サンプルでは、SmbFileクラスが持つ各メソッドで集めたファイル一覧が読み書きできるか、ファイルなのかフォルダなのかを調べています。
本例ではワイルドカードを “*” にしているので、ファイルとフォルダの両方が取得されていますが、ワイルドカードを “*.jpg” 等とすれは拡張子に jpg を持つものしか一覧化されません。
プログラムの全体像は、下記サンプルを参照してください。
ファイルをローカルPCに複写する
それでは共有エリアにあるファイルを、手元のPCに複写してみましょう。
接続した共有エリアにあるファイルを読み取るには、SmbFileクラスが持つopenInputStream()メソッドで、読み取り用のストリームをOPENします。
リモート側(ファイル共有エリア)にあるファイルは、SmbFileクラスが持つメソッドでアクセスするのが基本となるので注意してください。
ファイルを読み取りOPENするSmbFileInputStream is = sf.openInputStream();
sf:SmbFile インスタンス
is:読み取り専用ストリーム
得られた読み取り用ストリーム(SmbFileInputStream)はJavaのInputStreamを継承したクラスであるため、JavaのInputStreamと同じように利用できます。
OPENできない場合は、SmbException例外が発生します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
fileList = smbFile.listFiles("*.jpg"); String outFile = "d:\\temp\\"; //ローカルの複写先フォルダ for( SmbFile file : fileList ){ //フォルダは無視 if( file.isDirectory()) continue; //ファイルならローカルにCOPYする FileOutputStream fileOut = null; try { //共有エリアのファイルを読み取りOPENする println( file.getName() + " copy start to " + outFile + file.getName() ); SmbFileInputStream is = file.openInputStream(); //ローカルエリアのファイルを書き込みOPENする fileOut = new FileOutputStream(outFile + file.getName()); //読み取り用配列を宣言 byte[] buf = new byte[1024]; int len; // ファイルの終わりまで読み込む while ((len = is.read(buf)) != -1) { //ファイルに内容を書き込む fileOut.write(buf); } fileOut.flush(); fileOut.close(); is.close(); file.close(); println( file.getName() + " copy end" ); } catch( FileNotFoundException e){ e.printStackTrace(); } catch( SmbException e){ e.printStackTrace(); } catch( IOException e){ e.printStackTrace(); } } |
上記は共有エリアに接続した後で、共有エリアにある jpg ファイルをローカルPCのD\\tempフォルダへ複写する例です。
ファイルを共有エリアに複写する
それでは先ほどの例とは逆で、手元のPCにあるファイルを共有エリアに複写してみましょう。
接続した共有エリアにファイルを書き込むには、SmbFileクラスが持つopenOutputStream()メソッドで、書き込み用のストリームをOPENします。
ファイルを書き込みOPENするSmbFileOutputStream os = sf.openOutputStream();
os:書き込み用ストリーム
得られた書き込み用ストリーム(SmbFileOutputStream)はJavaのOutputStreamを継承したクラスであるため、JavaのOutputStreamと同じように利用できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
String readPath = "d:\\temp\\boy.png"; //ローカルの元ファイル //読み書き用ストリームを用意する BufferedInputStream bis = null; SmbFileOutputStream os = smbFile.openOutputStream(); try { println( readPath + "を" + smbFile.getCanonicalUncPath() + "に複写します"); //元ファイルをOPENする bis = new BufferedInputStream(new FileInputStream(readPath)); //順次読みだして共有エリアに書き込む byte[] bytes = new byte[1024]; int len = 0; while ((len = bis.read(bytes, 0, bytes.length)) != -1) { //書き込む os.write( bytes ); } os.flush(); os.close(); println( "複写しました"); } catch( FileNotFoundException e){ e.printStackTrace(); } catch( IOException e){ e.printStackTrace(); } finally { if( bis != null ){ try{ bis.close(); } catch( IOException e){ e.printStackTrace(); } } } |
上記は共有エリアに接続した後で、ローカルPCにある boy.pngファイルを共有エリアにhoge.pngとして複写する例です。
共有エリアには
1 |
final String remoteFile = "smb:\\\\MSLABO-PC\\Share\\hoge.png"; |
のように、書き込むファイルへのUNCパスを指定して接続しているものとします。
このファイル(hoge.png)は、接続先に存在する必要はありません。なければ生成されます。
ただし上記処理ではファイルの存在を確認せずに書き込んでいるため、すでにあるファイルへ書き込みを行った場合は上書き更新される事に注意してください。
共有エリアのファイルを削除する
次に、共有エリアにあるファイルを削除する例を紹介します。
共有エリアにあるファイルを削除するには、対象ファイルに対してSmbFileクラスが持つdelete()メソッドを利用します。
ファイルを削除するvoid sf.delete();
sf:SmbFile インスタンス
1 2 3 4 5 6 7 8 |
try { println( smbFile.getCanonicalUncPath() + "を削除します"); //削除する smbFile.delete(); println( "削除しました"); } catch( IOException e){ e.printStackTrace(); } |
上記は共有エリアに接続した後で、共有エリアにあるファイルを削除する例です。
共有エリアにあるファイルには
1 |
final String remoteFile = "smb:\\\\MSLABO-PC\\Share\\boy.png"; |
のように、削除対象ファイルへのUNCパスを指定して接続しているものとします。
対象となるファイル(本例ではboy.png)が存在しない場合は、delete()時に例外エラーとなるので注意してください。
【関連記事】
- なし
サンプルプログラム
ファイル一覧を取得する例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
/** * PROCESSING 3.0 Samba List Sample * @auther MSLABO * @version 2019/12 1.0 **/ import jcifs.CIFSContext; import jcifs.CIFSException; import jcifs.config.PropertyConfiguration; import jcifs.context.BaseContext; import jcifs.smb.*; import java.net.MalformedURLException; import java.util.Properties; final String userName="username"; final String passWord = "password"; final String remoteFile = "smb:\\\\MSLABO-PC\\share\\"; SmbFile smbFile = null; /** * 接続用プロパティをセットする * @param p プロパティ */ private void setProperties(Properties p){ p.setProperty("jcifs.smb.client.minVersion", "SMB202"); p.setProperty("jcifs.smb.client.maxVersion", "SMB311"); } /** * 共有エリアに接続する * @param auth 認証情報 * @param uncPath 接続先のUNCパス * @return 共有ファイル情報 */ private SmbFile connect( CIFSContext auth, String uncPath ) { try { String url = uncPath.replace("\\", "/"); return new SmbFile(url, auth); } catch( MalformedURLException e){ e.printStackTrace(); return null; } } void setup(){ //接続用プロパティを作成する Properties prop = new Properties(); setProperties(prop); try { //接続情報を作成する BaseContext baseContext = new BaseContext(new PropertyConfiguration(prop)); NtlmPasswordAuthenticator authenticator = new NtlmPasswordAuthenticator(userName, passWord); CIFSContext cifsContext = baseContext.withCredentials(authenticator); //接続する SmbFile smbFile = connect(cifsContext, remoteFile); if(smbFile == null) return; //ファイル一覧を取得する SmbFile[] fileList = smbFile.listFiles("*.jpg"); for( SmbFile file : fileList ){ //フォルダは無視 if( file.isDirectory()) continue; println( file.getName() ); file.close(); } } catch (CIFSException e) { e.printStackTrace(); } finally { if( smbFile != null ){ smbFile.close(); } } } void draw(){ } |
MSLABO-PCという名前のファイル共有サーバにある share 領域に接続し、その中にあるjpgという拡張子を持つファイルの一覧を取得する例です。
今回の例であれば、girl.jpg がヒットします。
<出力サンプル>
共有エリアのファイルを取得する例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
/** * PROCESSING 3.0 Samba RL Copy Sample * @auther MSLABO * @version 2019/12 1.0 **/ import jcifs.CIFSContext; import jcifs.CIFSException; import jcifs.config.PropertyConfiguration; import jcifs.context.BaseContext; import jcifs.smb.*; import java.net.MalformedURLException; import java.util.Properties; import java.io.*; final String userName="username"; final String passWord = "password"; final String remoteFile = "smb:\\\\MSLABO-PC\\share\\"; SmbFile smbFile = null; /** * 接続用プロパティをセットする * @param p プロパティ */ private void setProperties(Properties p){ p.setProperty("jcifs.smb.client.minVersion", "SMB202"); p.setProperty("jcifs.smb.client.maxVersion", "SMB311"); } /** * 共有エリアに接続する * @param auth 認証情報 * @param uncPath 接続先のUNCパス * @return 共有ファイル情報 */ private SmbFile connect( CIFSContext auth, String uncPath ) { try { String url = uncPath.replace("\\", "/"); return new SmbFile(url, auth); } catch( MalformedURLException e){ e.printStackTrace(); return null; } } void setup(){ //接続用プロパティを作成する Properties prop = new Properties(); setProperties(prop); try { //接続情報を作成する BaseContext baseContext = new BaseContext(new PropertyConfiguration(prop)); NtlmPasswordAuthenticator authenticator = new NtlmPasswordAuthenticator(userName, passWord); CIFSContext cifsContext = baseContext.withCredentials(authenticator); //接続する SmbFile smbFile = connect(cifsContext, remoteFile); if(smbFile == null) return; //ファイル一覧を取得する SmbFile[] fileList = smbFile.listFiles("*"); String outFile = "d:\\temp\\"; //ローカルの複写先フォルダ //複写する(共有エリア->ローカル) for( SmbFile file : fileList ){ //フォルダは無視 if( file.isDirectory()) continue; //ファイルならローカルにCOPYする FileOutputStream fileOut = null; try { println( file.getCanonicalUncPath() + " -> " + outFile + file.getName() ); //共有エリアのファイルを読み取りOPENする SmbFileInputStream is = file.openInputStream(); //ローカルエリアのファイルを書き込みOPENする fileOut = new FileOutputStream(outFile + file.getName()); //読み取り用配列を宣言 byte[] buf = new byte[1024]; int len; // ファイルの終わりまで読み込む while ((len = is.read(buf)) != -1) { //ファイルに内容を書き込む fileOut.write(buf); } fileOut.flush(); fileOut.close(); is.close(); file.close(); println( file.getName() + " copy end" ); } catch( FileNotFoundException e){ e.printStackTrace(); } catch( SmbException e){ e.printStackTrace(); } catch( IOException e){ e.printStackTrace(); } } } catch (CIFSException e) { e.printStackTrace(); } finally { if( smbFile != null ){ smbFile.close(); } } } void draw(){ } |
共有エリアにあるファイルをローカルPCに複写します。
今回の例であれば、boy.png と girl.jpg がDドライブのtempフォルダにコピーされます。
<出力サンプル>
共有エリアへファイルを書き込む例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
/** * PROCESSING 3.0 Samba LR Copy Sample * @auther MSLABO * @version 2019/12 1.0 **/ import jcifs.CIFSContext; import jcifs.CIFSException; import jcifs.config.PropertyConfiguration; import jcifs.context.BaseContext; import jcifs.smb.*; import java.net.MalformedURLException; import java.util.Properties; import java.io.*; final String userName="username"; final String passWord = "password"; final String remoteFile = "smb:\\\\MSLABO-PC\\share\\hoge.png"; SmbFile smbFile = null; /** * 接続用プロパティをセットする * @param p プロパティ */ private void setProperties(Properties p){ p.setProperty("jcifs.smb.client.minVersion", "SMB202"); p.setProperty("jcifs.smb.client.maxVersion", "SMB311"); } /** * 共有エリアに接続する * @param auth 認証情報 * @param uncPath 接続先のUNCパス * @return 共有ファイル情報 */ private SmbFile connect( CIFSContext auth, String uncPath ) { try { String url = uncPath.replace("\\", "/"); return new SmbFile(url, auth); } catch( MalformedURLException e){ e.printStackTrace(); return null; } } void setup(){ //接続用プロパティを作成する Properties prop = new Properties(); setProperties(prop); try { //接続情報を作成する BaseContext baseContext = new BaseContext(new PropertyConfiguration(prop)); NtlmPasswordAuthenticator authenticator = new NtlmPasswordAuthenticator(userName, passWord); CIFSContext cifsContext = baseContext.withCredentials(authenticator); //接続する SmbFile smbFile = connect(cifsContext, remoteFile); if(smbFile == null) return; String readPath = "d:\\temp\\boy.png"; //ローカルの元ファイル //読み書き用ストリームを用意する BufferedInputStream bis = null; SmbFileOutputStream os = smbFile.openOutputStream(); try { println( readPath + "を" + smbFile.getCanonicalUncPath() + "に複写します"); //元ファイルをOPENする bis = new BufferedInputStream(new FileInputStream(readPath)); //順次読みだして共有エリアに書き込む byte[] bytes = new byte[1024]; int len = 0; while ((len = bis.read(bytes, 0, bytes.length)) != -1) { //書き込む os.write( bytes ); } os.flush(); os.close(); println( "複写しました"); } catch( FileNotFoundException e){ e.printStackTrace(); } catch( IOException e){ e.printStackTrace(); } finally { if( bis != null ){ try{ bis.close(); } catch( IOException e){ e.printStackTrace(); } } } } catch (CIFSException e) { e.printStackTrace(); } finally { if( smbFile != null ){ smbFile.close(); } } } void draw(){ } |
ローカルエリアにある boy.png を共有エリアにhoge.pngとして複写します。
<出力サンプル>
共有エリアのファイルを削除する例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
/** * PROCESSING 3.0 Samba FileDelete Sample * @auther MSLABO * @version 2019/12 1.0 **/ import jcifs.CIFSContext; import jcifs.CIFSException; import jcifs.config.PropertyConfiguration; import jcifs.context.BaseContext; import jcifs.smb.*; import java.net.MalformedURLException; import java.util.Properties; import java.io.*; final String userName="username"; final String passWord = "password"; final String remoteFile = "smb:\\\\MSLABO-PC\\share\\"; SmbFile smbFile = null; /** * 接続用プロパティをセットする * @param p プロパティ */ private void setProperties(Properties p){ p.setProperty("jcifs.smb.client.minVersion", "SMB202"); p.setProperty("jcifs.smb.client.maxVersion", "SMB311"); } /** * 共有エリアに接続する * @param auth 認証情報 * @param uncPath 接続先のUNCパス * @return 共有ファイル情報 */ private SmbFile connect( CIFSContext auth, String uncPath ) { try { String url = uncPath.replace("\\", "/"); return new SmbFile(url, auth); } catch( MalformedURLException e){ e.printStackTrace(); return null; } } void setup(){ //接続用プロパティを作成する Properties prop = new Properties(); setProperties(prop); try { //接続情報を作成する BaseContext baseContext = new BaseContext(new PropertyConfiguration(prop)); NtlmPasswordAuthenticator authenticator = new NtlmPasswordAuthenticator(userName, passWord); CIFSContext cifsContext = baseContext.withCredentials(authenticator); //接続する SmbFile smbFile = connect(cifsContext, remoteFile); if(smbFile == null) return; //ファイル一覧を取得する SmbFile[] fileList = smbFile.listFiles("*"); //ファイルを削除する for( SmbFile file : fileList ) { //フォルダは無視 if (file.isDirectory()) continue; println(file.getCanonicalUncPath() + "を削除します"); //削除する file.delete(); println("削除しました"); file.close(); } } catch( SmbException e){ e.printStackTrace(); } catch( IOException e){ e.printStackTrace(); } finally { if( smbFile != null ){ smbFile.close(); } } } void draw(){ } |
共有エリアにあるファイルを削除します。本例では boy.pngとgirl.jpgが削除されます。
<出力サンプル>
本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。