あ、これってべんりだなあって思ったコーディングのメモ。
rm -rf `find ./ -type d -name classes`
import java.io.BufferedOutputStream; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; /******************************************************************************* * Copyright (c) 2007 Masatomi KINO. All rights reserved. * $Id$ ******************************************************************************/ public class Utils { public static byte[] file2Byte(String file) throws IOException { InputStream in = null; byte[] pix = null; try { in = new FileInputStream(file); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int j; while ((j = in.read(b)) != -1) { baos.write(b, 0, j); } pix = baos.toByteArray(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } return pix; } public static void byte2File(byte[] b, String outputFile) throws IOException { BufferedOutputStream stream = null; try { File file = new File(outputFile); FileOutputStream fstream = new FileOutputStream(file); stream = new BufferedOutputStream(fstream); stream.write(b); } finally { if (stream != null) { try { stream.close(); } catch (IOException e1) { e1.printStackTrace(); } } } } }
System.out.println(Integer.toHexString(15)); System.out.println(Integer.toBinaryString(15));
実行結果は以下の通り。
f 1111
Base64とはE-mailなどバイナリデータを使用できない環境で、バイナリデータを扱うためのエンコード方式です*1。バイナリデータをテキストデータに可逆変換します。
Commons Codecを用いれば、バイナリデータを簡単にBase64エンコード可能です。
public class Base64Main { public static String encode(String input) { byte[] bs = Base64.encodeBase64(input.getBytes(), false); // booleanはある単位で改行を入れるかどうか return new String(bs); } public static void main(String[] args) { String string = encode("kino"); System.out.println(string); } }
実行結果は以下の通り
a2lubw==
簡単ですね。引数にbyte[]を取るので、バイナリファイルからbyte[]を作成し、メソッドに渡してあげればバイナリファイルも簡単にエンコード可能なわけです*2。
ちなみにこのCodecライブラリは下に出てくる byte[] -> HexString?な変換をするメソッドなどもあります。
new String(Hex.encodeHex(b));
とすればOKです。
あ、よく見たらSHA-1でハッシュするメソッドもありました。
System.out.println(DigestUtils.shaHex("kino".getBytes()));
でしたと同じ結果を得ることができます。実行結果は以下の通り。
c108a2616c020deeb71df83906f039e3dfcc6752
おなじですね。
SHA-1はパスワードのハッシュ化などに使われるアルゴリズムです*3
public static String encrypt(String input) { try { MessageDigest md = MessageDigest.getInstance("SHA1"); md.update(input.getBytes("MS932")); return toHexString(md.digest()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; }
private static String toHexString(byte[] b) { StringBuffer hexString = new StringBuffer(); String plainText=null; for (int i = 0; i < b.length; i++) { plainText = Integer.toHexString(0xFF & b[i]); if (plainText.length() < 2) { plainText = "0" + plainText; } hexString.append(plainText); } return new String(hexString); }
public static void main(String[] args) { String string = encrypt("kino"); System.out.println(string); }
実行結果は以下の通り。
c108a2616c020deeb71df83906f039e3dfcc6752
SHA1でハッシュ化できました。MessageDigest?.getInstance("SHA1");の「SHA1」を「MD5」にすればMD5でハッシュ化できます。
thlocal.set( new LegacySystemImpl2()); thlocal.set( new LegacySystemImpl()); LegacySystem impl = (LegacySystem) thlocal.get();
などと同じ型のクラスをセットした場合、どうも上書きになるっぽい。ソースを調べた分けじゃないけど。。
http://www.hyuki.com/dp/dpinfo_ThreadSpecificStorage.html#i1
Eclipseのヒープサイズと、タスクマネージャのjavawのメモリ使用量の関係。Eclipseのヒープが
1024M中の500M
とかなってる場合、1024Mの方がタスクマネージャ上に表示される。だから実際どれだけjavaプロセスがメモリを使用しているかはOSからはわからないみたいですね。
CVSのトランク(メインっていう?)とブランチをマスターしたくちょっと触ってみました。
まずはバージョンとしてタグ付け。タグ名はたとえば
V20061026_01
とする。次にブランチの作成。チーム >> ブランチ より作成。ブランチ名はたとえば
V20061026_01_BRANCH
とする。そのとき、ブランチをマージするための開始点のタグも併せて登録される。これは自動的に
Root_V20061026_01_BRANCH
というタグ名になる。メインのモジュールにブランチをマージするには、開始点ってのが重要みたいだ。
ここまででCVSには上の3つのタグ
V20061026_01 メイン側 V20061026_01_BRANCH ブランチ側 Root_V20061026_01_BRANCH メイン側
ができる。
Eclipseプロジェクトに、メインとブランチ両方落としておく。ブランチの方はプロジェクト名を_branchとかつけとく。
Eclipseで各プロジェクトでソースを修正してコミットする。
メイン側はバージョンは 1.1 -> 1.2 ブランチ側はバージョンは 1.1 -> 1.1.2.1
となるみたい。
さあ、ブランチからメインへマージします。メインのプロジェクトで、チーム >> マージを選択し
マージされるバージョン(終了タグ) をブランチのバージョン i.e. V20061026_01_BRANCH 共通基本バージョン(開始タグ) をさっきの開始バージョン i.e. Root_V20061026_01_BRANCH
と選択すると、左がメイン、右がブランチのソース比較画面が現れます。適宜Updateすればブランチのソースがメインに取り込まれます。後はメインにコミットすれば、ブランチ分のマージは完了です。
※これはローカルコピーに、開始タグと終了タグの差分を取り出すって事かな?実際ブランチ側でマージしようとしたら、V20061026_01_BRANCH とV20061026_01_BRANCH には差分がないっていう当たり前の表示になってしまった。
new Throwable().getStackTrace()[0].getMethodName();
何故これでメソッド名が取れるんだろう。。。でもうまくいきますねー
逆に、byte[]をファイルに書き出す方法
public static void write(byte[] b) { BufferedOutputStream stream = null; try { File file = new File("after.bin"); FileOutputStream fstream = new FileOutputStream(file); stream = new BufferedOutputStream(fstream); stream.write(b); } catch (IOException e) { e.printStackTrace(); } finally { if (stream != null) { try { stream.close(); } catch (IOException e1) { e1.printStackTrace(); } } } }
Webサービスでバイナリをアップするときなどは、byte[]で渡すみたいです。
public byte[] createBin() { InputStream in = null; byte[] pix = null; try { in = new FileInputStream("before.bin"); <-バイナリファイル ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int j; while ((j = in.read(b)) != -1) { baos.write(b, 0, j); } pix = baos.toByteArray(); } catch (IOException e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } return pix; }
Apache Axisを使ったWEBサービスのProxyクライアントで、HTTPのプロキシー(ややこしい)を越える方法を探していました。
いやあEclipseでソースにブレークポイントつけまくって、探したー。。。。どうやら、
org.apache.axis.components.net.DefaultHTTPTransportClientProperties
てクラスが、なにやらプロパティをセットしていて、そこがAxisの環境設定値になってる模様。そしてこのクラスは、org.apache.axis.AxisProperties?というjava.util.Properties みたいなのを使っている。ソースを見ると、httpプロキシを越えるためのキー値は
AxisProperties.setProperty("http.proxyHost", "proxyのサーバ名"); AxisProperties.setProperty("http.proxyPort", "proxyのポート番号"); AxisProperties.setProperty("http.proxyUser", "xxxx"); AxisProperties.setProperty("http.proxyPassword", "xxxx");
越えた。。キター。。。
java -cp /opt/hsqldb/hsqldb.jar org.hsqldb.Server -database /tmp/bd -port 9001 -system_exit=true
java -cp lib/hsqldb.jar org.hsqldb.util.DatabaseManager
JavaのTIPではないけど、J2EE開発中によく使うので。ブラウザのURLに
javascript:document.cookie;
と入力すると、クライアントのCookie(今開いているサイトに対するもののみ)を参照できます。
Jakarta Commons LangはJavaのライブラリだけでは足りないようなユーティリティ的な機能を提供するクラスライブラリです。たとえば、こんな感じで使うことができます。
public String toString() { return new ToStringBuilder(this) .append("id", getId()) .append("title",getTitle()) .toString(); }とかで
nu.mine.kino.rss.hibernate.Rss@33441dfb[id=10,title=hoge]と出力できたり、
public boolean equals(Object other) { if (!(other instanceof Rss)){ return false; } Rss castOther = (Rss) other; return new EqualsBuilder() .append(this.getId(), castOther.getId()) .isEquals(); }とかで、getIdが同じならtrue、なんてことができたりします。ちなみにappendはどんどん後ろに追加することができます。これは便利!!
設定ファイルとかの場所がフィールドに定数で埋め込まれていて、単体テストのときだけそのパスを変えたいなあなんてときがあります。最近はDIとかで変えれるようにするのがはやってますが、DIコンテナなども使ってないときなどはどうすればよいでしょうか。
例としてテスト対象クラスがHogeだとして
public class Hoge{ private String path ="hoge/hogehoge.properties"; ..... public void exe(){ new File(path).....; } }
なんてのがあるとき、どうすればよいかってことです。
この場合、まずはソースを変更して単体テストしやすくします。そのソースの変更はEclipseなどを用いて、きっちりやる、と。やる手順は
具体的には上のクラスは以下のように変更します。
public class Hoge{ private String path ="hoge/hogehoge.properties"; ..... public void exe(){ new File(getPath()).....; } String getPath(){ return path; } }
public class HogeTest{ private Hoge hoge; ..... public void testExe(){ hoge=new Hoge(){ String getPath(){ return "新しいパス"; } }; hoge.exe();....... } }こうするとパスを変更することができます。気になるのは
ってところですね。。ソースの変更に関してはEclipseなどで論理的に安全に行うことはできますが。手順は、
変数を参照している箇所(new File(path)の"path")を選択して、リファクタリング >> フィールドのカプセル化
定数がフィールドにすらいない場合は、上の前にさらにこれをやる
変数を選択して、 リファクタリング >> ローカル変数を フィールドに変換
MessageFormat?を使うと、{0}のようなプレースホルダを使うことができます。
SimpleDateFormat yyyy = new SimpleDateFormat("yyyy"); SimpleDateFormat MM = new SimpleDateFormat("MM"); SimpleDateFormat dd = new SimpleDateFormat("dd"); Date selectedDate = new Date(); String year = yyyy.format(selectedDate); String month = MM.format(selectedDate); String date = dd.format(selectedDate); Object[] dateArgs = { year, month, date }; MessageFormat form = new MessageFormat("{0}年{1}月{2}日"); <-プレースホルダ System.out.println(form.format(dateArgs));
実行結果は
2005年03月18日
例外のインスタンスをexとして
StringWriter stringWriter = new StringWriter(); ex.printStackTrace(new PrintWriter(stringWriter)); String message = stringWriter.getBuffer().toString();
${WORKSPACE}\.metadata\.plugins\com.ibm.wtp.server.core\configs
-Dhttp.proxyHost=[プロクシサーバ名] -Dhttp.proxyPort=[ポート番号] -Dhttp.proxyUser=[UserID] -Dhttp.proxyPassword=[password]
たとえばインスタンス名instance のフィールド(Stringで変数名aField)にアクセスするには
Class clazz = instance.getClass(); Field field = clazz.getDeclaredField("aField"); field.setAccessible(true); String answer = (String)field.get(instance));
で取得できる。ここが参考になりました。
たとえば
<%@ page contentType=text/html; charset=EUC-JP" pageEncoding="Shift_JIS" %>
とした場合、pageEncodingがソースコードの文字コード、contentTypeで指定できるのが出力文字コードです*4。この場合はソースをShift_JISで書いて、EUC-JPで出力するってことですね。
requestからReaderを取得して、そこから文字を取得すればよいわけですね。
BufferedReader reader = request.getReader(); StringBuffer buffer = new StringBuffer(); String line = null; while ((line = reader.readLine()) != null) { buffer.append(URLDecoder.decode(line)); buffer.append("\n"); } String reqMsg = new String(buffer);
ByteArrayOutputStream out = new ByteArrayOutputStream(); try { TransformerFactory tfactory = TransformerFactory.newInstance(); Transformer transformer = tfactory.newTransformer(); transformer.setOutputProperty("encoding", encoding); transformer.transform(new DOMSource(document), new StreamResult(out)); } catch (TransformerConfigurationException e) { logger_.error(e); } catch (TransformerException e) { logger_.error(e); } return out.toString();
例外処理はとりあえずおいといて
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); StringReader stringReader = new StringReader(str); <- str: xmlの文字列 InputSource inputSource = new InputSource(stringReader); return builder.parse(inputSource); <- Document
InputStream in = .....; ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int j; while ((j = in.read(b)) != -1) baos.write(b, 0, j); byte[] pix = baos.toByteArray(); write("hoge.dat", pix); private void write(String filename, byte[] b) { BufferedOutputStream stream = null; try { File file = new File(DictionariesPlugin.getDefault() .getStateLocation().toFile(), filename); FileOutputStream fstream = new FileOutputStream(file); stream = new BufferedOutputStream(fstream); stream.write(b); } catch (IOException e) { e.printStackTrace(); } finally { if (stream != null) { try { stream.close(); } catch (IOException e1) { e1.printStackTrace(); } } } }
public boolean write(String log) { BufferedWriter writer = null; try { //第二引数がtrueなら追記、falseなら上書き。 writer = new BufferedWriter(new FileWriter("./log.txt", true)); writer.write(log, 0, log.length()); writer.newLine(); } catch (FileNotFoundException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } finally { try { if (writer != null) { writer.flush(); writer.close(); } } catch (Exception e) { e.printStackTrace(); } } return true; }
うまく説明できませんが、別のディレクトリに同じパス構成をコピーしたいときなどに使用できると思います。
//たとえば "c:/temp", "c:/temp/fuga/aaaaa.txt", "d:/huge/hoho" に対して // d:/huge/hoho/fuga/aaaaa.txt としたい public static String trimAndConcat(String base, String path, String other) { URI uriBase = new File(base).toURI(); URI uriPath = new File(path).toURI(); URI uriRelativised = uriBase.relativize(uriPath); return new File(other, uriRelativised.toString()).getAbsolutePath(); }
URLクラスからそのファイルまでのパスを取得する方法です。
String path = new File(url.getPath()).getPath();
とやることで、
URL : file:/C:/hoge/config/hoge.txt File: C:\hoge\config\hoge.txt
File mainDirectory = new File([ディレクトリ]); String[] files = mainDirectory.list(new FilenameFilter() { public boolean accept(File dir, String name) { if (name.endsWith("xml")) { return true; } return false; } });
filesが拡張子がxmlのファイル(ファイル名、の配列)
String hoge="aaa.xml"; hoge.substring(hoge.lastIndexOf('.'));
で.xmlが取得できる。
String hoge="aaa.xml"; hoge.substring(0, hoge.indexOf('.'));
でaaaが取得できる。/etc/aaa.xml.bakとかには使えないけど。。
try { Runtime.getRuntime().exec( new String[] { "rundll32.exe", "url.dll,FileProtocolHandler", "http://jp.sun.com/" }); } catch (IOException e) { e.printStackTrace(); }
SWTから起動したい方は こちら
String root_path = this.getServletContext().getRealPath("/"); String file_path = root_path + "hoge.dat"
try { TransformerFactory tfactory = TransformerFactory.newInstance(); Transformer transformer = tfactory.newTransformer(); // transformer.setOutputProperty("encoding", "EUC-JP"); transformer.transform(new DOMSource(document), <-document : XMLのDOMです //new StreamResult(System.out)); <- こっちだとコンソール出力 new StreamResult(new FileOutputStream(new File(output)))); } catch (TransformerConfigurationException e) { e.printStackTrace(); } catch (TransformerFactoryConfigurationError e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); } catch (FileNotFoundException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); }
public void write(HttpServletRequest request, HttpServletResponse response) { response.setContentType("text/xml; charset=UTF-8"); try { PrintWriter out = response.getWriter(); transformer.transform(new DOMSource(getDocument()), new StreamResult(out)); } catch (IOException e) { } catch (TransformerException e) { } }
response.setContentType("text/xml; charset=UTF-8");
//プロキシ認証の記述方法 BASE64Encoder encoder = new BASE64Encoder(); urlConnection.setRequestProperty( "Proxy-Authorization", "Basic " + encoder.encode((userid + ":" + password).getBytes()));
>java -classpath ".;lib;classes;lib\log4j-1.2.8.jar;swt.jar" kino.swt.JavaDocSearchForm >java -classpath ".;lib;classes;lib\log4j-1.2.8.jar;swt.jar;lib\kino_javadocsearch.jar" kino.swt.JavaDocSearchForm
>java -classpath "クラスパス(セミコロン区切り)" クラス
このサイトよいかも。
@see UserInformationManager#getUserInformation(String)
とすると、リンクが張られる。
{@link InformationController InformationController}のファイル読み込みの実装です。
とか
{@link クラス名#メンバ名 表示テキスト}
なんて使い方もできる
type: 型 collection: コレクションクラス (type[]) collection.toArray(new type[collection.size()]);
fileList: Object[]型 java.util.Arrays.asList(fileList);
BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(path)); //もしくは //new BufferedReader( // new InputStreamReader(url.openStream(), "JISAutoDetect")); String line; while ((line = reader.readLine()) != null) { buffer.append(line); buffer.append("\n"); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } reader = null; } }
try { //FileInputStreamオブジェクトの生成 FileInputStream inFile = new FileInputStream([serializeしたファイル名]); //ObjectInputStreamオブジェクトの生成 ObjectInputStream inObject = new ObjectInputStream(inFile); Object object = (クラス名) inObject.readObject(); inObject.close(); //オブジェクト入力ストリームのクローズ inFile.close(); //ファイル入力ストリームのクローズ //FileOutputStreamオブジェクトの生成 FileOutputStream outFile = new FileOutputStream([書き出したいファイル名]); //ObjectOutputStreamオブジェクトの生成 ObjectOutputStream outObject = new ObjectOutputStream(outFile); //クラスVectorのオブジェクトの書き込み outObject.writeObject(object); outObject.close(); //オブジェクト出力ストリームのクローズ outFile.close(); //ファイル出力ストリームのクローズ } catch (FileNotFoundException e) { } catch (IOException e) { } catch (ClassNotFoundException e) { }
String model = "hogehoge"; // String[] model = new String[] { "hogehoge", "hugahuga" }; List list = new ArrayList(); if (model.getClass().isArray()) { Object tmp = model; list = Arrays.asList((Object[]) tmp); } else { list.add(model); } System.out.println(list);
インナークラス・無名クラスは、フィールドにはアクセス可能、ローカル変数には不可能。
宣言時に初期化する必要があるのかと思ってたんですが、コンストラクタ内でもよいんですね。知らなかった。
この記事は
現在のアクセス:129673