Hệ thống tệp và tài liệu trong phát triển di động: khái niệm, nguyên tắc và cách hoạt động

Tác giả: IT Sectr Đã đăng: 2026-07-19 Thời gian đọc: 12 phút

Làm việc với hệ thống tệp là nền tảng của mọi ứng dụng di động. Mỗi nền tảng cung cấp mô hình truy cập riêng: Sandbox trên iOS cô lập các ứng dụng trong các vùng chứa riêng biệt, trong khi Scoped Storage trên Android hạn chế truy cập trực tiếp vào bộ nhớ dùng chung. Theo Google Developer Documentation (2026), việc giới thiệu Scoped Storage với Android 10 đòi hỏi phải xem xét lại toàn bộ kiến trúc lưu trữ dữ liệu. Trong hướng dẫn này, chúng ta sẽ tìm hiểu FileManager, MediaStore API, Storage Access Framework và DocumentProvider cho cả hai nền tảng.

Những điểm chính

  • Sandbox — môi trường iOS cô lập, mỗi ứng dụng chỉ hoạt động trong thư mục riêng mà không truy cập được dữ liệu của ứng dụng khác.
  • Scoped Storage — mô hình Android 10+ hạn chế truy cập trực tiếp vào bộ nhớ ngoài qua MediaStore API và SAF.
  • FileManager — lớp chính của iOS cho các thao tác tệp: tạo, đọc, sao chép, di chuyển và xóa.
  • Storage Access Framework — cơ chế hệ thống Android để chọn tài liệu bằng Intent ACTION_OPEN_DOCUMENT.
  • DocumentProvider — thành phần Android để xuất bản tệp ứng dụng vào hệ thống tệp dùng chung qua SAF.

Hệ thống tệp trong ứng dụng di động là gì?

Hệ thống tệp trong ứng dụng di động là tập hợp các API, quy tắc bảo mật và ràng buộc xác định cách lưu trữ và truy cập dữ liệu trên thiết bị iOS và Android. Không giống như hệ điều hành máy tính để bàn, nền tảng di động cô lập từng ứng dụng để bảo vệ dữ liệu người dùng khỏi bị đọc trái phép bởi các chương trình khác.

Sự khác biệt về kiến trúc giữa iOS và Android

iOS sử dụng mô hình Sandbox, trong đó mỗi ứng dụng tồn tại trong vùng chứa riêng với quyền hạn bị giới hạn nghiêm ngặt. Trước phiên bản 10, Android cung cấp quyền truy cập đầy đủ vào bộ nhớ ngoài, nhưng với sự ra đời của Scoped Storage, cách tiếp cận đã trở nên gần giống với iOS. Sự khác biệt chính là iOS cô lập hoàn toàn hệ thống tệp, trong khi Android cung cấp nhiều cấp độ truy cập: thư mục riêng tư, MediaStore công khai và truy cập tạm thời qua SAF.

Các loại lưu trữ chính

Ứng dụng di động sử dụng ba loại lưu trữ dữ liệu. Lưu trữ riêng tư — thư mục chỉ ứng dụng mới có thể truy cập cho các tệp nội bộ và bộ nhớ đệm. Lưu trữ dùng chung — tệp phương tiện qua MediaStore (Android) hoặc Files App (iOS). Lưu trữ đám mây — iCloud Drive và Google Drive để đồng bộ giữa các thiết bị. Mỗi loại có giới hạn riêng về kích thước, thời gian tồn tại của tệp và điều kiện truy cập.

Loại lưu trữiOSAndroid
Riêng tưDocuments, Library, CachesgetFilesDir(), getCacheDir()
Phương tiện dùng chungPHPhotoLibrary qua bộ chọnMediaStore API (ContentResolver)
Tài liệu dùng chungFiles App qua UIDocumentPickerStorage Access Framework (SAF)
Đám mâyiCloud Drive (UIDocument)Google Drive API
Bộ nhớ đệmThư mục Caches, hệ thống dọn dẹpgetCacheDir(), getExternalCacheDir()

Hệ thống tệp trong phát triển di động: Sandbox trên iOS

Sandbox là kiến trúc bảo mật của iOS cô lập từng ứng dụng. Ứng dụng chỉ có thể đọc và ghi bên trong hộp cát của chính nó. Để truy cập danh bạ, ảnh hoặc tệp từ ứng dụng khác, phải sử dụng bộ chọn hệ thống: UIImagePickerController hoặc UIDocumentPickerViewController. Truy cập Files App được cấu hình qua cờ UIFileSharingEnabled trong Info.plist. Hệ thống tệp trong phát triển di động trên iOS yêu cầu hiểu cấu trúc thư mục và chọn đúng vị trí cho từng loại dữ liệu.

