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 !
parcelFileDescriptor = null; FileDescriptor fileDescriptor = null; Bitmap bitmap = null; if (parcelFileDescriptor ! = null && parcelFileDescriptor.getFileDescriptor() ! = null) { fileDescriptor = parcelFileDescriptor.getFileDescriptor(); //转换uri为 = null) { parcelFileDescriptor.close(); }catch (IOException e) { } }
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调用的返回值中。
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
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.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
void handleGalleryKitKatResult(int resultCode, Intent data) { File faceFile; try { ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(contentUri, "r"); FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); Bitmap image = BitmapFactory.decodeFileDescriptor
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
= 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