top / index / prev / next / target / source

2002-01-23 diary: ファイル分割プログラムの試作

いがぴょんの日記 日記形式でつづる いがぴょんコラム ウェブページです。

old-v2

ファイル分割プログラムの試作

ファイル分割プログラムを試作してみました。

静岡出張から帰ってきました。明日は東京出張です

1泊2日の静岡出張から帰ってきました。明日は日帰りの東京出張です。先々週から出張シリーズ続きだなぁ。

ファイル分割プログラムを試作してみました

必要に駆られて ちょっとファイル分割プログラムを作成しました。分割と復元の2パターン両方を準備してみました。

/**
 * ファイル分割プログラム
 * Copyright (C) 2002  Tosiki IGA
 *
 *   @author Tosiki IGA
 *   @version 2002.01.23
 *   (http://homepage2.nifty.com/igat/igapyon/index.html)
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

import java.io.*;

public class Split
{
        public static final void main(String[] args)
        {
                if(args.length==0){
                        System.out.println("Split");
                        System.out.println("  usage: java Split FILENAME");
                        System.out.println("  usage: java Split -r FILENAME"+SZ_SPLIT_SUFFIX+"1");
                }else if(args[0].equals("-r") && args.length>1){
                        if(args[1].endsWith(SZ_SPLIT_SUFFIX+"1")==false){
                                System.out.println("*"+SZ_SPLIT_SUFFIX+"1 ファイルを指定してください.");
                        }else{
                                try{
                                        merge(new File(args[1]));
                                }catch(IOException ex){
                                        System.out.println(ex.toString());
                                        ex.printStackTrace();
                                }
                        }
                }else{
                        try{
                                split(new File(args[0]));
                        }catch(IOException ex){
                                System.out.println(ex.toString());
                                ex.printStackTrace();
                        }
                }

        }

        public static final int SPLIT_SIZE=1440000;
        public static final String SZ_SPLIT_SUFFIX="-split-";

        public static final void split(File fileInput)
                throws IOException
        {
                boolean isEndOfFile=false;
                BufferedInputStream inStream=null;
                try{
                        inStream=new BufferedInputStream(new FileInputStream(fileInput));

                        for(int iFileCounter=1;isEndOfFile==false;iFileCounter++){
                                File fileTarget=new File(fileInput.getName()+SZ_SPLIT_SUFFIX+iFileCounter);
                                BufferedOutputStream outStream=null;
                                outStream=new BufferedOutputStream(new FileOutputStream(fileTarget));
                                System.out.println("  generating ["+fileTarget+"]");
                                for(int iSplitCounter=0;iSplitCounter<SPLIT_SIZE;iSplitCounter++){
                                        int iRead=inStream.read();
                                        if(iRead==(-1)){
                                                isEndOfFile=true;
                                                break;
                                        }
                                        outStream.write(iRead);
                                }
                                outStream.flush();
                                outStream.close();
                        }

                }finally{
                        inStream.close();
                }
        }

        public static final void merge(File fileInput)
                throws IOException
        {
                String strOriginalFileName=fileInput.getName().substring(0,fileInput.getName().length()-SZ_SPLIT_SUFFIX.length()-1);

                BufferedOutputStream outStream=null;

                try{
                        outStream=new BufferedOutputStream(new FileOutputStream(strOriginalFileName));

                        for(int iFileCounter=1;;iFileCounter++){
                                BufferedInputStream inStream=null;
                                File fileRead=new File(strOriginalFileName+SZ_SPLIT_SUFFIX+iFileCounter);
                                if(fileRead.exists()==false){
                                        break;
                                }

                                inStream=new BufferedInputStream(new FileInputStream(fileRead));
                                System.out.println("  merging ["+fileRead+"]");

                                for(;;){
                                        int iRead=inStream.read();
                                        if(iRead==(-1)){
                                                break;
                                        }
                                        outStream.write(iRead);
                                }
                                inStream.close();
                        }

                }finally{
                        outStream.flush();
                        outStream.close();
                }
        }
}

Unicodeの半角カタカナが0xff以上でびっくり (というかこの誤解が元でバグを作っていました)

Unicodeでの半角カタカナって 0xff以上のところにマップされているんですね。これを誤認していて、バグを作り込んでいました。EUCと同じような注意が必要なんですね。… Unicodeの文字コードにおいて、ある文字コードが 半角・全角いずれであるのかを判定する命令って、Java言語APIにあるのかしらん、、、私は見つけられませんでした。

2002/01/29 追記 読者のまつもとさんからのツッコミまつもとです。半角、全角を弁別するお手軽な方法はありません:) Unicode にはそのような概念はありませんから:)

確かはるか昔に Java-House ML でも話があったような…。マットウにやるならStringをShift_JISだかのバイト列に変換して長さを見るということになるでしょうし(unmappedが困りそう?)、はしょるなら

" 012345..abc....".indexOf(src.charAt(..))なんてことになるんですかね:)

ここからいがぴょんみなさんお困りのネタだったのですね。べんきょうになります。とりあえず私は半角かな領域の大小比較というものすごくはしょった技を使って回避してしまいました。でも、それを調べる過程で Unicodeのコード表をみながら がくぜんとしてしまいましたが…。というのも 0xff以下でも 旧来日本語処理において全角な文字が幾つか見つかってしまったのですもの。およよ…。

派生元のメソッド内で 子クラスのオーバーライド済みメソッドが呼ばれない…

妙なことで悩んでいました。時間切れで調査はあきらめましたが…派生先に派生元と同じ引数なメソッドAをオーバライドしたとします。で 派生元の中にある別のメソッドBを呼び出した際に、このオーバライドしたメソッドAは呼び出されるかどうか、ということです。でメソッドBの中からはオーバライドしたはずの派生先メソッドAは呼び出されず、親クラス内のメソッドAが呼び出されました。はて、私の勘違いだったのかしら。ちなみに環境は Windows版 J2SE 1.3.1_02 ですが…。

2002/01/29 追記 読者のまつもとさんからのツッコミまつもとです。メソッドが static か private だった、とかいうオチはないですか? static も private も呼び出し(というか呼び出され?)が自クラスに固定されますので。

2002/01/29 追記 さんからのツッコミ結城です。

class Parent {
    public void execute() {
        System.out.println("Parent");
    }
    public static void main(String[] args) {
        Child obj1 = new Child();
        obj1.execute();     // => Child

        Parent obj2 = new Child();
        obj2.execute();     // => Child

        Parent obj3 = new Parent();
        obj3.execute();     // => Parent
    }
}

class Child extends Parent {
    public void execute() {
        System.out.println("Child");
    }
}

の実行結果は、 Child Child Parentになりますね。

ここからいがぴょんう~む。そのとおりです。とりあえず私のケースでは 呼び出され側メソッドでpublic staticなメソッドが絡んでいたので それが一端となっているように思えます。…結合テストラッシュが終わったらもうちょっとマジメに調べてみます。…しかしそれはいつのことだろう (苦笑)


この日記について