Cấu trúc thư mục hộp cát

Hộp cát iOS bao gồm một số thư mục tiêu chuẩn. Documents — cho tệp người dùng, được bao gồm trong iCloud Backup. Caches — cho dữ liệu tạm thời mà hệ thống có thể xóa khi dung lượng thấp. Temporary — cho tệp phiên hiện tại, bị xóa khi khởi động lại. Application Support — cho dữ liệu nội bộ của ứng dụng ẩn khỏi người dùng. Chọn sai thư mục dẫn đến vấn đề: lưu bộ nhớ đệm trong Documents lãng phí dung lượng iCloud và vi phạm nguyên tắc hệ thống tệp của Apple.

swift
import Foundation

let fileManager = FileManager.default
guard let documentsURL = fileManager.urls(
    for: .documentDirectory,
    in: .userDomainMask
).first else { return }

let fileURL = documentsURL.appendingPathComponent("notes.txt")
let text = "Содержимое файла"

// Ghi nguyên tử với mã hóa
try text.write(
    to: fileURL,
    atomically: true,
    encoding: .utf8
)

FileManager — API chính cho thao tác tệp

Lớp FileManager cung cấp bộ phương thức hoàn chỉnh để quản lý tệp trên iOS. FileManager.default là một singleton an toàn luồng phù hợp cho hầu hết các thao tác. Các phương thức như fileExists(atPath:), createDirectory(at:withIntermediateDirectories:attributes:), copyItem(at:to:) và removeItem(at:) bao phủ các kịch bản cơ bản. Các thao tác tệp lớn hơn 1 MB nên được thực hiện trong luồng nền qua DispatchQueue.global(). Để truyền phát khối lượng lớn, hãy sử dụng FileHandle thay vì tải toàn bộ tệp vào bộ nhớ.

swift
func readDocumentsFile(named fileName: String) -> String? {
    guard let docsURL = FileManager.default.urls(
        for: .documentDirectory,
        in: .userDomainMask
    ).first else { return nil }

    let fileURL = docsURL.appendingPathComponent(fileName)
    return try? String(contentsOf: fileURL)
}

Hệ thống tệp trong ứng dụng di động: Scoped Storage trên Android

Với việc phát hành Android 10, Google đã giới thiệu Scoped Storage — mô hình truy cập hạn chế vào hệ thống tệp. Ứng dụng chỉ có thể đọc và ghi tự do trong các thư mục riêng tư của nó. Đối với tệp phương tiện (ảnh, video, âm thanh), MediaStore API được sử dụng qua ContentResolver. Đối với tài liệu tùy ý, Storage Access Framework được sử dụng qua Intent ACTION_OPEN_DOCUMENT. Trên Android 11+, quyền truy cập trực tiếp vào thư mục gốc của bộ nhớ ngoài bị cấm hoàn toàn và tất cả nhà phát triển phải sử dụng API mới.

MediaStore API để làm việc với tệp phương tiện

MediaStore là ContentProvider hệ thống để truy cập tệp phương tiện trên thiết bị. Qua ContentResolver, ứng dụng yêu cầu Uri tệp thay vì đường dẫn trực tiếp. MediaStore.Files — cho tất cả loại tệp, Images — cho hình ảnh, Video — cho video, Audio — cho bản ghi âm. Ghi vào thư mục dùng chung được thực hiện qua insert() với DISPLAY_NAME, MIME_TYPE và RELATIVE_PATH. Sau khi chèn, ứng dụng nhận được Uri để ghi byte. Loại MIME đóng vai trò quan trọng — loại sai sẽ gây lỗi khi mở tệp.

kotlin
val contentValues = ContentValues().apply {
    put(MediaStore.MediaColumns.DISPLAY_NAME, "report.pdf")
    put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf")
    put(MediaStore.MediaColumns.RELATIVE_PATH, "Documents/Reports")
}

val uri = contentResolver.insert(
    MediaStore.Files.getContentUri("external"),
    contentValues
)

uri?.let {
    contentResolver.openOutputStream(it)?.use { stream ->
        stream.write(pdfBytes)
    }
}

Storage Access Framework để chọn tệp

