Передача файлов
Файлы можно передавать между клиентами и серверами 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.