File System Access API: 로컬 파일 액세스 간소화

File System Access API를 사용하면 웹 앱이 사용자 기기의 파일 및 폴더를 직접 읽거나 저장할 수 있습니다.

File System Access API란 무엇인가요?

개발자는 File System Access API를 사용하여 상호 작용하는 강력한 웹 앱을 구축할 수 있습니다. IDE, 사진 및 동영상 편집기, 텍스트 편집기 등 사용자의 로컬 기기에 있는 파일. 후(After) 이 API를 사용하면 사용자가 웹 앱에 액세스 권한을 부여하여 파일에 직접 변경사항을 읽거나 저장할 수 사용자 기기의 폴더에 저장됩니다. 파일 읽기 및 쓰기 외에도 File System Access API는 디렉터리를 열고 그 콘텐츠를 열거하는 기능

이전에 파일 읽기 및 쓰기 작업을 해보셨다면 이제 공유할 내용은 대부분 익숙하실 것입니다. 모든 시스템이 서로 다르므로 읽어 보시기 바랍니다.

File System Access API는 Windows, macOS, ChromeOS, Linux 주목할 만한 예외로는 현재 플래그에서만 사용할 수 있습니다. Android 지원은 crbug.com/1011535에서 개발 중입니다.

File System Access API 사용

File System Access API의 성능과 유용성을 자랑하기 위해 단일 파일 텍스트를 작성했습니다. 편집기를 사용합니다. 텍스트 파일을 열거나 수정하거나, 변경사항을 디스크에 다시 저장하거나, 새 파일을 만들고 변경사항을 디스크에 저장합니다 복잡하지는 않지만 도움이 될 만한 정보를 제공합니다. 이해할 수 있을 것입니다.

브라우저 지원

브라우저 지원

  • Chrome: 86 <ph type="x-smartling-placeholder">
  • Edge: 86. <ph type="x-smartling-placeholder">
  • Firefox: 지원되지 않음 <ph type="x-smartling-placeholder">
  • Safari: 지원되지 않음 <ph type="x-smartling-placeholder">

소스

특성 감지

File System Access API가 지원되는지 확인하려면 선택 도구 메서드가 존재하는지 확인할 수 있습니다.

if ('showOpenFilePicker' in self) {
  // The `showOpenFilePicker()` method of the File System Access API is supported.
}

직접 해 보기

File System Access API의 실제 작동 방식 보기 텍스트 편집기 데모입니다.

로컬 파일 시스템에서 파일 읽기

제가 먼저 다루고 싶은 사용 사례는 사용자에게 파일을 선택하라고 요청한 다음 파일을 열어 읽는 것입니다. 삭제할 수도 있습니다

사용자에게 읽을 파일을 선택하도록 요청

File System Access API의 진입점은 window.showOpenFilePicker() 호출하면 파일 선택 도구 대화상자가 표시됩니다. 사용자에게 파일을 선택하라는 메시지를 표시합니다. 파일을 선택하면 API가 있습니다. 선택사항인 options 매개변수를 사용하면 파일 선택 도구의 동작에 영향을 줄 수 있습니다. 예를 들어 사용자가 여러 파일, 디렉터리 또는 다른 파일 형식을 선택할 수 있습니다. 옵션을 지정하지 않으면 파일 선택 도구에서 사용자가 단일 파일을 선택할 수 있습니다. 이것은 텍스트 편집기에 적합합니다.

다른 여러 강력한 API와 마찬가지로 showOpenFilePicker() 호출은 안전한 API 컨텍스트를 따라야 하며 사용자 동작 내에서 호출되어야 합니다.

let fileHandle;
butOpenFile.addEventListener('click', async () => {
  // Destructure the one-element array.
  [fileHandle] = await window.showOpenFilePicker();
  // Do something with the file handle.
});

