ParcelFileDescriptor是android提供的,继承于Parcelable,可以在AIDL中直接使用。 4.1 用法 用java层File对象创建ParcelFileDescriptor public static ParcelFileDescriptor open(File file, int mode FileDescriptor fd = openInternal(file, mode); if (fd == null) return null; return new ParcelFileDescriptor 经过Binder通信传递ParcelFileDescriptor对象。Server端拿到的fd1指向的是file2。 假如Client端用java层File对象读文件,Server端拿到的ParcelFileDescriptor对应的fd1读写文件,两者并不会有任何影响。 ?
private static String IMAGE_DIRECTORY=localFile.getAbsolutePath(); public ParcelFileDescriptor openFile (file,ParcelFileDescriptor.MODE_READ_ONLY); } 这段代码使用android.net.Uri.getLastPathSegment()从paramUri中获取文件名 private static String IMAGE_DIRECTORY=localFile.getAbsolutePath(); public ParcelFileDescriptor openFile private static String IMAGE_DIRECTORY=localFile.getAbsolutePath(); public ParcelFileDescriptor openFile =0){ throw new IllegalArgumentException(); } return ParcelFileDescriptor.open(file,ParcelFileDescriptor.MODE_READ_ONLY
PdfRenderer允许从多个来源读取PDF文件,不同来源的PDF文件打开操作由ParcelFileDescriptor完成,该类的对象可以通过两种方式获得,一种方式是从assets目录下读取pdf文件 (); 从存储卡上读取pdf文件的代码举例如下: ParcelFileDescriptor fd = ParcelFileDescriptor.open( new File("example.pdf "), ParcelFileDescriptor.MODE_READ_ONLY); 打开PDF文件只是第一步,接下来还要使用PdfRenderer加载pdf文件,并进行相关的处理操作,PdfRenderer 的常用方法说明如下: 构造函数:从ParcelFileDescriptor对象构造一个PdfRenderer实例。 fd = ParcelFileDescriptor.open( new File(path), ParcelFileDescriptor.MODE_READ_ONLY); PdfRenderer
获取fileDescriptorModelLoader ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader = new StreamFileDataLoadProvider()); //GenericLoaderFactory注册 register(File.class, ParcelFileDescriptor.class Glide.buildFileDescriptorModelLoader:获取fileDescriptorModelLoader public static <T> ModelLoader<T, ParcelFileDescriptor , context); } 这一步和【1】差不多的流程,已module.class = String.class为例子,register(String.class, ParcelFileDescriptor.class modelClass, ModelLoader<ModelType, InputStream> streamModelLoader, ModelLoader<ModelType, ParcelFileDescriptor
android.arch.lifecycle.MutableLiveData; import android.graphics.Bitmap; import android.graphics.pdf.PdfRenderer; import android.os.ParcelFileDescriptor Boolean> mNextEnabled = new MutableLiveData<>(); private final Executor mExecutor; private ParcelFileDescriptor return; } Log.i("xqxinfo","file->"+file.getAbsolutePath()); mFileDescriptor = ParcelFileDescriptor.open (file, ParcelFileDescriptor.MODE_READ_ONLY); if (mFileDescriptor !
import android.os.IBinder; import android.os.MemoryFile; import android.os.Parcel; import android.os.ParcelFileDescriptor 通过反射获得文件句柄 FileDescriptor fd = (FileDescriptor) method.invoke(mf); ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(fd); //将文件句柄写到binder调用的返回值中。
parcelFileDescriptor = null; FileDescriptor fileDescriptor = null; Bitmap bitmap = null; if (parcelFileDescriptor ! = null && parcelFileDescriptor.getFileDescriptor() ! = null) { fileDescriptor = parcelFileDescriptor.getFileDescriptor(); //转换uri为 = null) { parcelFileDescriptor.close(); }catch (IOException e) { } }
6)根据Uri获得Bitmap private Bitmap getBitmapFromUri(Uri uri) throws IOException { ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r"); FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); Bitmap image = BitmapFactory.decodeFileDescriptor (fileDescriptor); parcelFileDescriptor.close(); return image; } ? = null) { stringBuilder.append(line); } fileInputStream.close(); parcelFileDescriptor.close
ByteBufferGifDecoder(context, registry.getImageHeaderParsers(), bitmapPool, arrayPool); ResourceDecoder<ParcelFileDescriptor Bitmap.class, streamBitmapDecoder) .append( Registry.BUCKET\_BITMAP, ParcelFileDescriptor.class streamBitmapDecoder)) .append( Registry.BUCKET\_BITMAP\_DRAWABLE, ParcelFileDescriptor.class InputStream.class, resourceLoaderStreamFactory) .append( int.class, ParcelFileDescriptor.class new UriLoader.StreamFactory(contentResolver)) .append( Uri.class, ParcelFileDescriptor.class
android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.ParcelFileDescriptor failed to close file"); } } return true; } @Override public ParcelFileDescriptor ; return ParcelFileDescriptor.open(file, modeBits); } @Override public String getType android.content.pm.ProviderInfo; import android.net.Uri; import android.os.Bundle; import android.os.ParcelFileDescriptor ParcelFileDescriptor pfd = null; try { pfd = getContentResolver().openFileDescriptor
android.content.ContentResolver#openFileDescriptor(Uri, String) ContentResolver.openFileDescriptor} to get a {@link ParcelFileDescriptor } 也就是openFileDescriptor方法,拿到ParcelFileDescriptor类型数据,其实就是一个文件描述符,然后就可以读取文件流了。 ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(intent.getData(), "r"); FileReader reader = new FileReader(parcelFileDescriptor.getFileDescriptor()); BufferedReader bufferedReader
在加载成为InputStream ResourceLoader.UriFactory 将资源ID转换为Uri ResourceLoader.FileDescriptorFactory 将资源ID转化为ParcelFileDescriptor 转换为ByteBuffer FileLoader.StreamFactory 将File转换为InputStream FileLoader.FileDescriptorFactory 将File转化为ParcelFileDescriptor Uri转换为InputStream UriLoader.StreamFactory 将Uri转换为InputStream UriLoader.FileDescriptorFactory 将Uri转换为ParcelFileDescriptor 实在太多,只列出了部分) 源数据 转换数据 转换器 Integer.class InputStream.class ResourceLoader.StreamFactory Integer.class ParcelFileDescriptor.class
android.content.ContentResolver#openFileDescriptor(Uri, String) ContentResolver.openFileDescriptor} to get a {@link ParcelFileDescriptor } 也就是openFileDescriptor方法,拿到ParcelFileDescriptor类型数据,其实就是一个文件描述符,然后就可以读取文件流了。 ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(intent.getData(), "r"); FileReader reader = new FileReader(parcelFileDescriptor.getFileDescriptor()); BufferedReader bufferedReader
但是如果代码写得不严谨,就可能会出现路径穿越等问题,一个经典的漏洞实现如下: @Override public ParcelFileDescriptor openFile(Uri uri, String (file, ParcelFileDescriptor.MODE_READ_ONLY); } throw new FileNotFoundException(uri.getPath()) (f, ParcelFileDescriptor.MODE_READ_ONLY); } 这里想用 getLastPathSegment 去只获取最后一级的文件名,但实际上可以被 URL encode 的路径绕过 正确的防御和过滤方式如下: public ParcelFileDescriptor openFile (Uri uri, String mode) throws FileNotFoundException (mode); return ParcelFileDescriptor.open(new File(path), modeBits); } 这个方法的主要作用是方便子类用于快速实现 openFile
void handleGalleryKitKatResult(int resultCode, Intent data) { File faceFile; try { ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(contentUri, "r"); FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); Bitmap image = BitmapFactory.decodeFileDescriptor
= null var parcelfd : ParcelFileDescriptor? = null var mBitmap : Bitmap? (file,ParcelFileDescriptor.MODE_READ_ONLY) btn_prev.setOnClickListener { renderPrev() } 注意的是 PdfRenderer 构造方法接受的参数是一个 ParcelFileDescriptor 对象。 所以,我们要将 pdf 路径创建的 File 对象转换成 ParcelFileDescriptor。 parcelfd = ParcelFileDescriptor.open(file,ParcelFileDescriptor.MODE_READ_ONLY) 整个 Activity 最核心的方法是 renderPage
MemoryFile.class.getDeclaredMethod("getFileDescriptor"); FileDescriptor des = (FileDescriptor) method.invoke(memoryFile); ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(des); 「进程 B 中通过 binder 拿到 A 进程中准备好的文件描述符,然后直接读取数据:」 FileDescriptor descriptor
final ModelLoader<ModelType, InputStream> streamModelLoader; private final ModelLoader<ModelType, ParcelFileDescriptor (Glide glide, ModelLoader<A, InputStream> streamModelLoader, ModelLoader<A, ParcelFileDescriptor modelClass, ModelLoader<ModelType, InputStream> streamModelLoader, ModelLoader<ModelType, ParcelFileDescriptor (Glide glide, ModelLoader<A, InputStream> streamModelLoader, ModelLoader<A, ParcelFileDescriptor > { private final DataFetcher<InputStream> streamFetcher; private final DataFetcher<ParcelFileDescriptor
android.media.MediaMetadataRetriever; import android.media.MediaFile.MediaFileType; import android.net.Uri; import android.os.ParcelFileDescriptor Bitmap makeBitmap(int minSideLength, int maxNumOfPixels, Uri uri, ContentResolver cr, ParcelFileDescriptor closeSilently(pfd); } return b; } private static void closeSilently(ParcelFileDescriptor c.close(); } catch (Throwable t) { // do nothing } } private static ParcelFileDescriptor
零拷贝传输方案: // 使用Ashmem共享内存传输大文件 ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(fd); parcel.writeFileDescriptor