Надсилання файлів

Файли можна надсилати між клієнтами/серверами Binder, використовуючи тип ParcelFileDescriptor:

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

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

birthday_service/src/client.rs:

fn main() { binder::ProcessState::start_thread_pool(); let service = connect().expect("Не вдалося підключитися до 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:

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("Неправильний дескриптор файлу"); 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!("З днем народження {name}, вітаємо з {years} роками!")) } }

Speaker Notes

  • Дескриптор ParcelFileDescriptor обгортає OwnedFd, тому може бути створений з File (або будь-якого іншого типу, який обгортає OwnedFd), і може бути використаний для створення нового дескриптора File на іншій стороні.
  • Інші типи дескрипторів файлів можуть бути загорнуті та надіслані, наприклад, TCP, UDP та UNIX-сокети.