사용자가 파일을 선택하면 showOpenFilePicker()가 핸들 배열을 반환합니다. 이 경우 및 다음 속성을 포함하는 하나의 FileSystemFileHandle가 있는 단일 요소 배열 메서드를 제공합니다.

나중에 사용할 수 있도록 파일 핸들에 대한 참조를 유지하는 것이 좋습니다. 예: 파일 변경 사항을 저장하거나 다른 파일 작업을 수행하기 위해 필요한 모든 API를 제공합니다.

파일 시스템에서 파일 읽기

이제 파일에 대한 핸들이 있으므로 파일의 속성을 가져오거나 파일 자체에 액세스할 수 있습니다. 지금은 콘텐츠를 읽어 보겠습니다. handle.getFile()를 호출하면 File이 반환됩니다. 객체에는 blob이 포함됩니다 blob에서 데이터를 가져오려면 메서드, (slice(), stream(), text() 또는 arrayBuffer())

const file = await fileHandle.getFile();
const contents = await file.text();
드림

FileSystemFileHandle.getFile()에서 반환된 File 객체는 기본 파일이 변경되지 않았는지 확인합니다 디스크의 파일이 수정되면 File 객체가 다음과 같이 됩니다. 읽을 수 없으며 getFile()를 다시 호출하여 변경사항을 읽을 새 File 객체를 가져와야 합니다. 데이터를 수집하는 데 사용됩니다

요약 정리

사용자가 Open(열기) 버튼을 클릭하면 브라우저에 파일 선택 도구가 표시됩니다. 파일을 선택하면 앱이 콘텐츠를 읽고 <textarea>에 넣습니다.

let fileHandle;
butOpenFile.addEventListener('click', async () => {
  [fileHandle] = await window.showOpenFilePicker();
  const file = await fileHandle.getFile();
  const contents = await file.text();
  textArea.value = contents;
});

로컬 파일 시스템에 파일 쓰기

텍스트 편집기에서는 저장다른 이름으로 저장, 두 가지 방법으로 파일을 저장할 수 있습니다. 저장 이전에 검색한 파일 핸들을 사용하여 변경사항을 원본 파일에 다시 씁니다. 하지만 저장 As는 새 파일을 만들므로 새 파일 핸들이 필요합니다.

새 파일 만들기

파일을 저장하려면 파일 선택 도구를 표시하는 showSaveFilePicker()를 호출합니다. '저장'에서 사용자가 저장에 사용할 새 파일을 선택할 수 있습니다. 텍스트 편집기에 .txt 확장 프로그램을 자동으로 추가하기 위해 매개변수입니다.

async function getNewFileHandle() {
  const options = {
    types: [
      {
        description: 'Text Files',
        accept: {
          'text/plain': ['.txt'],
        },
      },
    ],
  };
  const handle = await window.showSaveFilePicker(options);
  return handle;
}
드림

디스크에 변경사항 저장

파일의 변경사항을 저장하는 데 필요한 모든 코드는 다음 페이지의 텍스트 편집기 데모에서 찾을 수 있습니다. GitHub 핵심 파일 시스템 상호작용은 fs-helpers.js 간단히 말하면 이 프로세스는 다음 코드와 같습니다. 각 단계를 진행하면서 설명해 드리겠습니다.

// fileHandle is an instance of FileSystemFileHandle..
async function writeFile(fileHandle, contents) {
  // Create a FileSystemWritableFileStream to write to.
  const writable = await fileHandle.createWritable();
  // Write the contents of the file to the stream.
  await writable.write(contents);
  // Close the file and write the contents to disk.
  await writable.close();
}

디스크에 데이터를 쓸 때 서브클래스인 FileSystemWritableFileStream 객체를 사용합니다. (WritableStream) 파일에서 createWritable()를 호출하여 스트림을 만듭니다. 핸들 객체를 생성할 수 있습니다. createWritable()가 호출되면 브라우저에서 먼저 사용자가 파일에 대한 쓰기 권한 쓰기 권한이 부여되지 않은 경우 브라우저에 사용자에게 권한을 요청합니다. 권한이 부여되지 않으면 createWritable()에서 DOMException가 되면 앱이 파일에 쓸 수 없게 됩니다. 텍스트 편집기에서 DOMException 객체는 saveFile() 메서드에서 처리됩니다.

