Hatena::ブログ(Diary)

Undead mode 忘備録

2008-02-15 [C#]シリアライズなバイナリを圧縮解凍してみよう

[C#]シリアライズしたバイナリデータを圧縮解凍する方法 01:16

.Net Freamework 2.0から、System.IO.Compressionが追加されていて、DeflateStream(rfc1951), GZipStream(rfc1952)が使用できる。

シリアライズはBinaryFormatterを使えばいい。簡単に書こうとすると、以下のよーな感じになる。

/// <summary>
/// オブジェクトを圧縮して書き込み
/// </summary>
/// <param name="filePath"></param>
/// <param name="obj"></param>
public void WriteWithCompress(string filePath, object obj)
{
    using (Stream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
    {
        using (DeflateStream ds = new DeflateStream(stream, CompressionMode.Compress, true))
        {
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(ds, obj);
        }
    }
}

このソースを.Net Freamework 2.0(VisualStudio2005)で動作させてみると、出力サイズが大して圧縮されていないことに気づくと思う。ところが、.Net Freamework 3.0(VisualStudio2008)で動作させるとサイズは半分以下になる。

この違いは、恐らく2.0のバグが3.0で改善されたとか、そんなところじゃないかと思われる。根拠はないが。

じゃあ2.0では使い物にならないのかというと、そういうわけでもない。

MemoryStreamを使用して、逐一バッファに保持すればいい。

/// <summary>
/// オブジェクトを圧縮して書き込み
/// </summary>
/// <param name="filePath"></param>
/// <param name="obj"></param>
public void WriteWithCompress(string filePath, object obj)
{
    byte[] buffer;
    using (MemoryStream ms = new MemoryStream())
    {
        IFormatter formatter = new BinaryFormatter();
        formatter.Serialize(ms, obj);
        buffer = ms.ToArray();
    }
    using (MemoryStream ms = new MemoryStream())
    {
        using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Compress, true))
        {
            ds.Write(buffer, 0, buffer.Length);
        }
        buffer = ms.ToArray();
    }
    using (Stream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
    {
        stream.Write(buffer, 0, buffer.Length);
    }
}

これで2.0, 3.0で同様の結果が得られる。

読み込みについては、バージョン関係なく以下のように。

/// <summary>
/// 圧縮されたオブジェクトを解凍して読み込み
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public object ReadWithDecompress(string filePath)
{
    object obj;
    using (Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
    {
        using (DeflateStream ds = new DeflateStream(stream, CompressionMode.Decompress))
        {
            IFormatter formatter = new BinaryFormatter();
            obj = formatter.Deserialize(ds);
        }
    }
    return obj;
}

ちなみに、GZipStreamを使いたい場合は、DeflateStreamをGZipStreamに書き換えるだけでOKだ。

[C#]シリアライズしたオブジェクトバイナリ形式で出力する方法 00:50

まずはシリアライズ。方法は、[Serializable]を付けるだけ。

例として、文字列をバイト配列で保持するシリアライズクラスを適当に書いてみた。

using System;
using System.Collections.Generic;
using System.Text;

namespace SandBox
{
    [Serializable]
    public class SerializedByteArray
    {
        private byte[] data;

        public SerializedByteArray(string str)
        {
            this.data = Encoding.Unicode.GetBytes(str);
        }

        public string Text
        {
            get { return Encoding.Unicode.GetString(data); }
        }
        /// <summary>
        /// 保持しているバイト情報を引数で指定した数だけ倍にする
        /// </summary>
        /// <param name="size"></param>
        public void Increase(int size)
        {
            string str = this.Text;
            StringBuilder temp = new StringBuilder(str);
            for (int i = 0; i < size; i++)
            {
                temp.Append(str);
            }
            this.data = Encoding.Unicode.GetBytes(temp.ToString());
        }
    }
}

さて、このクラスをバイナリ形式でファイル入出力してみよう。

実はBinaryFormatterを使って簡単に出力できる。

使うのは、Serialize()メソッド。

/// <summary>
/// オブジェクト書き込み
/// </summary>
/// <param name="filePath"></param>
/// <param name="obj"></param>
public void Write(string filePath, object obj)
{
    using (Stream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
    {
        IFormatter formatter = new BinaryFormatter();
        formatter.Serialize(stream, obj);
    }
}

読み込みも同様に簡単に書ける。

こちらは、Deserialize()メソッドで取り込み。

/// <summary>
/// オブジェクト読み込み
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public object Read(string filePath)
{
    object obj;
    using (Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
    {
        IFormatter formatter = new BinaryFormatter();
        obj = formatter.Deserialize(stream);
    }
    return obj;
}

手軽。

ぱにゅあぁああwwwwwぱにゅあぁああwwwww 2009/07/09 15:03
前のは俺と相性合わなかったから最近コッチに替えたらバッチリ最強ww
クリ舐めパイ揉み同時進行上等すぎだしwwwww
てか一発で10万貰えたんだけど、ここのお姉さんみんな金使いひでぇなwww
まぁ俺の懐は潤うからいいけどなw 金ってある所にはあるんだな(^^;

http://oKdsEcJ.meshiuma.tsukimisou.net/

ケースバイケースwwwwケースバイケースwwww 2009/07/26 19:22
「今日はディープスロートの練習させて!!ケースバイケースだから!!!」
昨日こんな事を言われたんだが・・・なんだよケースバイケースってwwww
使い方間違ってるよwwww てかこんなヴァカなのに何で金持ちなの??
すごいテンションでいつも10万くれるのはやっぱヴァカだから?wwwwww

http://netoge.bolar.net/4iMcSA8/

おっぷぁい!ぷぁい!おっぷぁい!ぷぁい! 2009/08/06 00:14
しばらくお互いに愛撫し合ってたら、女が急にカバンから蜂蜜取り出してボクのティンポに塗りたくってきてパイズリ始めたからビックリしたよ(^^;
パイズリされつつ蜂蜜塗られてティンポしゃぶってもらっての繰り返しで、気持ちよすぎて気がついたら3回イったしwww 俺淡白なのにすげwwwwww
やっぱ巨乳で工口工口な女が一番だよねーヽ(゜∀゜)ノヒャッヒャッ!!

http://ene.creampie2.net/7yAq7o9/

じゃぶぁー!!!!じゃぶぁー!!!! 2009/08/10 02:11
やっぱコスしてもらってハ メ るのが一番萌えに燃えるって!!!!!!
昨日はエ○ァの新キャラコスしてもらったもんねー(*´Д`)ハァハァ
興 奮しすぎて無意識に服着せたままパ ン ツ ビリビリに破いてバック突きしまくっちゃったwwww(テヘw)
既に次はハ○ヒで決定してるしwktkが止まらんねぇぇぇwwwwwwwwww

http://kachi.strowcrue.net/0Rz0NZ2/

ケ ツ コ キ!!!!!!!!!ケ ツ コ キ!!!!!!!!! 2009/08/16 21:42
すんげえケ ツでかい女に当たった!!! コイツのケ ツ 技すぎすぎwwwww

ケ ツにロ -ショ ン塗りたくって、俺のティ ヌコ挟んですんげー前後すんの!!!
前後してる時にク リに当たったりマ ヌ コに入ったりして
女もアヒアヒしまくりで俺も女も絶 頂しまくりで最高ですたwwwwwww

こりゃハマるわぁ・・・・

http://yuzo.plusnote.net/zndUCzi/

よーちよちよちよち!!!!よーちよちよちよち!!!! 2009/08/23 09:36
最近ここの女におしゃぶり咥えさせてガラガラ持たせて
パッコンパッコンしてやったんだが、反応がハンパネェっすwwwwwwww

「気持ちいいですぅーん!!はあっぁぁああ!!!」

こんな萌えボイスで叫ばれたら余計に興 奮するっての!!!!!!

仕方ないからずぶずぶ奥まで挿れてあげたら
ずっと潮ピュルーって飛ばして痙攣しまくりー(・∀・)ぐっふふ

http://okane.d-viking.com/OHCeWVi/

ちょwwwwこれわwwwwwちょwwwwこれわwwwww 2009/08/27 22:10
ここまで簡単なバ イ トって他に無ぇだろwwwwwww
ち ん こさえあればおkだもんなwwwwwwwww
女にち ん こ見せただけでも大喜びだし、
挿入してやったらもうキャンキャン言いまくりwwwwwwwww

ぶっちゃけここまで気持ちよく稼げるとは思ってなかったわぁ(>_<)

http://koro.chuebrarin.com/3lPzxkW/

2007-09-30 [java]Super CSV CsvBeanWriter 考察

[java]CsvBeanReader, CsvBeanWriter, ParseDateを併用するには 04:27

前回、Beanによる読み込みとMapによる書き込みを取り上げましたが、元サイトのサンプルソースに手を加えての紹介、という趣旨だったので、Beanによる書き込みについては割愛しました。

なので、今回はBeanによる書き込みに焦点を当ててみましょう。


配布サイト:no title

前回記事:[java]CSVの読み書きを快適に〜「Super CSV」ノススメ - Undead mode 忘備録


早速ですが、Bean内容を出力するmain実装をしてみると、↓のような感じになります。

ファイル名:WritingObjects.java

package write;

import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;

import bean.UserBean;

/**
 * SuperCSVによるCSVファイル書き込み(Bean)
 * @author kazuki.kido
 */
public class WritingObjects {
    public static void main(String[] args) throws Exception {
        // ヘッダ情報定義
        String[] header = new String[]{"username", "password", "date", "zip", "town"};
        List<UserBean> list = new ArrayList<UserBean>();
        // 1行目データを作成
        UserBean bean1 = new UserBean();
        bean1.setUsername("Klaus");
        bean1.setPassword("qwexyKiks");
        bean1.setDate(new Date());
        bean1.setZip(1111);
        bean1.setTown("Tokyo");
        list.add(bean1);
        // 2行目データを作成
        UserBean bean2 = new UserBean();
        bean2.setUsername("Oufu");
        bean2.setPassword("bobilop");
        bean2.setDate(new Date());
        bean2.setZip(4555);
        bean2.setTown("Tokyo");
        list.add(bean2);
        ICsvBeanWriter writer = new CsvBeanWriter(new FileWriter("./data/boo.csv"), CsvPreference.EXCEL_PREFERENCE);
        try {
            // ファイルへ出力
            writer.writeHeader(header);
            // エラーログ取得用バッファ
            StringBuilder errorLog = new StringBuilder();
            // ファイルへ書き出し
            for(UserBean bean : list){
                writer.write(bean, header, UserBean.processors, errorLog);
                if(errorLog.length() > 0){
                    System.err.println(errorLog);
                    break;
                }
            }
        } finally {
            writer.close();
        }
    }
}

UserBeanについては前回作成したものを流用します。が、実はこのままだとエラーが発生してしまいます。エラーが発生する原因は、UserBean.javaの以下の部分。

ファイル名:UserBean.java

    /** 各要素フォーマット定義 */
    public static final CellProcessor[] processors = new CellProcessor[] {
            new Unique(new StrMinMax(4, 20)),    // username
            new StrMinMax(7, 35),                // password
            new ParseDate("dd/MM/yyyy"),         // date
            new Optional(new ParseInt()),        // zip
            null                                 // town
    };

date要素の定義にParseDateを使用していますが、このクラスは「CSVから取得した文字列 ⇒ 引数のフォーマットとして解釈し、Date型に変換して保持する」ことを指示しています。

しかし、CsvBeanWrite.write(Object, String, CsvPreference, StringBuilder)で必要となるのは「Date型⇒引数のフォーマットで変換し、文字列として出力する」指示です。探してみても、この2つを満たすハイブリットなクラスは用意されていません。

ないんじゃ仕方ないですよね〜というわけで、作ってみました。

ファイル名:ParseDateEx.java

package cell;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.supercsv.cellprocessor.ParseDate;
import org.supercsv.cellprocessor.ift.DateCellProcessor;
import org.supercsv.exception.SuperCSVException;
import org.supercsv.util.CSVContext;

/**
 * write時の処理を考慮したParseDate拡張
 * @author kazuki.kido
 */
public class ParseDateEx extends ParseDate{
    /** 日付フォーマット */
    DateFormat formatter;
    /**
     * コンストラクタ
     * @param s
     */
    public ParseDateEx(String s) {
        super(s);
        formatter = new SimpleDateFormat(s);
    }
    /**
     * コンストラクタ
     * @param s
     * @param datecellprocessor
     */
    public ParseDateEx(String s, DateCellProcessor datecellprocessor) {
        super(s, datecellprocessor);
        formatter = new SimpleDateFormat(s);
    }
    /**
     * フォーマットチェック処理
     * @param obj
     * @param csvcontext
     * @throws SuperCSVException
     */
    public Object execute(Object obj, CSVContext csvcontext) throws SuperCSVException {
        // 出力時処理
        if(obj instanceof Date){
            return formatter.format((Date)obj);
        }
        // 入力時処理
        return super.execute(obj, csvcontext);
    }
}

ParseDateを継承し、executeメソッドのみ小細工しています。他メソッドは親メソッドを呼んでいるだけです。executeメソッドの引数objにDate型が渡された場合、ファイル出力時にメソッドが呼ばれているということになるので、formatterに基づくString型の値を返します。他の型が渡された場合は親メソッドに処理を引き継ぎます。

早速これをUserBeanに適用してみます。

ファイル名:UserBean.java

package bean;

import java.util.Date;

import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.ParseInt;
import org.supercsv.cellprocessor.constraint.StrMinMax;
import org.supercsv.cellprocessor.constraint.Unique;
import org.supercsv.cellprocessor.ift.CellProcessor;

import cell.ParseDateEx;

/**
 * CSVファイルの要素定義(Bean)
 * @author kazuki.kido
 */
public class UserBean {
    
    /** 各要素フォーマット定義 */
    public static final CellProcessor[] processors = new CellProcessor[] {
            new Unique(new StrMinMax(4, 20)),    // username
            new StrMinMax(7, 35),                // password
            new ParseDateEx("dd/MM/yyyy"),       // date
            new Optional(new ParseInt()),        // zip
            null                                 // town
    };
    
    /* 各要素の Getter/Setter 定義 */
    
    private String username, password, town;
    private Date date;
    private int zip;

    public String getPassword() { return password; }
    public Date getDate() { return date; }
    public String getTown() { return town; }
    public String getUsername() { return username; }
    public int getZip() { return zip; }
    public void setPassword(String password) { this.password = password; }
    public void setDate(Date date) { this.date = date; }
    public void setTown(String town) { this.town = town; }
    public void setUsername(String username) { this.username = username; }
    public void setZip(int zip) { this.zip = zip; }
}

ParseDate ⇒ ParseDateExに変わったのと、importが変更になっただけですね。

これで準備OKです。

実行してみると、以下のような内容が出力されます。

ファイル名:boo.csv

username,password,date,zip,town
Klaus,qwexyKiks,30/09/2007,1111,Tokyo
Oufu,bobilop,30/09/2007,4555,Tokyo

ちゃんと日付も意図した形式で出力されました。


尚、今回のプロジェクト構成は以下の通りです。

f:id:kazuki-kido:20070930042516j:image

2007-09-25 [java]CSVの読み書きを快適に〜「Super CSV」ノススメ

[java]Super CSV による File Read 22:44

Super CSVは、CSVファイルをオブジェクトのような感覚で扱うことができる、オープンソースCSVファイル高速アクセスライブラリです。言ってみればO/RマッピングCSVファイル版ですね。

no title

これが非常に便利そうなのに、何故かサイトに載っているサンプルコードが微妙に不親切なので、簡単に書き換えてみました。


読み込むCSVファイルの内容は次のような感じです。

ファイル名:foo.csv

username, password,   date,        zip,  town
Klaus,    qwexyKiks,  17/1/2007,   1111, New York
Oufu,     bobilop,    10/10/2007,  4555, New York

さて、まずはBeanの定義。このクラスでは、CSVファイルの列要素を定義します。

ファイル名:UserBean.java

package bean;

import java.util.Date;

import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.ParseDate;
import org.supercsv.cellprocessor.ParseInt;
import org.supercsv.cellprocessor.constraint.StrMinMax;
import org.supercsv.cellprocessor.constraint.Unique;
import org.supercsv.cellprocessor.ift.CellProcessor;

/**
 * CSVファイルの要素定義(Bean)
 * @author kazuki.kido
 */
public class UserBean {
    
    /** 各要素フォーマット定義 */
    public static final CellProcessor[] processors = new CellProcessor[] {
            new Unique(new StrMinMax(4, 20)),    // username
            new StrMinMax(7, 35),                // password
            new ParseDate("dd/MM/yyyy"),         // date
            new Optional(new ParseInt()),        // zip
            null                                 // town
    };
    
    /* 各要素の Getter/Setter 定義 */
    
    private String username, password, town;
    private Date date;
    private int zip;

    public String getPassword() { return password; }
    public Date getDate() { return date; }
    public String getTown() { return town; }
    public String getUsername() { return username; }
    public int getZip() { return zip; }
    public void setPassword(String password) { this.password = password; }
    public void setDate(Date date) { this.date = date; }
    public void setTown(String town) { this.town = town; }
    public void setUsername(String username) { this.username = username; }
    public void setZip(int zip) { this.zip = zip; }
}

で、実際に読み込み処理を行うmain実装が↓のようなかんじになります。読み込んだ内容をコンソール出力します。

ファイル名:ReadingObjects.java

package read;

import java.io.FileReader;

import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.prefs.CsvPreference;

import bean.UserBean;

/**
 * SuperCSVによるCSVファイル読み込み
 * @author kazuki.kido
 */
public class ReadingObjects {
    
    public static void main(String[] args) throws Exception{
        ICsvBeanReader inFile = new CsvBeanReader(
            new FileReader("./data/foo.csv"), CsvPreference.EXCEL_PREFERENCE);
        try {
            final String[] header = inFile.getCSVHeader(true);
            UserBean user = null;
            while((user = inFile.read(UserBean.class, header,
                            UserBean.processors)) != null){
                // 取得要素をコンソールへ出力
                System.out.print("ユーザ名:" + user.getUsername());
                System.out.print(" パスワード:" + user.getPassword());
                System.out.print(" 日付:" + user.getDate());
                System.out.print(" 郵便番号:" + user.getZip());
                System.out.println(" 住所:" + user.getTown());
            }
        } finally {
            inFile.close();
        }
    }
}

で、コンソール出力結果がこんなかんじになります。

ユーザ名:Klaus パスワード:qwexyKiks 日付:Wed Jan 17 00:00:00 JST 2007 郵便番号:1111 住所:New York

ユーザ名:Oufu パスワード:bobilop 日付:Wed Oct 10 00:00:00 JST 2007 郵便番号:4555 住所:New York

Beanを介してCSVファイルの内容を簡単に取得できます。定義に沿ってDate型なんかに自動変換してくれるので、とても楽です。


ちなみにプロジェクト構成は以下の通り。

f:id:kazuki-kido:20070925232527j:image

[java]Super CSV による File Write 23:10

では続いてファイル書き込みもやってみましょう。

ファイル名:WritingMaps.java

package write;

import java.io.FileWriter;
import java.util.HashMap;

import org.supercsv.io.CsvMapWriter;
import org.supercsv.io.ICsvMapWriter;
import org.supercsv.prefs.CsvPreference;

/**
 * SuperCSVによるCSVファイル書き込み
 * @author kazuki.kido
 */
class WritingMaps {
    public static void main(String[] args) throws Exception {
        ICsvMapWriter writer = new CsvMapWriter(new FileWriter("./data/boo.csv"), CsvPreference.EXCEL_PREFERENCE);
        try {
            final String[] header = new String[] { "name", "city", "zip" };
            // 1行目データを作成
            final HashMap<String, ? super Object> data1 = new HashMap<String, Object>();
            data1.put(header[0], "Karl");
            data1.put(header[1], "Tent city");
            data1.put(header[2], 5565);
            // 2行目データを作成
            final HashMap<String, ? super Object> data2 = new HashMap<String, Object>();
            data2.put(header[0], "Banjo");
            data2.put(header[1], "River side");
            data2.put(header[2], 5551);
            // ファイルへ出力
            writer.writeHeader(header);
            writer.write(data1, header);
            writer.write(data2, header);
        } finally {
            writer.close();
        }
    }
}

こちらはBeanではなく、Mapを用いています。当然、ICsvBeanWriter, CsvBeanWriterとUserBeanを使えば、Beanによる書き込みも可能です。

[java]CsvBeanReader, CsvBeanWriter, ParseDateを併用するには - Undead mode 忘備録

ファイルへの出力結果は次の通り。

ファイル名:boo.csv

name,city,zip
Karl,Tent city,5565
Banjo,River side,5551

よさげです。

[java]Super CSV で区切り文字や改行文字を任意に指定する 00:51

「で、区切り文字とかどうなってんの?」


はい、ちゃんと用意されています。CsvPreferenceというクラスで指定できます。

次のように第2引数で指定します。

ICsvBeanReader inFile = new CsvBeanReader(new FileReader("./data/foo.csv"), CsvPreference.EXCEL_PREFERENCE);

ICsvMapWriter writer = new CsvMapWriter(new FileWriter("./data/boo.csv"), CsvPreference.EXCEL_PREFERENCE);

CsvPreference.EXCEL_PREFERENCEを使用していますが、予め用意されている定義は全部で4種類。

定数名称クォート文字区切り文字(デリミタ)改行文字
STANDARD_PREFERENCE",\r\n
EXCEL_PREFERENCE",\n
EXCEL_NORTH_EUROPE_PREFERENCE";\n
NO_COMMENT_PREFERENCE",\n

何気にEXCEL_PREFERENCEとNO_COMMENT_PREFERENCEは、定義内容が全く同じです。

さて、当然これ以外のパターンについても任意で指定することが可能です。たとえば、クォート文字を'B'、区切り文字を'?'、改行文字列を"\r\n"としたい場合、

CsvPreference preference = new CsvPreference('B', '?', "\r\n");
ICsvBeanReader inFile = new CsvBeanReader(new FileReader("./data/foo.csv"), preference);

ICsvMapWriter writer = new CsvMapWriter(new FileWriter("./data/boo.csv"), preference);

といった要領でCsvPreferenceをインスタンス化し、使用します。

おうおう 2011/05/20 20:11 非常に分かりやすく説明です、有難うございました。

おうおうおうおう 2012/07/22 12:07 参考にさせて頂きました。ありがとうございます!

2007-09-06 [java]ファイル読込み速度について

[java]Jakarta IO の底力 01:12

単純なファイル読み込みを行う場合、FileInputStream, InputFileReader, BufferReader

コンボを使うよりも、LineIteratorを使う方が高速ですよ、という話。

Jakarta : 266ms

Standard : 343ms

Channel : 3375ms

filesize : 1,331,881 bytes

Java 1.6.0.2

/**
 * jakarta.ioを用いたファイル読込み
 * @param filePath
 * @return ファイル内容
 */
public List<String> jakartaReader(String filePath, String encode) throws IOException{
    List<String> fileData = new ArrayList<String>();
    LineIterator iterator = FileUtils.lineIterator(new File(filePath), encode);
    try{
        while(iterator.hasNext()){
            fileData.add(iterator.nextLine());
        }
    } finally {
        LineIterator.closeQuietly(iterator);
    }
    return fileData;
}
/**
 * 一般的なファイル読込み
 * @param filePath ファイルパス
 * @return ファイル内容
 */
public List<String> standardReader(String filePath, String encode) throws IOException{
    List<String> fileData = new ArrayList<String>();
    FileInputStream fs = null;
    InputStreamReader sr = null;
    BufferedReader br = null;
    try{
        fs = new FileInputStream(filePath);
        sr = new InputStreamReader(fs, encode);
        br = new BufferedReader(sr);
        String line = null;
        while((line = br.readLine()) != null){
            fileData.add(line);
        }
    }finally{
        if(br != null) try { br.close(); } catch (IOException e){}
        if(sr != null) try { sr.close(); } catch (IOException e){}
        if(fs != null) try { fs.close(); } catch (IOException e){}
    }
    return fileData;
}
/**
 * channel経由のファイル読込み
 * @param filePath
 * @return ファイル内容
 */
public List<String> channelReader(String filePath, String encode) throws IOException{
    List<String> fileData = new ArrayList<String>();
    int bufSize = 65535;
    FileInputStream fs = null;
    try{
        fs = new FileInputStream(filePath);
        FileChannel channel = fs.getChannel();
        long size = channel.size();
        if(size < bufSize) bufSize = (int)size;
        ByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
        byte[] bytes = new byte[bufSize];
        boolean chCR = false;
        int lastSize = (int)(size % bufSize);
        read : for(long pos = size; pos > 0; pos -= bufSize){
            if(pos <= lastSize) bytes = new byte[lastSize];
            buffer.get(bytes);
            String temp = new String(bytes, encode);
            int start = 0;
            for(int i=0; i<temp.length(); i++){
                char c = temp.charAt(i);
                if(c == '\r'){ // CR
                    fileData.add(temp.substring(start, i));
                    chCR = true;
                } else if(c == '\n'){ // LF
                    start = i + 1;
                    if(chCR){
                        chCR = false;
                    } else {
                        fileData.add(temp.substring(start, i));
                    }
                } else if(c == '\0'){ // ファイル終了
                    fileData.add(temp.substring(start, i));
                    break read;
                } else {
                    chCR = false;
                }
            }
            size -= bufSize;
        }
    } finally {
        if(fs != null) try{ fs.close(); } catch (IOException e){}
    }
    return fileData;
}

2007-09-03 超小ネタ

リモートデスクトップからリブートするには 21:48

1. Win + R

2. 名前:「cmd」⇒ OK

3.↓

リブート

shutdown -r -t 0

シャットダウン

shutdown -s -t 0

ほぼ毎日利用してます。

Connection: close