精华内容
下载资源
问答
  • android app私有路径的获取

    千次阅读 2021-03-04 09:27:43
    所以需要将文件保存在系统分配给APP的私有空间中,该路径获取也是很简单的,主要有两种场景。 1 在Activity 中获取该路径: 该场景只需调用函数 getExternalFilesDir(null) 函数即可获得,代码如下 var private...

    Anddroid 7.0 之后系统默认禁止访问公共存储目录。所以需要将文件保存在系统分配给APP的私有空间中,该路径获取也是很简单的,主要有两种场景。

    1 在Activity 中获取该路径:

    该场景只需调用函数

    getExternalFilesDir(null)

    函数即可获得,代码如下

    var privatePath = getExternalFilesDir(null).toString()
    

    该私有空间路径位于“外部存储根目录/Android/data/应用包名/files”下

    2 在其他类中获取该路径

    由于函数getExternalFilesDir() 函数只能在Activity中直接调用,那在我们需要写一些工具类时,也需要获取该路径,该如何实现呢?

    比较推荐的方法是先写一个继承自Application的类,在该类中声明 context 的静态常量(也就是一个全局的context),这样在该APP的所有类中均可直接调用该context下的方法。代码如下

    class MyApplication : Application() {
        override fun onCreate() {
            super.onCreate()
            //获取context
            context = applicationContext
        }
    
        companion object {
            //创建一个伴生对象,以便获取context对象
            var context: Context? = null
                private set
        }
    }
    
    注意:这个类写完后需要在 AndroidManifest.xml 文件中的< application >节点下声明一下。这样APP在初始化时才会把这个 context 作为一个全局常量初始化
    <application
            android:name=".MyApplication"
    

    以上完成后,就可以在其他的类中使用该 context 了,例如下面的代码

    import com.example.recorder.MyApplication.Companion.context
    
    fun getAPPpath():String{
            return context?.getExternalFilesDir(null).toString()
        }
    

    得到了这个路径,就可以在该APP中进行文件的读写等操作了

    展开全文
  • 基于Android系统对存储卡访问的各种特性,在充分保证基线的产品交互体验前提下,定义Android APP各业务开发中的可选存储路径,对应存储特性,各自适合存储文件范围和存储路径格式规范。 存储类型 根路径 特性...

    1. Android APP统一存储数据规范

    基于Android系统对存储卡访问的各种特性,在充分保证基线的产品交互体验前提下,定义Android APP各业务开发中的可选存储路径,对应存储特性,各自适合存储文件范围和存储路径格式规范。

    存储类型根路径特性存储文件范围业务路径格式
    内置数据分区 /data/../<packagename>/files/
    (对应:Context.getFilesDir()
    1.APP被安装时系统分配在data分区上的存储路径;
    2.APP访问不需要申请权限;APP私有,安全性最高;
    3.(非root或非共享UID)其它APP无权访问
    4.files和cache的区别:cache存储偏临时性的文件,在系统存储空间紧张时会被系统auto clean,应用设置中“清理缓存”会清理掉cache内文件;
    5.APP卸载时或“清理数据”时,此2种路径下的所有文件都会被系统自动清理;
    1.数据文件体积小(KB级别);
    2.运行时只能在data区加载的文件(如:动态下载的so库,插件apk或hotfix Dex文件等)
    3.安全性要求高的私密性文件;
    4.记录方便用户继续使用的历史行为数据,不希望被频繁重置到默认值的数据文件;

    各存储类型根路径下各业务相对路径格式:

    ./<一级业务>/<子业务>/<子路径>/,

    1.APP内各业务统一路径标准后,为了避免业务间冲突,请各业务找基线APP申请和注册<一级业务>,插件的还涉及<子业务>的注册<子路径>由各业务内部自行分配;但要严格根据存储特性和适合的文件范围选择存储路径;<子业务>和<子路径>是可选的;

    2.各一级业务存储路径层级尽量不要超过3级,层次越深,遍历计算各级文件大小和删除时效率越低;

    3.示例

    <一级业务>

    基线:./app

    <子业务>:

    下载:./app/download/

    播放器:./app/player/

    泡泡:./paopao

    插件: ./plugins

    <子业务>

    ./plugins/<插件包名>/

    ...

    /data/../<packagename>/cache/
    (对应:Context.getCacheDir())
    1.文件体积小(KB级别);
    2.被频繁删除或重置后不影响用户历史状态功能的文件;
    3.存储数据安全性相对较高,不希望被第三方获取到的临时文件
    内置存储卡(或分区)(APP私有存储路径)

    <内存储卡根路径>/

    Android/data/<packagename>/files/

    (对应:Context.getExternalFilesDir()

    1.系统为每个APP分配的基于不可插拔内置存储卡(或分区)的路径;
    2.APP私有的在存储卡上的空间,读写不需要特殊权限;
    3. 三方应用在获取到存储卡动态权限后可以读写该目录下文件,在存储安全性相比data区要低;
    4.files和cache的区别:cache存储偏临时性的文件,在系统存储空间紧张时会被系统auto clean,应用设置中“清理缓存”会清理掉cache内文件;
    5.APP卸载时或“清理数据”时,此2种路径下的所有文件都会被系统自动清理;

    1.存储体积较大的文件(例如:分发或自动更新的APK下载的视频类文件图片ZIP压缩包等体积较大的文件);
    2.存储对安全和隐私性要求不高的文件;

    3.没有单独的编辑删除入口,频繁删除或重置后不影响用户历史状态功能的文件放在cache目录中;

    <内存储卡根路径> /

    Android/data/<packagename>/cache/
    (对应:Context.getExternalCacheDir()

    存储卡非APP私有存储路径存储卡上非APP私有存储的其它路径(包括内置或可插拔的外置存储卡的非APP私有存储路径)

    1.Android 6.0+和部分OEM定制6.0-系统要动态申请存储卡读写权限,用户授权后才能读写;
    2.可插拔存储卡被移除后就数据无法访问;

     3.非系统指定的APP私有路径,卸载APP或清除数据时,对应的数据不会被清除,持久性强;

    4.放置到公共存储卡上,其实更容易被工具类APP清理缓存时引导用户做清理,

    因涉及用户动态权限,卸载APP后无法自动清理干净,一般不建议在此类路径下存储文件,有特殊需求的需要提出来Review审核 不建议使用的存储路径,暂时不做规范
    SharedPreferences/data/../<packagename>/shared_prefs/存储SharedPreferences文件存储全局性的开关,基类型的键值对数据涉及历史数据兼容性,此类数据存储体积上相对较小,暂时不做清理和统一要求;但需要业务内定期静态清理废弃的字段或表;单个表添加的数据项得设置上限值(一般1000条以内),做LRU替换
    Databse/data/../<packagename>/databases/存储APP内基于系统Sqlite数据库存储的存储按数据库表格式访问的数据

    注:Android APP内各业务存储路径汇总表

    2. Android APP统一访问存储卡路径的API

     根据第1节的介绍,基线APP内各业务一般只需要在内置数据区和存储卡APP私有路径上存取文件或数据,按基线APP中运行的业务特性提供不同的根路径获取API

      1>基线维护的所有业务,或以aar,jar等依赖基线基础库接入基线的业务,使用基线基础库提供的适配层API(便于在Android新系统或定制机型上存储特性变更时,由基线APP基础库修改API内部逻辑做兼容)

    内置数据区files根路径: File getInternalDataFilesDir(Context mContext, String subFolder);

    内置数据区cache根路径:File getInternalDataCacheDir(Context mContext, String subFolder);

    内置存储卡APP私有存储files根路径:File getInternalStorageFilesDir(Context mContext, String subFolder)

    内置存储卡APP私有存储cache根路径:File getInternalStorageCacheDir(Context mContext, String subFolder)

    :以上API细节定义和说明参考wiki:Android存储介绍及API定义 

      2>基线对接的native库,由native提供API和接收路径参数,按照第1节中描述的存储特性,由基线APP层传递相应的根路径给native业务;

      3>独立不依赖基线APP基础库的业务按照当前系统API来获取各自存储根路径(Android新系统或厂商定制系统上存储特性变更时,自行解决兼容性)

    内置数据区files根路径:Context.getFilesDir()

     内置数据区cache根路径:Context.getExternalCacheDir()

    内置存储卡APP私有存储files根路径:Context.getExternalFilesDir()

    内置存储卡APP私有存储cache根路径:Context.getExternalCacheDir()

      4>垂直插件业务:各个插件按照3>中独立业务形式使用API,但插件中心会Hook Context中4个API来锁定根路径(对应到基线基础库的4个API上的根路径);

    3.缓存清理规范

    用户在基线APP的“清理缓存”入口触发清理时,可以提供2个层次的清理选项

    1.自动清理

       临时数据:图片,网络请求的缓存临时数据(如:okhttp,fresco下载缓存的文件),直接删除后对用户体验影响可以忽略,直接扫描后清理;

    2.深度清理

    1>自动扫描清理cache目录:按第1节规范的路径,接入基线APP的按要求统一存放路径,对数据分区和内置存储卡APP私有目录的cache目录和各级子目录(非白名单路径)下的文件直接进行清理,静默删除,不需要用户确认(类似于系统应用设置中“清理缓存”操作);

     白名单路径:存放在cache目录下,删除后影响用户下次操作体验,删除后重复下载耗费流量,或其它特殊需求目录或文件;需要各业务找基线技术和产品申请配置白名单,白名单支持云端动态更新,白名单以相对路径中<子业务>或<子路径>名称匹配,不能直接配置 <一级业务>为白名单(避免不被删除的缓存文件范围过大);

     2> 用户交互式清理:对files路径或各级子路径,做扫描,扫描出的文件和目录不直接删除,UI上展示出“文件用途,删除后的影响,文件大小”等信息,由用户自主选择和确认后删除;  各业务产品自己定义交互提示信息和涉及的文件路径范围;

    3. 技术接口

    1>基线业务,泡泡,Native库等业务,由基线APP在临时kill掉主进程,启独立子进程删除对应文件,删除后自动重启APP(参考地区模式切换的产品形态,产品定义必要的交互提示)效果上类似与系统应用设置中“清除数据”;独立业务可以提供独立清理API给基线APP调用清理对应文件,但各业务要确保文件能删除干净;

    2>各插件业务的清理,由基线的插件中心统一做清理。

     :各业务的SharedPreferences,数据库,或其他独立文件中有记录或依赖被删除文件的,请自行内部判断检查文件被删除后可能导致业务逻辑异常的情况

    参考

    1,Android官方文档对数据存储说明:Data Storage

    2.基线APP实践和测试总结的存储特性:Android存储介绍及API定义 

    3.stackoverflow :when to clear the cache dir in Android

    展开全文
  • Android获取文件夹路径 /data/data/http://www.2cto.com/kf/201301/186614.htmlString printTxtPath = getApplicationContext().getPackageResourcePath() + "/files/" + fileName;=>/data/app/...

    Android获取文件夹路径 /data/data/

    http://www.2cto.com/kf/201301/186614.html

    String printTxtPath = getApplicationContext().getPackageResourcePath() + "/files/" + fileName;

    => /data/app/com.example.fileoperation-2.apk/files/printMenu.txt

    String printTxtPath = getApplicationContext().getFilesDir();

    String printTxtPath = getApplicationContext().getFilesDir().getAbsolutePath();

    => /data/data/com.example.fileoperation/files

    //获取当前程序路径

    getApplicationContext().getFilesDir().getAbsolutePath();

    //获取该程序的安装包路径

    String path=getApplicationContext().getPackageResourcePath();

    //获取程序默认数据库路径

    getApplicationContext().getDatabasePath(s).getAbsolutePath();

    WPF 获取程序路径的一些方法,根据程序路径获取程序集信息

    一.WPF 获取程序路径的一些方法方式一 应用程序域 //获取基目录即当前工作目录 string str_1 = System.AppDomain.CurrentDomain.BaseDirector ...

    C&num; 通过窗口句柄获取程序路径 图标

    转自:http://qqhack8.blog.163.com/blog/static/11414798520113363829505/ C# 通过窗口句柄获取程序路径 图标using System;u ...

    Android ----------获取各种路径(更新中。。。。。。)

    ##在手机中的路径 *获取应用的路径,形式:/data/data/包名 String appDataDir = getApplicationInfo().dataDir; *获取手机数据存储路径,即/ ...

    C&num;获取程序路径

    // 获取程序的基目录. System.AppDomain.CurrentDomain.BaseDirectory // 获取模块的完整路径. System.Diagnostics.Process.G ...

    Android 获取SD路径&comma;存储空间大小的方法

    Android用 Environment.getExternalStorageDirectory() 方法获取 SD 卡的路径 , 卡存储空间大小及已占用空间获取方法 : /* 获取存储卡路径 */ ...

    Delphi~通过程序窗体句柄获取程序路径

    http://www.cnblogs.com/Jesses/articles/1636323.html 引用PsAPI var  h:HWND;  pid: Cardinal;  pHandle: T ...

    获取程序的SHA1值

    android获取程序的SHA1值 public static String getSHA1(Context context) { try { PackageInfo info = context.g ...

    Android获取文件夹路径 &sol;data&sol;data&sol;

    首先内部存储路径为/data/data/youPackageName/,下面讲解的各路径都是基于你自己的应用的内部存储路径下.所有内部存储中保存的文件在用户卸载应用的时候会被删除. 一. files1 ...

    android 获取SD卡的图片及其路径

    1.首先是intent的设置: private static final int IMAGECODE = 0; Intent imageIntent = new Intent(Intent.ACYIO ...

    随机推荐

    利用mysqldump 将一个表按条件导出数据

    mysqldump -uroot -pdsideal -t dsideal_db t_resource_info --where="res_type=1 and group_id=1 and ...

    Java中的注解是如何工作的?--annotation学习一

    自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分.开发过程中,我们也时常在应用代码中会看到诸如@Override,@Deprecated这样的注解.这篇文章中,我将向大家讲述 ...

    zabbix discovery

    preface(见面礼): 仅扫tcp端口: netstat -tnlp|egrep -i "$1"

    &lbrack;COGS 2051&rsqb; 王者之剑

    Saber大法吼 2051. 王者之剑 ★★★☆   输入文件:Excalibur.in   输出文件:Excalibur.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述 ...

    WCF跨域解决方法及一些零碎的东西。

    之前发过一篇随笔,说的WCF配置文件配置问题.里面也配了跨域支持,但是jsoncollback只支持Get请求,Post请求是解决不了,所以这里把真正的WCF跨域问题贴出来. 话不多说,直接帖配置文件 ...

    SpringBoot基础系列-SpringCache使用

    原创文章,转载请标注出处: 一.概述 SpringCache本身是一个缓存体系的抽象实现,并没有具体的缓存能力,要使用Sprin ...

    Linux-系统调用理解

    系统调用即为Linux内核中设置的一组用于实现各种系统功能的子程序,操作系统通过系统调用为运行在其上的进程提供服务. 由于进程一般不能访问内核所占内存空间以及调用内核函数,为了与用户态进程进行交互,内 ...

    &commat;Value&lpar;&quot&semi;&dollar;&lbrace;xxxx&rcub;&quot&semi;&rpar;注解的配置及使用

    代码中的用法 Spring 通过@Value注解获取*.porperties文件code的内容,然后赋值给使用该注解的Code属性上. @Value("${code}") priv ...

    django 之Paginator

    Django自身提供了一些类来实现管理分页,数据被分在不同的页面中,并带有“上一页/下一页”标签.这个类叫做Pagination,其定义位于 django/core/paginator.py 中. p ...

    Model操作补充

    参考: http://www.cnblogs.com/wupeiqi/articles/6216618.html

    展开全文
  • 文章转自...自从API 8后也就是Android2.2后,我们能使APK安装到外部存储上。这是一个可选的特性,在工程的manifest文件中可以进行配置: xmlns:android="http://schemas....

    文章转自http://blog.csdn.net/ryantang03/article/details/8756261

    Android应用可以安装在本机自带存储,同时也可以安装到外部存储(SD卡)。自从API 8后也就是Android2.2后,我们能使APK安装到外部存储上。这是一个可选的特性,在工程的manifest文件中可以进行配置:

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:installLocation="preferExternal"

    ... >

    如上,如果声明为preferExternal,则指定APK安装到外部存储上,但是系统不保证一定能安装到外部存储上,所以叫preferExternal,例如当外部存储空间已经满了,这时系统会将应用程序安装到内部存储上。用户能够在内部存储与外部存储之间移动应用程序。还有一种声明选择,那就是“auto”,如果将属性值声明为这个,安装位置将由系统去决定。

    想要将应用程序安装到外部存储上,需要保证以下条件都满足:

    1.在manifest文件中指定android:installLocation属性值为“preferExternal”或“auto";

    2.确保当前系统API级别为8或以上,android:minSdkVersion值必须是8以上(Android 2.2);

    需要特别注意的是,用户连接手机到PC并开启大容量存储模式时,也就是读取外部存储卡内容时,所有安装到外部存储的应用程序将会被系统全部杀掉!

    如果你的应用中存在在以下情况下,应用程序不推荐安装到外部存储上:

    1.应用程序中有运行后台Service

    2.注册了通知服务例如AlarmManager

    3.第三方输入法,如果将第三方输入法安装到外部存储上,如果当前外部存储被挂起,则第三方输入法会失效并切回系统输入法

    4.墙纸主题应用,外部存储被挂起时,会切换为系统默认墙纸或主题

    5.App桌面组件工具,外部存储被挂起是,会将Widgets从桌面移除

    6.注册了开机广播的应用,因为系统是先发出开机广播然后再加载外部存储设备的,这里有个顺序问题

    展开全文
  • 转:https://blog.csdn.net/luoguopeng/article/details/72832567android app目录: SDCard/Android/data/你的应用的包名/原来,只要把文件写在这里的话,可以不用动态申请权限,只要在manifest里面声明权限就ok了;...
  • 我已经解决了:我使用qt rcc tool将包含大文件的qrc转换为二进制文件,然后使用以下代码从Qt Android Activity调用正确的方法并检索扩展文件的正确路径:QAndroidJniObject mediaDir = QAndroidJniObject::...
  • 1.下载adb.exe 链接: https://pan.baidu.com/s/1g9HOaKrz4_Y6WWwGCo14Cg 提取码: 6v84 复制这段内容后打开百度网盘手机App,...6.然后打开手机你的App CMD界面,cmp= 后面的值就是 包名/activity名称 例如: cmp=com.s
  • Android app 安装目录知识

    千次阅读 2021-06-02 17:36:52
    我们都知道android app有两个安装路径,一个是system/app目录,这个就是所谓的系统应用,只有获得root权限才能删除这个目录下的应用,另一个是data/app目录,用户安装的应用都在这个目录下。几个认知(1)同一个包名的...
  • 通过Environment获取的路径Environment.getDataDirectory().getPath() : 获得根目录/data 内部存储路径Environment.getDownloadCacheDirectory().getPath() : 获得缓存目录/cacheEnvironme...
  • Android的每个应用程序,都有自己的可控的目录。在Setting/Application info里面,可以看到每个应用程序,都有Clear data和Clear cache选项。具体这些目录在哪里呢?用adb连接上设备。如果是连接真实设备,需要有...
  • [干货]手把手教你写一个安卓app

    万次阅读 多人点赞 2021-04-27 21:06:49
    我想大家是想写一个手机app吧,前面已经分享了在QT上如何写一个安卓蓝牙app,虽然qt可以做app但是比起Android Studio还是差很多了!这里我们介绍一种快速入门的方法来制作一款app,就算你是零基础小白没有学习过java...
  • 自定义路径:在sdcard自定义路径(app数据不会随app的删除而删除) SimpleDateFormat df = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");//设置日期格式 //在sdcard自定义路径(app数据不会随app的删除而删除) ...
  • = /data/data/com.my.app/databases/test getDir(“test”, Context.MODE_PRIVATE) = /data/data/com.my.app/app_test getExternalCacheDir() = /mnt/sdcard/Android/data/com.my.app/cache getExternalFilesDir(...
  • 绝对路径和相对路径的区别:绝对路径:D:\Java\main\MainActivity.java,这种能看的懂得。相对路径:相对于项目来说,位于某某某个地方的地址,看不懂的。。。。。我也不知道咋解释。会把 ..\ 、.\ 这样的符号解析掉...
  • 网页打开Android APP

    2021-06-05 18:48:06
    原理解析在Android平台而言,URI主要分三个部分:scheme,...格式如下:://:[||]对应的manifest中的配置如下:android:mimeType=""android:path=""android:pathPattern=""android:pathPrefix=""android:port=""andr...
  • 安卓常见文件路径

    2021-05-27 07:28:11
    安卓文件路径非常容易记混,现记录如下,方便以后查看1.外部存储和内部存储的区别Internal storage:总是可用的这里的文件默认只能被我们的app所访问。当用户卸载app的时候,系统会把internal内该app相关的文件都清除...
  • Android储存路径

    2021-06-03 03:07:00
    前一个项目针对App自动更新,需要下载apk文件并进行安装,在下载文件的过程中,涉及到了android文件存储的一些知识,现对于文件储存做了以下的汇总。首先列出了一个总体的印象图:(请原谅我是一个试用版用户= =)...
  • Android 文件存放路径和读取方式

    千次阅读 2021-06-02 17:56:02
    另外,Android还对创建缓存提供了支持,通过getCacheDir()可以获取应用的缓存路径,在系统可用空间不足时,Android会清空缓存,但对于开发者而言,不应维护过多的缓存。用户可以通过系统的设置来手动清空缓存,有人...
  • Android Studio开发实战:从零基础到App上线》自面世以来,承蒙众多朋友的抬爱,该书一直保持不错的销量,其中第一版的出货量突破一万,第二版的出货量即将突破两万。对于一个程序员来说,这是对其劳动成果的极大...
  • Android app更新适配安卓10、11版本

    千次阅读 2021-03-25 17:59:15
    Android app内部更新适配安卓10、11版本 前言 ​ App内部更新现在基本每个app中都有,由于安卓各大应用市场不统一,不像Ios那样只有一个应用商城。并且现在安卓已经更新到11版本了,中间有几个版本还需对App内部更新...
  • 开发一款Android App,从零开始详细讲解

    万次阅读 多人点赞 2021-03-04 17:16:38
    入门篇:第一篇:开发环境篇第二篇:材料设计篇第三篇:规范开发篇第四篇:从项目开发到上架篇...功能很简单,利用豆瓣电影Api实现一款基于Android的电影集合的App。star me on GitHub! 该项目的数据源来自于豆瓣;
  • android存储路径详解

    2021-04-20 17:52:04
    前两天因为开发一个app更新的功能,我将从服务器下载的apk文件放在了内部存储目录(测试手机为小米,路径为:data/user/0/packagename/files)下面,然后安装的时候一直安装不了,提示解析包出错。后来查询发现,...
  • Android安卓APP渗透测试-总结

    千次阅读 2021-01-05 15:30:14
    文章目录基础知识安卓系统目录结构组件基础APK目录结构ADB使用Drozer客户端安全测试反编译测试(脱壳与混淆)脱壳回编译测试本地敏感信息存储四大组件安全本地注入动/静态扫描安全的通信方式HOOK开源移动端扫描工具...
  • Android APP 渗透测试方法大全by backlion一、Android APP 渗透测试方法1.测试环境SDK : J a JDK , Android SDK。工具: 7zip, dex2jar ,jd -gui, apktool, IDA pro (6.1), ApkAnalyser , Eclipse,dexopt-...
  • Delphi 安卓App自动升级

    2021-06-07 15:17:05
    Androidapi.JNI.Support引用这个单元procedure _InstallApk(Apk: string);varLFile: JFile;LIntent: JIntent;beginLFile := TJFile.JavaClass.init(StringToJString(ExtractFilePath(Apk)), StringToJstring...
  • Android app调用动态库so

    2021-05-28 01:26:27
    目标:在Android Studio工程中加入C语言写的动态库so,实现App调用so0. 首先需要下载Android NDK,解压以后,假设路径为/your/path/to/ndk/,里面有一个编译的脚本ndk-build,以及一些例子sample。1. 创建一个C的...
  • Android保存文件到本地路径问题常见路径例如: application包名: com.my.company项目名: chat/data/data == ///data/user/0getExternalFilesDir()方法可以获取到 SDCard/Android/data/你的应用的包名/files/ 目录,...
  • Android实现APP在线下载更新发布时间:2020-09-01 22:54:06来源:脚本之家阅读:217作者:ChatHello前言项目地址:UpdateAppDemo现在的android应用app会隔一段时间发布一个新的版本,当你打开某个app,如果有最新的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 167,091
精华内容 66,836
关键字:

安卓app路径