write() 메서드는 텍스트 편집기에 필요한 문자열을 사용합니다. 그러나 BufferSource 또는 Blob. 예를 들어, 스트림을 다음과 같습니다.

async function writeURLToFile(fileHandle, url) {
  // Create a FileSystemWritableFileStream to write to.
  const writable = await fileHandle.createWritable();
  // Make an HTTP request for the contents.
  const response = await fetch(url);
  // Stream the response into the file.
  await response.body.pipeTo(writable);
  // pipeTo() closes the destination pipe by default, no need to close it.
}

seek() 또는 스트림 내에서 truncate()를 클릭하여 파일을 특정 위치에 배치하거나 파일 크기를 조절할 수 있습니다.

추천 파일 이름 및 시작 디렉터리 지정

대부분의 경우 앱에서 기본 파일 이름이나 위치를 제안하도록 할 수 있습니다. 예를 들어 편집기에서 Untitled 대신 Untitled Text.txt의 기본 파일 이름을 제안하는 것이 좋습니다. 나 showSaveFilePicker 옵션의 일부로 suggestedName 속성을 전달하여 이를 달성할 수 있습니다.

const fileHandle = await self.showSaveFilePicker({
  suggestedName: 'Untitled Text.txt',
  types: [{
    description: 'Text documents',
    accept: {
      'text/plain': ['.txt'],
    },
  }],
});

기본 시작 디렉터리도 마찬가지입니다. 텍스트 편집기를 빌드하는 경우 기본 documents 폴더에서 파일 저장 또는 파일 열기 대화상자를 시작하는 반면 이미지의 경우 편집기의 경우 기본 pictures 폴더에서 시작하는 것이 좋습니다. 기본 시작 시간을 제안할 수 있습니다. startIn 속성을 showSaveFilePicker, showDirectoryPicker() 또는 showOpenFilePicker 메서드와 비슷합니다.

const fileHandle = await self.showOpenFilePicker({
  startIn: 'pictures'
});

잘 알려진 시스템 디렉터리의 목록은 다음과 같습니다.

  • desktop: 사용자의 데스크톱 디렉터리(있는 경우)
  • documents: 일반적으로 사용자가 만든 문서가 저장되는 디렉터리입니다.
  • downloads: 일반적으로 다운로드된 파일이 저장되는 디렉터리입니다.
  • music: 오디오 파일이 일반적으로 저장되는 디렉터리입니다.
  • pictures: 사진 및 기타 정지 이미지가 일반적으로 저장되는 디렉터리입니다.
  • videos: 동영상 또는 영화가 일반적으로 저장되는 디렉터리입니다.

잘 알려진 시스템 디렉터리 외에도 기존 파일이나 디렉터리 핸들을 startIn의 값입니다. 그러면 대화상자가 동일한 디렉터리에서 열립니다.

// Assume `directoryHandle` is a handle to a previously opened directory.
const fileHandle = await self.showOpenFilePicker({
  startIn: directoryHandle
});

다양한 파일 선택 도구의 용도 지정

애플리케이션의 용도가 다른 선택 도구를 사용하는 경우가 있습니다. 예를 들어, 편집기를 사용하면 텍스트 파일을 열 수 있을 뿐만 아니라 이미지를 가져올 수도 있습니다. 기본적으로 각 파일은 마지막으로 저장된 위치에서 선택 도구가 열립니다. id 값을 저장하여 이를 우회할 수 있습니다. 를 사용합니다. id가 지정되면 파일 선택 도구 구현은 다음을 기억합니다. 해당 id에 마지막으로 사용한 별도의 디렉터리를 제공합니다.