SAF cung cấp giao diện thống nhất để chọn và tạo tệp mà không cần quyền runtime. Intent ACTION_OPEN_DOCUMENT mở trình quản lý tệp hệ thống trên Android. Sau khi chọn, ứng dụng nhận được Uri content:// với quyền truy cập tạm thời qua FLAG_GRANT_READ_URI_PERMISSION. ACTION_CREATE_DOCUMENT cho phép lưu tệp vào bất kỳ vị trí lưu trữ ngoài nào do người dùng chọn. SAF hoạt động trên Android 5+ và cung cấp quyền truy cập vào tệp từ nhà cung cấp đám mây được kết nối qua DocumentsProvider.

kotlin
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
    addCategory(Intent.CATEGORY_OPENABLE)
    type = "*/*"
    putExtra(Intent.EXTRA_MIME_TYPES, arrayOf(
        "application/pdf",
        "text/plain"
    ))
}
startActivityForResult(intent, REQUEST_CODE)

Chọn tài liệu trong ứng dụng di động: bộ chọn hệ thống

Cả hai nền tảng đều cung cấp cơ chế tích hợp cho người dùng chọn tệp. Tài liệu trong ứng dụng di động được truyền qua bộ chọn hệ thống cấp quyền truy cập tạm thời vào tệp mà không cần quyền vĩnh viễn. Trên iOS, đó là UIDocumentPickerViewController; trên Android, đó là ACTION_OPEN_DOCUMENT. Tài liệu trong ứng dụng di động có thể được chọn từ cả bộ nhớ cục bộ và dịch vụ đám mây. Người dùng chỉ định rõ ràng tệp và ứng dụng nhận được Uri hoặc URL với thời hạn hiệu lực giới hạn.

UIDocumentPickerViewController trên iOS

UIDocumentPickerViewController mở Files App và cho phép chọn một hoặc nhiều tài liệu. Chế độ: import (sao chép vào hộp cát) và mở (truy cập qua URL có phạm vi bảo mật). Để lọc tệp, một mảng loại UTType được truyền — ví dụ: .pdf và .plainText. Sau khi nhận URL, ứng dụng phải gọi startAccessingSecurityScopedResource() trước khi đọc và stopAccessingSecurityScopedResource() sau khi hoàn thành. Không gọi stopAccessing dẫn đến rò rỉ tài nguyên hệ thống. Tài liệu trong ứng dụng di động trên iOS yêu cầu giải phóng bắt buộc các quyền tạm thời sau khi hoàn thành làm việc với tệp.

swift
let picker = UIDocumentPickerViewController(
    forOpeningContentTypes: [.pdf, .plainText]
)
picker.allowsMultipleSelection = true
picker.delegate = self
present(picker, animated: true)

// Giải phóng quyền truy cập trong đại biểu
func documentPicker(
    _ controller: UIDocumentPickerViewController,
    didPickDocumentsAt urls: [URL]
) {
    guard let url = urls.first else { return }
    url.startAccessingSecurityScopedResource()
    defer { url.stopAccessingSecurityScopedResource() }
}

FileProvider và DocumentProvider trên Android

FileProvider là lớp con của ContentProvider để chia sẻ tệp an toàn giữa các ứng dụng. Nó tạo Uri content:// tạm thời dựa trên tệp từ các thư mục XML được chỉ định. Các ứng dụng khác nhận quyền truy cập qua Intent với FLAG_GRANT_READ_URI_PERMISSION. DocumentProvider, không giống như FileProvider, xuất bản tệp trong SAF và cho phép ứng dụng khác duyệt nội dung của ứng dụng bạn như một phần của hệ thống tệp. Để triển khai DocumentsProvider, bạn cần ghi đè queryRoots(), queryChildDocuments() và openDocument(), sau đó đăng ký trong AndroidManifest.xml

iCloud Drive và đồng bộ tệp đám mây

Đồng bộ đám mây cho phép người dùng truy cập tài liệu trên tất cả thiết bị của họ. Hệ thống tệp trong ứng dụng di động được tăng cường bởi lớp đám mây: UIDocument trên iOS tự động theo dõi thay đổi và đồng bộ qua iCloud. Trên Android, chức năng tương tự được xây dựng qua Google Drive API hoặc DocumentsProvider với gốc đám mây. Hiểu hệ thống tệp trong phát triển di động là rất quan trọng để xây dựng đồng bộ đáng tin cậy giữa các thiết bị.

UIDocument — Đồng bộ trên iOS

