Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Передача файлов

Файлы можно передавать между клиентами и серверами Binder с помощью типа ParcelFileDescriptor:

birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl:

interface IBirthdayService {
    /** То же самое, но загружает информацию из файла. */
    String wishFromFile(in ParcelFileDescriptor infoFile);
}

birthday_service/src/client.rs:

// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0

fn main() {
    binder::ProcessState::start_thread_pool();
    let service = connect().expect("Failed to connect to BirthdayService");

    // Откройте файл и запишите в него информацию о дне рождения.
    let mut file = File::create("/data/local/tmp/birthday.info").unwrap();
    writeln!(file, "{name}")?;
    writeln!(file, "{years}")?;

    // Создайте `ParcelFileDescriptor` из файла и отправьте его.
    let file = ParcelFileDescriptor::new(file);
    service.wishFromFile(&file)?;
}

birthday_service/src/lib.rs:

// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0

impl IBirthdayService for BirthdayService {
    fn wishFromFile(
        &self,
        info_file: &ParcelFileDescriptor,
    ) -> binder::Result<String> {
        // Преобразуйте дескриптор файла в `File`. `ParcelFileDescriptor` оборачивает
        // `OwnedFd`, который можно клонировать, а затем использовать для создания
        // объекта `File`.
        let mut info_file = info_file
            .as_ref()
            .try_clone()
            .map(File::from)
            .expect("Invalid file handle");

        let mut contents = String::new();
        info_file.read_to_string(&mut contents).unwrap();

        let mut lines = contents.lines();
        let name = lines.next().unwrap();
        let years: i32 = lines.next().unwrap().parse().unwrap();

        Ok(format!("Happy Birthday {name}, congratulations with the {years} years!"))
    }
}
  • ParcelFileDescriptor оборачивает OwnedFd, поэтому его можно создать из File (или любого другого типа, который оборачивает OwnedFd), а на другой стороне использовать для создания нового дескриптора File.
  • Можно обернуть и отправить и другие типы файловых дескрипторов, например сокеты TCP, UDP и UNIX.