ãªãªãžã³ãã©ã€ããŒããã¡ã€ã«ã·ã¹ãã ïŒOPFSïŒã®åœ¹å²ãšããããWebã¢ããªã±ãŒã·ã§ã³ã«å ç¢ãªåé¢ã¹ãã¬ãŒãžãæäŸããäžçäžã®ããã©ãŒãã³ã¹ãšUXãåäžãããæ¹æ³ãæ¢ããŸãã
ãªãªãžã³ãã©ã€ããŒããã¡ã€ã«ã·ã¹ãã ïŒã°ããŒãã«ã¢ããªã±ãŒã·ã§ã³ã®ããã®åé¢ã¹ãã¬ãŒãžæŽ»çšè¡
é²åãç¶ããWebéçºã®äžçã§ã¯ãã·ãŒã ã¬ã¹ã§å¹ççãªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæäŸããããšãæãéèŠã§ããã°ããŒãã«ã¢ããªã±ãŒã·ã§ã³ã«ãšã£ãŠãããã¯ãã°ãã°ã¯ã©ã€ã¢ã³ããµã€ãã§ã®å¹æçãªããŒã¿ç®¡çã䌎ããŸããOrigin Private File System (OPFS)ã¯ãéçºè ããŠãŒã¶ãŒã®ãã©ãŠã¶å ã«çŽæ¥ããŒã¿ãä¿åããããã®ãå ç¢ã§åé¢ãããã髿§èœãªæ¹æ³ãæäŸãã匷åãªããŒã«ãšããŠç»å ŽããŸããããã®å æ¬çãªã¬ã€ãã§ã¯ãOPFSã®è€éããåœéçãªéçºã«ãããå©ç¹ããããŠåŒ·åãããWebã¢ããªã±ãŒã·ã§ã³ã®ããã«ãããæŽ»çšããæ¹æ³ã«ã€ããŠæãäžããŠãããŸãã
Webãšã³ã·ã¹ãã ã«ãããåé¢ã¹ãã¬ãŒãžã®çè§£
OPFSã«é£ã³èŸŒãåã«ãWebã¢ããªã±ãŒã·ã§ã³ã®æèã«ãããåé¢ã¹ãã¬ãŒãžã®æŠå¿µãçè§£ããããšãéèŠã§ããWebãã©ãŠã¶ã¯ãèšèšäžã峿 Œãªã»ãã¥ãªãã£ã¢ãã«ã®äžã§åäœããŸãããã®ã¢ãã«ã®äžæ žçãªä¿¡æ¡ã®äžã€ãããªãªãžã³ããŒã¹ã®åé¢ã§ããããã¯ãç¹å®ã®ãªãªãžã³ïŒãããã³ã«ããã¡ã€ã³ãããŒãïŒãããŠã§ããµã€ããçæããããŒã¿ã¯ãéåžžãä»ã®ãªãªãžã³ãçæããããŒã¿ãšã¯å¥ã«ä¿ãããããšãæå³ããŸãããã®åé¢ã«ãããæªæã®ãããµã€ããä»ã®ä¿¡é Œã§ãããµã€ãããã®æ©å¯æ å ±ã«ã¢ã¯ã»ã¹ããããå¹²æžãããããã®ãé²ããŸãã
æŽå²çã«ãLocal StorageãSession Storageã®ãããªWebã¹ãã¬ãŒãžã¡ã«ããºã ã¯ãåçŽãªããŒã»ããªã¥ãŒãã¢ã®ã¹ãã¬ãŒãžãæäŸããŠããŸãããå°éã®ããŒã¿ã«ã¯äŸ¿å©ã§ãããã¹ãã¬ãŒãžå®¹éãæ§é åããŒã¿ãŸãã¯ãã€ããªããŒã¿ãå¹ççã«æ±ãèœåã«ã¯éçããããŸããäžæ¹ãIndexedDBã¯ããã€ããªããããå«ã倧éã®æ§é åããŒã¿ã«å¯ŸããŠããã匷åãªãã©ã³ã¶ã¯ã·ã§ã³åã®ããŒã¿ããŒã¹ã®ãããªã¹ãã¬ãŒãžãæäŸããŸããããããIndexedDBã§ãããç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã«ãããããã©ãŒãã³ã¹ãéçºè ã®ãšã«ãŽããã¯ã¹ã«é¢ããŠãç¬èªã®èæ ®äºé ããããŸãã
ãã©ãŠã¶å ã§çŽæ¥ããã髿§èœã§æè»ãªãã¡ã€ã«ã·ã¹ãã ã®ãããªã¹ãã¬ãŒãžãœãªã¥ãŒã·ã§ã³ã®å¿ èŠæ§ããFile System Access APIã®ãããªAPIããããŠç¹ã«ãªãªãžã³ã«çŽã¥ãããŒã¿ã®ããã®Origin Private File Systemã®éçºã«ã€ãªãããŸããã
Origin Private File System (OPFS)ãšã¯äœãïŒ
Origin Private File System (OPFS)ã¯ãFile System Access APIã®é²å圢ã§ãããç¹ã«ãªãªãžã³ãã©ã€ããŒããªã¹ãã¬ãŒãžãæäŸããããã«èšèšãããŠããŸããããã¯ãOPFSå ã«äœæããããã¡ã€ã«ããã£ã¬ã¯ããªã¯ããããäœæãããªãªãžã³ããã®ã¿ã¢ã¯ã»ã¹å¯èœã§ããããšãæå³ããŸãããŠãŒã¶ãŒã«ããã€ã¹äžã®ãã£ã¬ã¯ããªãéžæããããä¿ãããšãã§ããåºç¯ãªFile System Access APIãšã¯ç°ãªããOPFSã¯ãã©ãŠã¶ãã³ããŒã«ãã£ãŠç®¡çãããããã©ãŠã¶ã®ãµã³ãããã¯ã¹åãããã¹ãã¬ãŒãžå ã§å®å šã«åäœããŸãã
OPFSã¯ãéçºè ãããã°ã©ã ã§ãã¡ã€ã«ããã£ã¬ã¯ããªãäœæãèªã¿åããæžã蟌ã¿ã管çã§ããã銎æã¿ã®ãããã¡ã€ã«ã·ã¹ãã ã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããŸããããã¯IndexedDBã®äžã«æ§ç¯ãããŠããŸãããããçŽæ¥çã§ãã¡ã€ã«ã©ã€ã¯ãªAPIãå ¬éããŠãããç¹å®ã®æäœãç¹ã«å€§ããªãã€ããªããŒã¿ãè€éãªãã¡ã€ã«æ§é ãæ±ãå Žåã«ãèããé«ãããã©ãŒãã³ã¹ãçºæ®ããããšããããŸãã
OPFSã®äž»ãªç¹åŸŽã¯ä»¥äžã®éãã§ãïŒ
- ãªãªãžã³ãã©ã€ããŒãïŒããŒã¿ã¯ãããäœæããç¹å®ã®ãªãªãžã³ã«åé¢ããããã©ã€ãã·ãŒãšã»ãã¥ãªãã£ã確ä¿ããŸãã
- ãã¡ã€ã«ã·ã¹ãã ã©ã€ã¯ãªAPIïŒåŸæ¥ã®ãã¡ã€ã«ã·ã¹ãã ãšåæ§ã«ããã¡ã€ã«ãšãã£ã¬ã¯ããªã管çããããã®æ§é åãããæ¹æ³ãæäŸããŸãã
- 髿§èœïŒç¹ã«ãã€ããªããŒã¿ã®é«éãªèªã¿æžãæäœã«æé©åãããŠããŸãã
- ãã©ãŠã¶ç®¡çïŒãã©ãŠã¶ãOPFSããŒã¿ã®åºç€ãšãªãã¹ãã¬ãŒãžãšç®¡çãåŠçããŸãã
- ãŠãŒã¶ãŒããã³ãããªãïŒFile System Access APIã®äžéšãšã¯ç°ãªããOPFSã¯ãªãªãžã³ã®æš©éå ã«ããããããã¡ã€ã«ãžã®ã¢ã¯ã»ã¹èš±å¯ãåŸãããã®ãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ãå¿ èŠãšããŸããã
OPFSã®åïŒã°ããŒãã«Webã¢ããªã±ãŒã·ã§ã³ãžã®ã¡ãªãã
ã°ããŒãã«ãªãŠãŒã¶ãŒããŒã¹ãæã€Webã¢ããªã±ãŒã·ã§ã³ã«ãšã£ãŠãOPFSã¯ããã€ãã®é åçãªå©ç¹ãæäŸããŸãïŒ
1. ããã©ãŒãã³ã¹ãšå¿çæ§ã®åäž
å ±åç·šéããŒã«ããªãã©ã€ã³ãã¡ãŒã¹ãã®çç£æ§åäžã¹ã€ãŒãããŸãã¯ã³ã³ãã³ããããŒãªãã©ãããã©ãŒã ãªã©ãå€ãã®ã°ããŒãã«ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãå€§èŠæš¡ãªããŒã¿ã»ããã®å¹ççãªåŠçãæ±ããããŸããOPFSã®çŽæ¥çãªãã¡ã€ã«ã·ã¹ãã ã¢ã¯ã»ã¹ã¯ãç¹å®ã®æäœã«ãããŠIndexedDBã®ãªããžã§ã¯ãã¹ãã¢ã¢ãã«ã«é¢é£ãããªãŒããŒãããã®äžéšãåé¿ããããšã§ãå€§å¹ ãªããã©ãŒãã³ã¹åäžã«ã€ãªããå¯èœæ§ããããŸãã
äŸïŒã°ããŒãã«ãªåçç·šéã¢ããªã±ãŒã·ã§ã³ãæ³åããŠã¿ãŠãã ããããŠãŒã¶ãŒã¯äœçŸãã®é«è§£å床ç»åãã¢ããããŒããããããããŸãããããããIndexedDBã«ããããšããŠä¿åãããšã·ãªã¢ã©ã€ãºãšãã·ãªã¢ã©ã€ãºãçºçããå¯èœæ§ããããŸãããOPFSã§ã¯çŽæ¥çãªãã¡ã€ã«æäœãå¯èœã§ããããã«ãããç»åã®èªã¿èŸŒã¿ãåŠçãä¿åã«ãããæéãåçã«ççž®ããããŠãŒã¶ãŒã®å°ççãªå Žæããããã¯ãŒã¯ç¶æ³ã«é¢ãããããããããããšããå¿çæ§ã®é«ããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãå®çŸããŸãã
2. ãªãã©ã€ã³æ©èœãšããŒã¿æ°žç¶æ§
ããã°ã¬ãã·ãWebã¢ããªïŒPWAïŒã¯ãæç¶çãªãããã¯ãŒã¯æ¥ç¶ã§ãæ©èœãæå¹ã«ããããšãã§ãããããã°ããŒãã«ãªãªãŒãã«ãšã£ãŠãŸããŸãéèŠã«ãªã£ãŠããŸããOPFSã¯ãå ç¢ãªãªãã©ã€ã³ãã¡ãŒã¹ãã®PWAãæ§ç¯ããããã®ã²ãŒã ãã§ã³ãžã£ãŒã§ãã
äŸïŒã°ããŒãã«ãªeã©ãŒãã³ã°ãã©ãããã©ãŒã ã§ã¯ãåŠçããªãã©ã€ã³åŠç¿ã®ããã«ææããããªãã€ã³ã¿ã©ã¯ãã£ããªæŒç¿ãããŠã³ããŒãã§ããããã«ããå¿ èŠããããŸããOPFSã䜿çšããŠããããã®ããŠã³ããŒããããã¢ã»ããããã©ãŠã¶å ã§æ§é åãããæ¹æ³ã§æŽçããããšãã§ããŸãããŠãŒã¶ãŒããªãã©ã€ã³ã®ãšããã¢ããªã±ãŒã·ã§ã³ã¯OPFSãããããã®ãã¡ã€ã«ã«ã·ãŒã ã¬ã¹ã«ã¢ã¯ã»ã¹ããŠæäŸããéåããããšã®ãªãåŠç¿ãä¿èšŒããŸããããã¯ãã€ã³ã¿ãŒãããã€ã³ãã©ãäžå®å®ãªå°åã«ãšã£ãŠæ¥µããŠéèŠã§ãã
3. å€§èŠæš¡ãã€ããªããŒã¿ã®å¹ççãªåãæ±ã
IndexedDBã¯ãã€ããªããŒã¿ïŒç»åãé³å£°ããããªãªã©ïŒã`Blob`ã`ArrayBuffer`ãªããžã§ã¯ããšããŠä¿åã§ããŸãããOPFSã¯ãããã®ã¿ã€ãã®ãã¡ã€ã«ãæ±ãããã®ããçŽæ¥çã§ããã°ãã°ãã髿§èœãªæ¹æ³ãæäŸããŸãã
äŸïŒäžçäžã®ãã¥ãŒãžã·ã£ã³ã䜿çšããWebããŒã¹ã®é³æ¥œå¶äœããŒã«ã¯ãå€§èŠæš¡ãªãªãŒãã£ãªãµã³ãã«ã©ã€ãã©ãªãæ±ãå¿ èŠããããããããŸãããOPFSã䜿çšãããšããããã®ã©ã€ãã©ãªãåå¥ã®ãã¡ã€ã«ãšããŠä¿åããã¢ã¯ã»ã¹ããããšãã§ããŸããç¹å®ã®æ¥œåšãµã³ãã«ãèªã¿èŸŒãããšã¯ãçŽæ¥çãªãã¡ã€ã«èªã¿åãæäœãšãªããIndexedDBãã倧ããªããããååŸããŠåŠçãããããã¯ããã«é«éã«ãªãå¯èœæ§ããããŸãããã®å¹çæ§ã¯ããªã¢ã«ã¿ã€ã ã®ãªãŒãã£ãªåŠçã«ãšã£ãŠäžå¯æ¬ ã§ãã
4. ãã¡ã€ã«æäœã«ãããéçºè ãšã«ãŽããã¯ã¹ã®åäž
åŸæ¥ã®ãã¡ã€ã«ã·ã¹ãã æäœã«æ £ããŠããéçºè ã«ãšã£ãŠãOPFSã¯ããçŽæçãªããã°ã©ãã³ã°ã¢ãã«ãæäŸããŸãã
äŸïŒæ§ã ãªããã¥ã¡ã³ãããŒãžã§ã³ãã¡ã¿ããŒã¿ãã¡ã€ã«ããããŠããããåã蟌ã¿ã¢ã»ããã管çããå¿ èŠãããWebããŒã¹ã®ããã¥ã¡ã³ããšãã£ã¿ãæ§ç¯ããéãOPFSã¯æç¢ºãªãã£ã¬ã¯ããªãšãã¡ã€ã«æ§é ãæäŸããŸããæ°ããããã¥ã¡ã³ãããŒãžã§ã³ãäœæããããšã¯ãæ°ãããã¡ã€ã«ããã£ã¬ã¯ããªãäœæããã³ã³ãã³ããæžã蟌ã¿ãã¡ã¿ããŒã¿ãæŽæ°ããããšãå«ã¿ãããã¯äžè¬çãªãã¡ã€ã«ã·ã¹ãã æäœã«çŽæ¥å¯Ÿå¿ããŸããããã«ãããåæ§ã®ã¿ã¹ã¯ã®ããã«IndexedDBå ã§è€éãªãªããžã§ã¯ãæ§é ã管çããå Žåãšæ¯èŒããŠã粟ç¥çãªãªãŒããŒããããåæžãããŸãã
5. ãã©ã€ãã·ãŒãšã»ãã¥ãªãã£ã®åŒ·å
OPFSã«åºæã®ãªãªãžã³ãã©ã€ããŒããªæ§è³ªã¯ãéèŠãªã»ãã¥ãªãã£äžã®å©ç¹ã§ããOPFSã«ä¿åãããããŒã¿ã¯ãåããŠãŒã¶ãŒã®ãã·ã³äžã§å®è¡ãããŠããä»ã®ãŠã§ããµã€ãããã¢ã¯ã»ã¹ããããšã¯ã§ããŸãããããã¯ããŠãŒã¶ãŒãé »ç¹ã«ç°ãªããŠã§ããµã€ãéãç§»åããã°ããŒãã«ãªãªã³ã©ã€ã³ç°å¢ã§ãŠãŒã¶ãŒããŒã¿ãä¿è·ããããã«äžå¯æ¬ ã§ãã
äŸïŒæ§ã ãªåœã®å人ã䜿çšãã財å管çã¢ããªã±ãŒã·ã§ã³ã¯ãæ©å¯æ§ã®é«ãååŒããŒã¿ãå®å šã«ä¿åããå¿ èŠããããŸããOPFSã䜿çšããããšã§ããã®æ©å¯ããŒã¿ã¯ã¢ããªã±ãŒã·ã§ã³ã®ãªãªãžã³ã«å³å¯ã«éå®ãããä»ã®ãªãªãžã³ããããŒã¿ã«ã¢ã¯ã»ã¹ããããšããå¯èœæ§ã®ããã¯ãã¹ãµã€ãã¹ã¯ãªããã£ã³ã°ïŒXSSïŒæ»æããä¿è·ãããŸãã
OPFSã®ã³ã¢ã³ã³ã»ãããšAPI
OPFS APIã¯ãäž»ã«window.showDirectoryPicker()
ãä»ããŠããŸãã¯navigator.storage.getDirectory()
ã䜿çšããŠãªãªãžã³ãã©ã€ããŒããã£ã¬ã¯ããªã«çŽæ¥ã¢ã¯ã»ã¹ããããšã«ãã£ãŠå©çšãããŸããåŸè
ã¯ããŠãŒã¶ãŒããã³ãããªãã®çã®ãªãªãžã³ãã©ã€ããŒãã¹ãã¬ãŒãžã®ããã®æšå¥šãããæ¹æ³ã§ãã
OPFSã®äž»ãªãšã³ããªãã€ã³ãã¯ããªãªãžã³ã®ãã©ã€ããŒããã¡ã€ã«ã¹ãã¬ãŒãžé åã衚ãã«ãŒããã£ã¬ã¯ããªã§ãããã®ã«ãŒãããããã£ã¬ã¯ããªãäœæããŠããã²ãŒããããã¡ã€ã«ãšå¯Ÿè©±ããããšãã§ããŸãã
ãªãªãžã³ãã©ã€ããŒããã£ã¬ã¯ããªãžã®ã¢ã¯ã»ã¹
OPFSãå§ããæãçŽæ¥çãªæ¹æ³ã¯ãnavigator.storage.getDirectory()
ã䜿çšããããšã§ãïŒ
async function getOpfsRoot() {
if (
'launchQueue' in window &&
'files' in window.launchQueue &&
'supported' in window.launchQueue.files &&
window.launchQueue.files.supported
) {
// Handle files launched from the OS (e.g., PWA files on Windows)
// This part is more advanced and relates to file launching, not direct OPFS root.
// For OPFS, we typically want the root directory directly.
}
// Check for browser support
if (!('storage' in navigator && 'getDirectory' in navigator.storage)) {
console.error('OPFS not supported in this browser.');
return null;
}
try {
const root = await navigator.storage.getDirectory();
console.log('Successfully obtained OPFS root directory:', root);
return root;
} catch (err) {
console.error('Error getting OPFS root directory:', err);
return null;
}
}
getOpfsRoot();
getDirectory()
ã¡ãœããã¯FileSystemDirectoryHandleãè¿ããŸããããã¯ãã£ã¬ã¯ããªãšå¯Ÿè©±ããããã®äž»èŠãªã€ã³ã¿ãŒãã§ãŒã¹ã§ããåæ§ã«ããã£ã¬ã¯ããªãã³ãã«äžã®getFileHandle()
ã¯åã
ã®ãã¡ã€ã«ã®ããã®FileSystemFileHandleãè¿ããŸãã
ãã¡ã€ã«ãšãã£ã¬ã¯ããªã®æäœ
ãã£ã¬ã¯ããªãã³ãã«ãååŸããããæ§ã ãªæäœãå®è¡ã§ããŸãïŒ
ãã£ã¬ã¯ããªã®äœæ
ãã£ã¬ã¯ããªãã³ãã«äžã§getDirectoryHandle()
ã¡ãœããã䜿çšããŠãæ¢åã®ãµããã£ã¬ã¯ããªãäœæãŸãã¯ååŸããŸãã
async function createSubdirectory(parentDirectoryHandle, dirName) {
try {
const subDirHandle = await parentDirectoryHandle.getDirectoryHandle(dirName, { create: true });
console.log(`Directory '${dirName}' created or accessed:`, subDirHandle);
return subDirHandle;
} catch (err) {
console.error(`Error creating/accessing directory '${dirName}':`, err);
return null;
}
}
// Example usage:
// const root = await getOpfsRoot();
// if (root) {
// const dataDir = await createSubdirectory(root, 'userData');
// }
ãã¡ã€ã«ãžã®äœæãšæžã蟌ã¿
getFileHandle()
ã䜿çšããŠãã¡ã€ã«ãã³ãã«ãååŸããæ¬¡ã«createWritable()
ã䜿çšããŠããŒã¿ãæžã蟌ãããã®æžã蟌ã¿å¯èœãªã¹ããªãŒã ãååŸããŸãã
async function writeToFile(directoryHandle, fileName, content) {
try {
const fileHandle = await directoryHandle.getFileHandle(fileName, { create: true });
const writable = await fileHandle.createWritable();
await writable.write(content);
await writable.close();
console.log(`Successfully wrote to '${fileName}':`, content);
} catch (err) {
console.error(`Error writing to file '${fileName}':`, err);
}
}
// Example usage:
// if (dataDir) {
// const userData = JSON.stringify({ userId: 123, name: 'Alice' });
// await writeToFile(dataDir, 'profile.json', userData);
// }
ãã¡ã€ã«ããã®èªã¿åã
getFileHandle()
ã䜿çšããæ¬¡ã«getFile()
ã䜿çšããŠFile
ãªããžã§ã¯ããååŸãããããèªã¿åãããšãã§ããŸãã
async function readFile(directoryHandle, fileName) {
try {
const fileHandle = await directoryHandle.getFileHandle(fileName);
const file = await fileHandle.getFile();
const content = await file.text(); // Or file.arrayBuffer() for binary data
console.log(`Content of '${fileName}':`, content);
return content;
} catch (err) {
console.error(`Error reading file '${fileName}':`, err);
return null;
}
}
// Example usage:
// if (dataDir) {
// const profileData = await readFile(dataDir, 'profile.json');
// }
ãã£ã¬ã¯ããªã®å 容äžèŠ§è¡šç€º
ãã£ã¬ã¯ããªãã³ãã«äžã§values()
ã€ãã¬ãŒã¿ã䜿çšããŠããã®å
容ãäžèŠ§è¡šç€ºããŸãã
async function listDirectory(directoryHandle) {
const entries = [];
for await (const entry of directoryHandle.values()) {
entries.push(entry.kind + ': ' + entry.name);
}
console.log(`Contents of directory '${directoryHandle.name}':`, entries);
return entries;
}
// Example usage:
// if (dataDir) {
// await listDirectory(dataDir);
// }
WebAssembly (Wasm)ã§ã®OPFSã®äœ¿çš
OPFSã®æã匷åãªãŠãŒã¹ã±ãŒã¹ã®1ã€ã¯ãWebAssembly (Wasm)ãšã®çµ±åã§ããWasmã䜿çšãããšãCãC++ãRustãªã©ã®èšèªããã³ã³ãã€ã«ãããã³ãŒãããã©ãŠã¶å ã§ã»ãŒãã€ãã£ãã®é床ã§å®è¡ã§ããŸããéäžçãªããŒã¿åŠçãè€éãªèšç®ãå¿ èŠãšããã¢ããªã±ãŒã·ã§ã³ã«ãšã£ãŠãOPFSã¯Wasmã¢ãžã¥ãŒã«ã®ããã®é«æ§èœãªã¹ãã¬ãŒãžããã¯ãšã³ããšããŠæ©èœããããšãã§ããŸãã
OPFSãå«ãFile System Access APIã¯ãWasmã¢ãžã¥ãŒã«ãç¹å®ã®ãã€ã³ãã£ã³ã°ãã©ã€ãã©ãªãä»ããŠãã©ãŠã¶ã®ãã¡ã€ã«ã·ã¹ãã ã«ã¢ã¯ã»ã¹ããããã®ã¡ã«ããºã ãæäŸããŸããããã«ãããæ¬¡ã®ãããªã·ããªãªãå¯èœã«ãªããŸãïŒ
- ãããªãšãã£ã¿ãCADãœãããŠã§ã¢ã®ãããªå®å šãªãã¹ã¯ãããã¯ã©ã¹ã®ã¢ããªã±ãŒã·ã§ã³ããã©ãŠã¶å ã§å®å šã«å®è¡ããOPFSã䜿çšããŠãããžã§ã¯ããã¡ã€ã«ãã¢ã»ãããä¿åããã
- OPFSã«ä¿åãããå€§èŠæš¡ãªããŒã¿ã»ããã«å¯ŸããŠã髿§èœãªããŒã¿åæãç§åŠèšç®ã¿ã¹ã¯ãå®è£ ããã
- ãã¡ã€ã«æäœãããŒã¿ããŒã¹æäœã®ããã®æ¢åã®Wasmã³ã³ãã€ã«æžã¿ã©ã€ãã©ãªã掻çšãããããOPFSã§åããã
äŸïŒã°ããŒãã«ãªç§åŠã·ãã¥ã¬ãŒã·ã§ã³ãã©ãããã©ãŒã ãèããŠã¿ãŸããããç ç©¶è ã¯å€§èŠæš¡ãªã·ãã¥ã¬ãŒã·ã§ã³ããŒã¿ãã¡ã€ã«ãã¢ããããŒãã§ããŸããFortranãCããã³ã³ãã€ã«ãããWasmã¢ãžã¥ãŒã«ã¯ããããã®ãã¡ã€ã«ãOPFSããçŽæ¥èªã¿åããè€éãªèšç®ãå®è¡ããçµæãOPFSã«æžãæ»ãããšãã§ããŸããããã«ãããJavaScriptããŒã¹ã®ãœãªã¥ãŒã·ã§ã³ãšæ¯èŒããŠåŠçé床ãåçã«åäžããããŒã¿ããŠãŒã¶ãŒã®ãã©ãŠã¶ã»ãã·ã§ã³å ã§å¹ççãã€ãã©ã€ããŒãã«ç®¡çãããããšãä¿èšŒãããŸãã
ã°ããŒãã«å±éã«ãããå®è·µçãªèæ ®äºé
OPFSã¯çµ¶å€§ãªåãæäŸããŸãããã°ããŒãã«å±éãæåãããããã«ã¯ããã€ãã®èŠå ãèæ ®ããå¿ èŠããããŸãïŒ
1. ãã©ãŠã¶ã®ãµããŒããšæ©èœæ€åº
OPFSã¯æ¯èŒçæ°ããAPIã§ãããµããŒãã¯æ¡å€§ããŠããŸãããã¢ããªã±ãŒã·ã§ã³ãããããµããŒãããŠããªããã©ãŠã¶ã§é©åã«æ©èœäœäžãããã代æ¿ãœãªã¥ãŒã·ã§ã³ãæäŸããããšãä¿èšŒããããã«ãå ç¢ãªæ©èœæ€åºãå®è£ ããããšãäžå¯æ¬ ã§ãã
å®çšçãªæŽå¯ïŒOPFSã䜿çšããããšããåã«ãåžžã«navigator.storage.getDirectory
ã®ååšã確èªããŠãã ãããOPFSãå©çšã§ããªãå Žåã¯ãããããIndexedDBããéèŠã§ãªãããŒã¿ã«ã¯ããåçŽãªã¹ãã¬ãŒãžã䜿çšãããªã©ãæç¢ºãªãã©ãŒã«ããã¯ã¡ã«ããºã ãæäŸããŠãã ããã
2. ã¹ãã¬ãŒãžã¯ã©ãŒã¿ãšãŠãŒã¶ãŒç®¡ç
ãã©ãŠã¶ã¯ãŠã§ããµã€ãã«ã¹ãã¬ãŒãžã¯ã©ãŒã¿ã課ããŸããOPFSã¯ãã倧ããªã¹ãã¬ãŒãžããŒãºã«å¯Ÿå¿ããããã«èšèšãããŠããŸãããç¡å¶éã§ã¯ãããŸãããæ£ç¢ºãªã¯ã©ãŒã¿ã¯ãã©ãŠã¶ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ãã£ãŠç°ãªãå ŽåããããŸãããŠãŒã¶ãŒã¯ã¹ãã¬ãŒãžã®èš±å¯ã管çãããµã€ãããŒã¿ãæ¶å»ããããšãã§ããŸãã
å®çšçãªæŽå¯ïŒãŠãŒã¶ãŒã«ã¹ãã¬ãŒãžäœ¿çšéã«ã€ããŠéç¥ããã¡ã«ããºã ãå®è£ ããŠãã ããããŠãŒã¶ãŒããã£ãã·ã¥ãããããŒã¿ãã¯ãªã¢ããããã¢ããªã±ãŒã·ã§ã³å ã«ä¿åããããã¡ã€ã«ã管çãããããããã®ãªãã·ã§ã³ãæäŸããããšãæ€èšããŠãã ããã倧éã®ããŒã¿ãæžã蟌ãããšããåã«ãå©çšå¯èœãªã¹ãã¬ãŒãžã¹ããŒã¹ã宿çã«ç¢ºèªããŠãã ããã
3. åæãšã¯ã©ãŠãçµ±å
OPFSã¯ããŒã«ã«ã®ã¯ã©ã€ã¢ã³ããµã€ãã¹ãã¬ãŒãžãæäŸããŸãããŠãŒã¶ãŒãè€æ°ã®ããã€ã¹ããããŒã¿ã«ã¢ã¯ã»ã¹ããããããã¯ã¢ãããå¿ èŠãšãããããã°ããŒãã«ã¢ããªã±ãŒã·ã§ã³ã®å Žåãã¯ã©ãŠããµãŒãã¹ãšããŒã¿ãåæããããã®æŠç¥ãå¿ èŠã«ãªããŸããããã«ã¯ãã«ã¹ã¿ã ã®ããã¯ãšã³ããœãªã¥ãŒã·ã§ã³ããã¯ã©ãŠãã¹ãã¬ãŒãžAPIãšã®çµ±åãå«ãŸããå ŽåããããŸãã
å®çšçãªæŽå¯ïŒåæã念é ã«çœ®ããŠããŒã¿ã¢ãã«ãèšèšããŠãã ãããè€æ°ã®ããã€ã¹ãåãããŒã¿ã倿Žã§ããå Žåã¯ãç«¶å解決æŠç¥ãå®è£ ããŠãã ãããUIããããã¯ããããšãªãããã¯ã°ã©ãŠã³ãã§åæã¿ã¹ã¯ãå®è¡ããããã«ããŠã§ãã¯ãŒã«ãŒã掻çšããŠãã ããã
4. ãã¡ã€ã«/ãã£ã¬ã¯ããªåã®åœéåïŒi18nïŒãšããŒã«ã©ã€ãºïŒl10nïŒ
OPFSèªäœã¯ãã¡ã€ã«ã·ã¹ãã ãªããžã§ã¯ããæ±ããŸãããäœæãããã¡ã€ã«ããã£ã¬ã¯ããªã®ååã¯åœéåã®æèã§èæ ®ãããã¹ãã§ãã
å®çšçãªæŽå¯ïŒãããã®ååã«å¯Ÿããå ç¢ãªi18næŠç¥ããªãéããèšèªåºæã®æåãçšèªãå«ããã¡ã€ã«åããã£ã¬ã¯ããªåãããŒãã³ãŒãã£ã³ã°ããããšã¯é¿ããŠãã ããããŠãŒã¶ãŒãçæããã³ã³ãã³ãããã¡ã€ã«åã圢æããå Žåã¯ã倿§ãªæåã»ããïŒäŸïŒUTF-8ïŒãæ±ãããã«ãé©åãªãµãã¿ã€ãºãšãšã³ã³ãŒãã£ã³ã°ã確å®ã«è¡ã£ãŠãã ããã
5. å°åããŸããã ããã©ãŒãã³ã¹ãããã¡ã€ãªã³ã°
OPFSã®å®éã®ããã©ãŒãã³ã¹ã¯ãåºç€ãšãªããã£ã¹ã¯é床ããã©ãŠã¶ã®å®è£ ãããã«ã¯ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®æé©åã«ãã£ãŠåœ±é¿ãåããå¯èœæ§ããããŸããã°ããŒãã«ãªãªãŒãã£ãšã³ã¹ã«å¯ŸããŠã¯ãæ§ã ãªå°åããããã©ãŒãã³ã¹ãã¹ãã宿œããããšãè³¢æã§ãã
å®çšçãªæŽå¯ïŒç°ãªãå°ççãªå Žæããã®ã¡ããªã¯ã¹ã远跡ã§ããããã©ãŒãã³ã¹ç£èŠããŒã«ã掻çšããŠãã ãããç¹å®ã®å°åããã©ãŠã¶/OSã®çµã¿åããã«ç¹æã®ããã©ãŒãã³ã¹ã®ããã«ããã¯ãç¹å®ããããã«å¿ããŠæé©åããŠãã ããã
ã·ããªãªäŸïŒã°ããŒãã«ãªããã¥ã¡ã³ãå ±åäœæ¥ããŒã«
ç°ãªã倧éžã®ããŒã ã«ãã£ãŠäœ¿çšãããWebããŒã¹ã®ããã¥ã¡ã³ãå ±åäœæ¥ããŒã«ãæ³åããŠã¿ãŸãããããã®ã¢ããªã±ãŒã·ã§ã³ã¯ã以äžã®ããšãè¡ãå¿ èŠããããŸãïŒ
- ãŠãŒã¶ãŒãããã¥ã¡ã³ããäœæããã³ç·šéã§ããããã«ããã
- ãªãã©ã€ã³ã¢ã¯ã»ã¹ã®ããã«ãããã¥ã¡ã³ãã®ã³ã³ãã³ããã¡ã¿ããŒã¿ãããŒãžã§ã³å±¥æŽãããŒã«ã«ã«ä¿åããã
- ããã¥ã¡ã³ãå ã§äœ¿çšãããç»åããã³ãã¬ãŒããªã©ã®å ±æã¢ã»ããããã£ãã·ã¥ããã
- 倿Žãäžå€®ãµãŒããŒãšåæããã
OPFSã®æŽ»çšæ¹æ³ïŒ
- ãããžã§ã¯ãæ§é ïŒã¢ããªã±ãŒã·ã§ã³ã¯OPFSã䜿çšããŠãåãããžã§ã¯ãã®ããã®æ§é åããããã£ã¬ã¯ããªãäœæã§ããŸããäŸãã°ããQ3 Marketing Campaignããšããååã®ãããžã§ã¯ãã¯ã
/projects/Q3_Marketing_Campaign/
ã®ãããªãã£ã¬ã¯ããªãæã€ããšãã§ããŸãã - ããã¥ã¡ã³ãã¹ãã¬ãŒãžïŒãããžã§ã¯ããã£ã¬ã¯ããªå
ã§ãåã
ã®ããã¥ã¡ã³ãã¯ãã¡ã€ã«ãšããŠä¿åã§ããŸããäŸïŒ
/projects/Q3_Marketing_Campaign/report.docx
ãããŒãžã§ã³å±¥æŽã¯ã/projects/Q3_Marketing_Campaign/report_v1.docx
ã/projects/Q3_Marketing_Campaign/report_v2.docx
ã®ããã«ãããŒãžã§ã³çªå·ãã¿ã€ã ã¹ã¿ã³ãä»ãã®æ°ãããã¡ã€ã«ãäœæããããšã§ç®¡çã§ããŸãã - ã¢ã»ãããã£ãã·ã³ã°ïŒããã¥ã¡ã³ãå
ã«åã蟌ãŸããç»åããã®ä»ã®ã¢ã»ããã¯ã
/projects/Q3_Marketing_Campaign/assets/logo.png
ã®ãããªå°çšã®ãassetsããµããã£ã¬ã¯ããªã«ä¿åã§ããŸãã - ãªãã©ã€ã³ã¢ã¯ã»ã¹ïŒãŠãŒã¶ãŒããªãã©ã€ã³ã«ãªããšãã¢ããªã±ãŒã·ã§ã³ã¯OPFSãããããã®ãã¡ã€ã«ãçŽæ¥èªã¿åã£ãŠããã¥ã¡ã³ãã衚瀺ããç·šéãèš±å¯ã§ããŸãã
- å¹ççãªæŽæ°ïŒå€æŽãå ããããŠä¿åããããšãOPFSã®
createWritable
APIã«ããããã¡ã€ã«ã®å¹ççãªäžæžãã远èšãå¯èœã«ãªããããŒã¿è»¢éãšåŠçæéãæå°éã«æããããŸãã - WebAssemblyçµ±åïŒããã¥ã¡ã³ãã®ã¬ã³ããªã³ã°ãããŒãžã§ã³æ¯èŒã®ããã®è€éãªå·®åã¢ã«ãŽãªãºã ãªã©ãèšç®éã®å€ãã¿ã¹ã¯ã«ã¯WebAssemblyã¢ãžã¥ãŒã«ã䜿çšããOPFSãã¡ã€ã«ã«çŽæ¥èªã¿æžãããããšãã§ããŸãã
ãã®ã¢ãããŒãã¯ãæ§ã ãªãããã¯ãŒã¯ç¶æ³ãçµéšããå¯èœæ§ã®ããã°ããŒãã«ããŒã ã«ãšã£ãŠäžå¯æ¬ ãªã髿§èœã§æŽçãããããªãã©ã€ã³å¯Ÿå¿ã®ã¹ãã¬ãŒãžãœãªã¥ãŒã·ã§ã³ãæäŸããŸãã
OPFSãšWebã¹ãã¬ãŒãžã®æªæ¥
Origin Private File Systemã¯ãWebã¢ããªã±ãŒã·ã§ã³ã«å ç¢ãªã¯ã©ã€ã¢ã³ããµã€ãã®ããŒã¿ç®¡çæ©èœãäžããäžã§ã倧ããªäžæ©ãæå³ããŸãããã©ãŠã¶ãã³ããŒããããã®APIãæ¹è¯ããæ¡åŒµãç¶ããã«ã€ããŠãããã«æŽç·ŽããããŠãŒã¹ã±ãŒã¹ãç»å ŽããããšãæåŸ ãããŸãã
ãã¬ã³ãã¯ãæ©èœãšããã©ãŒãã³ã¹ã®é¢ã§ãã¹ã¯ãããã¢ããªã±ãŒã·ã§ã³ã«å¹æµããããšãã§ããWebã¢ããªã±ãŒã·ã§ã³ã«åãã£ãŠããŸããOPFSã¯ãç¹ã«WebAssemblyãšçµã¿åãããããšã§ããã®ããžã§ã³ã®äž»èŠãªå®çŸèŠå ãšãªããŸããã°ããŒãã«åãã®Webã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããéçºè ã«ãšã£ãŠãOPFSãçè§£ããæŠç¥çã«å®è£ ããããšã¯ãåè¶ãããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæäŸãããªãã©ã€ã³æ©èœã匷åãã倿§ãªãŠãŒã¶ãŒç°å¢å šäœã§å¹ççãªããŒã¿åŠçãä¿èšŒããããã«äžå¯æ¬ ã§ãã
WebããŸããŸã髿©èœã«ãªãã«ã€ããŠããã©ãŠã¶å ã§ããŒã«ã«ã«å®å šã«ããŒã¿ã管çããèœåã®éèŠæ§ã¯å¢ãã°ããã§ããOPFSã¯ãã®åãã®æåç·ã«ãããæ¬¡äžä»£ã®åŒ·åã§é«æ§èœãªããŠãŒã¶ãŒäžå¿ã®Webãšã¯ã¹ããªãšã³ã¹ãäžçäžã§æäŸããããã®åºç€ãç¯ããŠããŸãã
çµè«
Origin Private File System (OPFS)ã¯ãçŸä»£ã®Webéçºãç¹ã«ã°ããŒãã«ãªãªãŒãã£ãšã³ã¹ã察象ãšããã¢ããªã±ãŒã·ã§ã³ã«ãšã£ãŠã匷åã§äžå¯æ¬ ãªAPIã§ããåé¢ãããã髿§èœãªããã¡ã€ã«ã·ã¹ãã ã©ã€ã¯ãªã¹ãã¬ãŒãžãæäŸããããšã§ãOPFSã¯ãªãã©ã€ã³æ©èœãè€éãªããŒã¿ç®¡çããããŠåŒ·åããããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã®ããã®æ°ããªå¯èœæ§ãè§£ãæŸã¡ãŸããWebAssemblyãšã®ã·ãŒã ã¬ã¹ãªçµ±åã¯ããã®ããã³ã·ã£ã«ãããã«å¢å¹ ããããã©ãŠã¶å ã§çŽæ¥ãã¹ã¯ãããã¯ã©ã¹ã®ããã©ãŒãã³ã¹ãå¯èœã«ããŸãã
åœéçãªWebã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããæ¹è¯ããéã«ã¯ãOPFSãããŒã¿ã¹ãã¬ãŒãžã®ããŒãºã«ã©ã®ããã«å¯ŸåŠã§ããããæ€èšããŠãã ããããã®èœåãæŽ»çšããŠãäžçäžã®ãŠãŒã¶ãŒãåã°ãããããå¿çæ§ãé«ããå埩åããããæ©èœè±å¯ãªãšã¯ã¹ããªãšã³ã¹ãåµé ããŠãã ããã