Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

iOS10.3 APFSの対処

More than 3 years have passed since last update.

やらかしたので反省文

iOS10.3にてファイルシステムが HFS+からAPFSに強制変換されましたが
濁点など含むファイル名にてfopenなどの下位関数にアクセスする際
Stringなどからconst char* への変換は
UTF8String ではなく fileSystemRepresentation を使いましょう。

ざくっと調べた

検証コードを整えるのが面倒なので結果だけ

合成された普通のもの NFC : "だ" 3080 (1文字は1文字)
正規化分解NFD : "だ" 305F 3099 (濁点分割して検索なんかも楽しそうよね)

HFS+でもAPFSでもファイル名は正規化分割NFDされて保存される (前からそう)

HFS+では分割されていてもいなくても(NFD,NFC)同じNFDファイル名にアクセスできる、おそらくどこかでうまく処理してくれていたのだろう

APFSではfopenなどの下位関数はNFCそのままにアクセスされる、変換処理してくれない (ここが問題)

よってAPFSではNFC,NFDのファイル名が2つできたり、NFC名でアクセスした際ファイルが無いなどの問題が起こる
(これでNFCなファイルが出来るとbackupなんかでも問題起きたりするとか)

NSFileManagerなどの上位関数でのファイル処理は問題ない
(objc的に書いているけれども)swiftも問題は同じ

対処としては、ファイル名などは普通StringなりURLなりで持っていると思われ、
fopenなどの低位関数にてアクセスする際のファイル名は const char* に変換することになると思われるので、
このStringなりからconst char*への変換をUTF8StringではなくfileSystemRepresentation (これはファイルシステムに対応してNFDなりの処理をしてくれる)で行う。

CFStringNormalize((CFMutableStringRef)なにか, kCFStringNormalizationFormD);
でもNFD変換できるが、ここは素直にファイル系のAPIに従おう。

NSURLのメソッドなのでNSStringとかからなら
[[NSURL fileURLWithPath:self] fileSystemRepresentation];
てのでもよい。(相対パスからだと少し注意)

ファイルシステムとAPIの問題で、今までうまく処理していてくれただけに、バグと判断したくもなるヨナ。

ざくっとなので内容に関しては自分で確認してね。

https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/APFS_Guide/FAQ/FAQ.html#//apple_ref/doc/uid/TP40016999-CH6-DontLinkElementID_3

追記
NFCなファイル名は存在するべきではないし、
ファイルのcreate/writeには上記に気をつけていれば問題ないがreadの場合、
NSFileManagerなどの上位関数ではNFCなファイル名のものは無いものとして処理される。
fileExistsAtPathなどではfalse
だがcontentsOfDirectoryAtPathではNFCなままリストアップされて返ってくる。
上位関数レベルで見ると、あるらしいけれどアクセスできないってファイルになるという。

そんなの作らなければいいのだけれど、windowsのiTunes転送だと、NFCなファイル名なまま作成されてしまう恐ろしい罠が。(あ、もうapple自身がやっちゃてるならバグよね)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away