const fileHandle1 = await self.showSaveFilePicker({
  id: 'openText',
});

const fileHandle2 = await self.showSaveFilePicker({
  id: 'importImage',
});

파일 핸들 또는 디렉터리 핸들을 IndexedDB에 저장

파일 핸들과 디렉터리 핸들은 직렬화 가능합니다. 즉, 파일을 저장하거나 디렉터리 핸들을 IndexedDB로 이동하거나 postMessage()를 호출하여 동일한 최상위 수준 간에 전송합니다. 출처입니다.

파일이나 디렉터리 핸들을 IndexedDB에 저장하면 상태를 저장하거나 어떤 작업을 수행할지 사용자가 작업 중이던 파일 또는 디렉토리를 확인할 수 있습니다. 이렇게 하면 최근에 연 목록을 유지할 수 있습니다. 또는 수정한 파일, 앱을 열 때 마지막 파일을 다시 열도록 제안, 이전 작업 복원 디렉터리 등이 있습니다 사용자가 보유한 가장 최근 파일 5개의 목록을 텍스트 편집기에 저장합니다. 해당 파일에 다시 액세스할 수 있습니다.

다음 코드 예에서는 파일 핸들과 디렉터리 핸들을 저장하고 검색하는 방법을 보여줍니다. 다음과 같은 작업을 할 수 있습니다. 실제 사례 보기 ( 간결성을 위해 idb-keyval 라이브러리를 사용하세요.)

import { get, set } from 'https://unpkg.com/idb-keyval@5.0.2/dist/esm/index.js';

const pre1 = document.querySelector('pre.file');
const pre2 = document.querySelector('pre.directory');
const button1 = document.querySelector('button.file');
const button2 = document.querySelector('button.directory');

// File handle
button1.addEventListener('click', async () => {
  try {
    const fileHandleOrUndefined = await get('file');
    if (fileHandleOrUndefined) {
      pre1.textContent = `Retrieved file handle "${fileHandleOrUndefined.name}" from IndexedDB.`;
      return;
    }
    const [fileHandle] = await window.showOpenFilePicker();
    await set('file', fileHandle);
    pre1.textContent = `Stored file handle for "${fileHandle.name}" in IndexedDB.`;
  } catch (error) {
    alert(error.name, error.message);
  }
});

// Directory handle
button2.addEventListener('click', async () => {
  try {
    const directoryHandleOrUndefined = await get('directory');
    if (directoryHandleOrUndefined) {
      pre2.textContent = `Retrieved directroy handle "${directoryHandleOrUndefined.name}" from IndexedDB.`;
      return;
    }
    const directoryHandle = await window.showDirectoryPicker();
    await set('directory', directoryHandle);
    pre2.textContent = `Stored directory handle for "${directoryHandle.name}" in IndexedDB.`;
  } catch (error) {
    alert(error.name, error.message);
  }
});

저장된 파일 또는 디렉터리 핸들 및 권한

세션 간에 권한이 유지되지 않는 경우도 있으므로 사용자가 이(가) queryPermission()을 사용하여 파일 또는 디렉터리에 권한을 부여했습니다. 표시되지 않으면 requestPermission()하여 (다시) 요청합니다. 파일 및 디렉터리 핸들에서도 동일하게 작동합니다. 나 fileOrDirectoryHandle.requestPermission(descriptor)를 실행하거나 각각 fileOrDirectoryHandle.queryPermission(descriptor)입니다.

텍스트 편집기에서 사용자가 이미 사용 중인지 확인하는 verifyPermission() 메서드를 만들었습니다. 필요한 경우 요청을 수행합니다.

async function verifyPermission(fileHandle, readWrite) {
  const options = {};
  if (readWrite) {
    options.mode = 'readwrite';
  }
  // Check if permission was already granted. If so, return true.
  if ((await fileHandle.queryPermission(options)) === 'granted') {
    return true;
  }
  // Request permission. If the user grants permission, return true.
  if ((await fileHandle.requestPermission(options)) === 'granted') {
    return true;
  }
  // The user didn't grant permission, so return false.
  return false;
}