UIDocument là lớp trừu tượng để làm việc với tài liệu iCloud. Nó tự động lưu thay đổi, đọc dữ liệu và thông báo cho đại biểu về cập nhật. Khi xảy ra xung đột ghi, NSFileVersion cung cấp danh sách các phiên bản có sẵn — nhà phát triển có thể chọn phiên bản mới nhất hoặc hiển thị cho người dùng các tùy chọn giải quyết xung đột. Cấu hình Ubiquity Container trong Capabilities của dự án là bắt buộc cho iCloud Drive. NSFileCoordinator và NSFilePresenter ngăn chặn điều kiện cạnh tranh dữ liệu khi truy cập đồng thời từ nhiều luồng hoặc thiết bị.

Sao lưu và khôi phục dữ liệu

iOS tự động bao gồm thư mục Documents trong iCloud Backup. Android hoạt động với Auto Backup for Apps — hệ thống lưu dữ liệu từ getFilesDir(), SharedPreferences và cơ sở dữ liệu SQLite vào Google Drive. Bộ nhớ đệm và tệp ngoài không được bao gồm trong sao lưu. Cả hai nền tảng đều cho phép cấu hình ngoại lệ: trên iOS qua NSURLIsExcludedFromBackupKey, trên Android qua cấu hình XML quy tắc sao lưu. Mã hóa tệp có dữ liệu cá nhân là bắt buộc — trên iOS sử dụng NSDataWritingFileProtectionComplete, trên Android sử dụng EncryptedFile từ thư viện security-crypto.

Tham sốiOSAndroid
Sao lưu mặc địnhDocuments và LibrarygetFilesDir(), SharedPreferences, DB
Loại trừ tệpisExcludedFromBackupKeyQuy tắc XML sao lưu (fullBackupContent)
Mã hóaNSDataWritingFileProtectionCompleteEncryptedFile (security-crypto)
Đồng bộ đám mâyUIDocument + iCloudGoogle Drive API + SAF
Tự động khôi phụciCloud Restore sau khi cài đặtAuto Backup khi cài lại

Câu hỏi thường gặp

Sandbox trên iOS là gì?

Sandbox là môi trường cô lập cho mỗi ứng dụng trên iOS. Ứng dụng không thể truy cập tệp của ứng dụng khác nếu không sử dụng bộ chọn hệ thống như UIDocumentPickerViewController.

Scoped Storage trên Android là gì?

Scoped Storage là mô hình truy cập hạn chế vào hệ thống tệp trên Android 10+. Ứng dụng chỉ đọc trực tiếp tệp của chính nó, sử dụng MediaStore API cho phương tiện và Storage Access Framework cho tài liệu.

Làm thế nào để chọn tệp trên iOS?

Sử dụng UIDocumentPickerViewController — bộ chọn hệ thống để chọn tài liệu từ Files App hoặc iCloud Drive. Sau khi chọn, bạn nhận được URL có phạm vi bảo mật với quyền truy cập tạm thời.

Làm thế nào để truy cập tệp trên Android 11+?

Đối với tệp phương tiện, sử dụng MediaStore API qua ContentResolver với loại MIME được chỉ định. Đối với tài liệu tùy ý, sử dụng Storage Access Framework với Intent ACTION_OPEN_DOCUMENT.

FileProvider trên Android là gì?

FileProvider là lớp con của ContentProvider để chia sẻ tệp an toàn giữa các ứng dụng qua Uri content:// tạm thời với FLAG_GRANT_READ_URI_PERMISSION.

Tổng kết

  • Sandbox — hệ thống tệp cô lập của iOS, ứng dụng chỉ có thể truy cập thư mục Documents, Caches và Library của chính nó.
  • FileManager — API chính cho thao tác tệp trên iOS. Đọc tệp lớn qua FileHandle trong luồng nền.
  • Scoped Storage — mô hình hệ thống tệp trên Android 10+ thay thế truy cập trực tiếp vào bộ nhớ ngoài bằng MediaStore API và SAF.
  • MediaStore API — ContentProvider hệ thống để làm việc với tệp phương tiện trên Android. Ghi được thực hiện qua insert() với ContentValues.
  • Storage Access Framework — cơ chế chọn tài liệu phổ quát trên Android qua ACTION_OPEN_DOCUMENT và ACTION_CREATE_DOCUMENT.
  • UIDocumentPickerViewController — bộ chọn hệ thống iOS mở Files App và iCloud Drive. Hoạt động với URL có phạm vi bảo mật.
  • FileProvider — cơ chế chia sẻ tệp an toàn giữa ứng dụng Android qua Uri content:// tạm thời và quyền runtime.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án