Cocoaのエンコーディング

  • 投稿日:
  • by
  • カテゴリ:

とりあえず一個題材を決めて勉強しています。

今やっているのは、テキストファイルをNSOpenPanelで選択してNSTextViewに表示し、さらにファイルへ書き出すというものです。

Cocoa-Javaでも似たようなことを以前やっていたので、なんとなく分かるのですが、読み込むテキストのエンコーディングについて良くわからなくてウェブで色々調べてました。


Cocoa-Javaの時は意識していたかどうか定かではないのですが、読み込むファイルのエンコーディングがUTF-8だったりSJISだったEUCだったり・・・と様々な場合、ちゃんと化けずに読めるのかな?と。

たぶん英数字しか入ってないファイルであれば読めてしまうんでしょうけど、2バイト文字の日本語とかが入っているとどうなるのやら・・・。


で、結論から言うと、化けるというか読み込んでくれません。

使ったメソッドはNSStringの+ (id)stringWithContentsOfFile:(NSString *) path usedEncoding:(NSStringEncoding *) enc error:(NSError **) errorです。

※頭に+が付いてるとクラスメソッド、-だとインスタンスメソッドだそうです。

リファレンスを見ると、読み込んだファイルのエンコーディングを教えてくれるようなので、なんでも嫌わずに読み込んでくれるのかと思いましたがだめでした。

これが使えると、ブラウザで言うところの自動判別みたいなものが出来て楽だと思うのですけど、なんだかちゃんと動きません。

それでウェブで調べてみると、Cocoaのエンコーディングはどうなっておるのだ? - Nothing Upstairsという記事を見つけました。


なるほどやっぱりダメなんですね。


ということで、読み込むファイルのエンコーディングが分からない時は、トライアンドエラーするしかないのですかね。

ブラウザとかテキストエディタとかの実装ってみんなそうしているだろうか。


良くわかりませんが、とりあえず+ (id)stringWithContentsOfFile:(NSString *) path encoding:(NSStringEncoding) enc error:(NSError **) errorを使うことにして、NSStringEncodingに片っ端からエンコーディングを指定していくしかないのかな。

合ってるのかね??


/*
 NSOpenPanel終了時の処理
*/
- (void)openPanelDidEnd:( NSOpenPanel * )panel returnCode:( NSInteger )code {
	
	NSString *string = nil;
	//NSStringEncoding encoding = 0;
	NSError *error;
	
	// 押下されたボタンの判定
	if( code == NSCancelButton ) {
		
		/* Cancelボタン時 */
		
		// 何もせず終了
		return;
	}
	
	//
	// とりあえず、SJISで読み込んでだめならUTF8で読み込む。それだダメならreturn
	//
		
	// 選択されたファイル名称を取得
	NSString *path = [ panel filename ];
		
	// エンコーディングにNSShiftJISStringEncodingを指定してファイルを読み込む
	string = [ NSString stringWithContentsOfFile:path encoding:NSShiftJISStringEncoding error:&error ];
		
	// 読み込めたか判定
	if( string == nil ) {
			
		/* 読み込めなかった場合 */
			
		// エンコーディングにNSUTF8StringEncodingを指定してファイルを読み込む
		string = [ NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error ];
			
		// 読み込めたか判定
		if ( string == nil ) {
				
			/* 読み込めなかった場合 */
				
			// エラー出力
			NSLog( [ error localizedDescription ] );
				
			return;
		}
	}
			
	// テキストエリアに読み込んだ内容を出力
	[ textView setString: string ];
}