읽기 요청과 함께 쓰기 권한을 요청하여 권한 요청 메시지 수를 줄였습니다. 사용자가 파일을 열 때 메시지 하나가 표시되고 읽기 및 쓰기 권한을 모두 부여합니다.

디렉터리 열기 및 디렉터리의 콘텐츠 열거

디렉터리의 모든 파일을 열거하려면 showDirectoryPicker()를 호출합니다. 사용자 선택도구에서 디렉터리를 선택한 후 FileSystemDirectoryHandle가 반환되어 디렉터리의 파일을 열거하고 액세스할 수 있습니다. 기본적으로 읽기 자료는 액세스할 수 없지만, 쓰기 권한이 필요한 경우 { mode: 'readwrite' }를 메서드에 추가합니다.

butDir.addEventListener('click', async () => {
  const dirHandle = await window.showDirectoryPicker();
  for await (const entry of dirHandle.values()) {
    console.log(entry.kind, entry.name);
  }
});

예를 들어 개별 파일을 가져오기 위해 getFile()를 사용하여 각 파일에 추가로 액세스해야 하는 경우 각 결과에 await를 순차적으로 사용하지 말고 병렬(예: Promise.all() 사용)

butDir.addEventListener('click', async () => {
  const dirHandle = await window.showDirectoryPicker();
  const promises = [];
  for await (const entry of dirHandle.values()) {
    if (entry.kind !== 'file') {
      continue;
    }
    promises.push(entry.getFile().then((file) => `${file.name} (${file.size})`));
  }
  console.log(await Promise.all(promises));
});

디렉터리에 파일 및 폴더 만들기 또는 액세스

디렉터리에서 getFileHandle() 또는 각각 getDirectoryHandle() 메서드를 사용하여 축소하도록 요청합니다. 키가 create이고 불리언 값이인 선택적 options 객체를 전달합니다. true 또는 false로 설정한 경우, 존재하지 않는 경우 새 파일이나 폴더를 만들어야 하는지 결정할 수 있습니다.

// In an existing directory, create a new directory named "My Documents".
const newDirectoryHandle = await existingDirectoryHandle.getDirectoryHandle('My Documents', {
  create: true,
});
// In this new directory, create a file named "My Notes.txt".
const newFileHandle = await newDirectoryHandle.getFileHandle('My Notes.txt', { create: true });

디렉터리의 항목 경로 확인

디렉터리의 파일이나 폴더로 작업할 때 항목의 경로를 확인하는 것이 유용할 수 있습니다. 있습니다. 이 작업은 적절한 이름의 resolve() 메서드를 사용하여 실행할 수 있습니다. 이 문제를 해결하기 위해 항목은 디렉터리의 직속 또는 간접 하위 요소일 수 있습니다.

// Resolve the path of the previously created file called "My Notes.txt".
const path = await newDirectoryHandle.resolve(newFileHandle);
// `path` is now ["My Documents", "My Notes.txt"]

디렉터리에서 파일 및 폴더 삭제

디렉터리에 대한 액세스 권한을 취득한 경우 포함된 파일과 폴더를 removeEntry() 메서드를 사용하여 지도 가장자리에 패딩을 추가할 수 있습니다. 폴더의 경우 삭제는 선택적으로 재귀적일 수 있으며 다음을 포함합니다. 모든 하위 폴더와 그 안에 있는 파일

// Delete a file.
await directoryHandle.removeEntry('Abandoned Projects.txt');
// Recursively delete a folder.
await directoryHandle.removeEntry('Old Stuff', { recursive: true });

파일 또는 폴더 직접 삭제

파일 또는 디렉터리 핸들에 액세스할 수 있는 경우 remove() FileSystemFileHandle 또는 FileSystemDirectoryHandle하여 삭제합니다.

// Delete a file.
await fileHandle.remove();
// Delete a directory.
await directoryHandle.remove();

파일 및 폴더 이름 바꾸기 및 이동

다음에서 move()를 호출하여 파일과 폴더의 이름을 바꾸거나 새 위치로 이동할 수 있습니다. FileSystemHandle 인터페이스 FileSystemHandle에는 하위 인터페이스 FileSystemFileHandleFileSystemDirectoryHandle입니다. move() 메서드는 하나 또는 두 개의 매개변수를 사용합니다. 첫 번째는 새 이름이 있는 문자열 또는 대상 폴더의 FileSystemDirectoryHandle일 수 있습니다. 후자의 경우 선택적인 두 번째 매개변수는 새 이름을 가진 문자열이므로 이동 및 이름 바꾸기를 통해 한 번에 발생합니다

// Rename the file.
await file.move('new_name');
// Move the file to a new directory.
await file.move(directory);
// Move the file to a new directory and rename it.
await file.move(directory, 'newer_name');
드림

드래그 앤 드롭 통합

HTML 드래그 앤 드롭 인터페이스 웹 애플리케이션이 드래그 앤 드롭된 파일 표시됩니다. 드래그 앤 드롭 작업 중에 드래그한 파일 및 디렉터리 항목이 연결됩니다. 각각 파일 항목과 디렉토리 항목으로 구성됩니다. DataTransferItem.getAsFileSystemHandle() 드래그한 항목이 파일인 경우 메서드는 FileSystemFileHandle 객체를 포함하는 프로미스를 반환하고 드래그한 항목이 디렉터리인 경우 FileSystemDirectoryHandle 객체로 프라미스를 표시합니다. 다음 등록정보 예를 살펴보겠습니다 드래그 앤 드롭 인터페이스의 경우 DataTransferItem.kind: 파일 디렉터리 모두에 "file"가 사용되는 반면, File System Access API의 FileSystemHandle.kind는 파일의 경우 "file", 디렉터리의 경우 "directory"

elem.addEventListener('dragover', (e) => {
  // Prevent navigation.
  e.preventDefault();
});

elem.addEventListener('drop', async (e) => {
  e.preventDefault();

  const fileHandlesPromises = [...e.dataTransfer.items]
    .filter((item) => item.kind === 'file')
    .map((item) => item.getAsFileSystemHandle());

  for await (const handle of fileHandlesPromises) {
    if (handle.kind === 'directory') {
      console.log(`Directory: ${handle.name}`);
    } else {
      console.log(`File: ${handle.name}`);
    }
  }
});

원본 비공개 파일 시스템 액세스

원본 비공개 파일 시스템은 이름에서 알 수 있듯이 확인할 수 있습니다. 브라우저는 일반적으로 이 원본 비공개 파일 시스템을 어딘가에 있는 디스크로 배포하는 경우, 콘텐츠가 사용자 역할을 하도록 의도된 것은 아닙니다. 있습니다. 마찬가지로 이름이 일치하는 파일이나 디렉터리는 원본 비공개 파일 시스템의 하위 요소 이름이 있는지 확인합니다. 브라우저는 사용자가 원본 개인 파일 시스템이기 때문에 내부적으로는 파일이 있습니다. 브라우저는 이러한 '파일'을 특정 데이터 포인트에 표시될 수 있습니다 기본적으로 이 API를 사용하면 생성된 파일이 하드 디스크의 어딘가에서 일대일로 일치할 것이라고 예상하지 않습니다. 다음에서 평소처럼 작동할 수 있습니다. 루트 FileSystemDirectoryHandle에 대한 액세스 권한이 부여되면 원본 비공개 파일 시스템에 복원해야 합니다.

const root = await navigator.storage.getDirectory();
// Create a new file handle.
const fileHandle = await root.getFileHandle('Untitled.txt', { create: true });
// Create a new directory handle.
const dirHandle = await root.getDirectoryHandle('New Folder', { create: true });
// Recursively remove a directory.
await root.removeEntry('Old Stuff', { recursive: true });

브라우저 지원

  • Chrome: 86 <ph type="x-smartling-placeholder">
  • Edge: 86. <ph type="x-smartling-placeholder">
  • Firefox: 111 <ph type="x-smartling-placeholder">
  • Safari 15.2. <ph type="x-smartling-placeholder">

소스

원본 비공개 파일 시스템에서 성능에 최적화된 파일 액세스

원본 비공개 파일 시스템은 고도로 민감한 특수 종류의 파일에 대한 선택적 액세스를 제공합니다. 예를 들어 파일의 기본 파일에 대한 인플레이스 및 독점 쓰기 액세스를 제공하여 성능에 최적화됩니다. 있습니다. Chromium 102 이상에는 파일 액세스 간소화: createSyncAccessHandle() (동기식 읽기 및 쓰기 작업용) FileSystemFileHandle에 노출되지만 다음에만 노출됩니다. 웹 작업자.

// (Read and write operations are synchronous,
// but obtaining the handle is asynchronous.)
// Synchronous access exclusively in Worker contexts.
const accessHandle = await fileHandle.createSyncAccessHandle();
const writtenBytes = accessHandle.write(buffer);
const readBytes = accessHandle.read(buffer, { at: 1 });
드림

폴리필링

File System Access API 메서드를 완전히 폴리필하는 것은 불가능합니다.

  • showOpenFilePicker() 메서드는 <input type="file"> 요소를 사용하여 근사치를 구할 수 있습니다.
  • showSaveFilePicker() 메서드는 <a download="file_name"> 요소로 시뮬레이션할 수 있습니다. 그러나 이렇게 하면 프로그램 방식의 다운로드가 트리거되고 기존 파일을 덮어쓰지 않습니다.
  • showDirectoryPicker() 메서드는 비표준 <input type="file" webkitdirectory> 요소

Google은 파일 계층 구조를 사용하는 browser-fs-access라는 가능한 경우 System Access API를 활용하며, 기타 모든 솔루션에서 차선의 옵션으로 대체됩니다. 있습니다.

보안 및 권한

Chrome팀은 핵심 원칙을 사용하여 File System Access API를 설계하고 구현했습니다. 강력한 웹 플랫폼 기능에 대한 액세스 제어에 정의됨(사용자 포함) 관리 및 투명성, 사용자 인체공학을 고려했습니다.

파일 열기 또는 새 파일 저장하기

<ph type="x-smartling-placeholder">
</ph> 읽기 위해 파일을 여는 파일 선택 도구 <ph type="x-smartling-placeholder">
</ph> 읽기 위해 기존 파일을 여는 데 사용되는 파일 선택기입니다.

사용자는 파일을 열 때 파일 선택기를 사용하여 파일 또는 디렉터리를 읽을 수 있는 권한을 제공합니다. 열린 파일 선택기는 보안 컨텍스트를 참고하세요. 사용자가 마음이 바뀌면 파일에서 선택사항을 취소할 수 있습니다. 사이트가 아무 액세스 권한도 얻지 못합니다. 이 동작은 <input type="file"> 요소

<ph type="x-smartling-placeholder">
</ph> 디스크에 파일을 저장할 파일 선택 도구입니다. <ph type="x-smartling-placeholder">
</ph> 디스크에 파일을 저장하는 데 사용되는 파일 선택 도구입니다.

마찬가지로 웹 앱이 새 파일을 저장하려고 하면 브라우저에 파일 저장 선택 도구가 표시됩니다. 사용자가 새 파일의 이름과 위치를 지정할 수 있습니다. 새 파일을 저장하고 있으므로 기존 파일을 덮어쓰는 것과 달리 파일 선택기는 앱에 있습니다

제한된 폴더

사용자 및 데이터를 보호하기 위해 브라우저에서는 사용자가 특정 예를 들어 Windows와 같은 핵심 운영 체제 폴더나 macOS Library 폴더 등에서 찾을 수 있습니다. 이 경우 브라우저에 메시지가 표시되고 사용자에게 다른 있습니다.

기존 파일 또는 디렉터리 수정

웹 앱은 사용자로부터 명시적 권한을 얻지 않고는 디스크의 파일을 수정할 수 없습니다.

권한 메시지

사용자가 이전에 읽기 액세스 권한을 부여했던 파일의 변경사항을 저장하려는 경우 브라우저에서 사이트의 변경사항을 디스크에 쓸 수 있는 권한을 요청하는 권한 메시지가 표시됩니다. 권한 요청은 사용자 동작(예: 저장 버튼 클릭)에 의해서만 트리거될 수 있습니다. 버튼을 클릭합니다.

<ph type="x-smartling-placeholder">
</ph> 파일을 저장하기 전에 표시되는 권한 메시지 <ph type="x-smartling-placeholder">
</ph> 브라우저에 쓰기가 부여되기 전에 사용자에게 표시되는 메시지 권한을 부여할 수 있습니다.

또는 IDE와 같이 여러 파일을 수정하는 웹 앱에서도 변경사항을 적용할 수 있습니다.

사용자가 취소를 선택하고 쓰기 액세스 권한을 부여하지 않으면 웹 앱이 변경사항을 로컬 파일로 저장합니다. 사용자가 데이터를 저장할 수 있는 다른 방법인 예를 들어 '다운로드' 파일을하거나 클라우드에 데이터를 저장할 때 유용합니다.

투명성

<ph type="x-smartling-placeholder">
</ph> 검색주소창 아이콘 <ph type="x-smartling-placeholder">
</ph> 사용자가 웹사이트 권한을 부여했음을 나타내는 주소 표시줄 아이콘 로컬 파일에 저장합니다

사용자가 로컬 파일을 저장할 수 있는 권한을 웹 앱에 부여하면 브라우저에 아이콘 를 입력합니다. 아이콘을 클릭하면 사용자가 제공한 파일 목록을 보여주는 팝오버가 열립니다. 액세스할 수 있습니다 사용자는 원하는 경우 언제든지 액세스 권한을 취소할 수 있습니다.

권한 지속성

웹 앱은 파일의 모든 탭이 표시되지 않고 파일에 변경 사항을 저장할 수 원점이 닫혔습니다. 탭을 닫으면 사이트에서 모든 액세스 권한을 잃게 됩니다. 다음에 사용자가 웹 앱을 사용하면 파일에 액세스하라는 메시지가 다시 표시됩니다.

의견

File System Access API를 사용해 본 경험에 관한 의견을 듣고자 합니다.

API 설계에 대해 알려주세요.

API에서 예상대로 작동하지 않는 부분이 있나요? 또는 누락된 메서드가 있나요? 속성이 있나요? 보안에 대한 질문이나 의견이 있으면 무엇인가요?

구현에 문제가 있습니까?

Chrome 구현에서 버그를 발견하셨나요? 아니면 구현이 사양과 다른가요?

  • https://new.crbug.com에서 버그를 신고합니다. 최대한 자세하게 작성해 주시기 바랍니다. 안내하고 구성요소Blink>Storage>FileSystem로 설정합니다. Glitch는 빠른 재현을 공유할 때 유용합니다.

API를 사용할 계획이신가요?

사이트에서 File System Access API를 사용할 계획이신가요? 여러분의 공개적 후원은 YouTube가 우선순위를 정하는 데 도움이 됩니다 기능을 지원하는 것이 얼마나 중요한지 다른 브라우저 공급업체에 보여줍니다.

유용한 링크

감사의 말씀

File System Access API 사양은 마리인 크루이셀브링크