Android Studio(Java)绝对路径访问找不到文件夹问题求助
问题描述
我正在开发一款实现计算功能的Android应用,为验证计算函数的正确性,准备了一系列CSV文件作为测试输入,用于校验输出结果。最初将所有CSV文件存放在Android Studio项目文件夹下名为data的目录中,尝试定位该文件夹并枚举内部所有文件时,程序提示目标文件夹无法找到。
我计划先在PC端完成代码测试,再将应用安装到Android手机上运行,因此代码中直接使用了PC端的本地绝对路径,目前该路径访问失败。相关参考材料包含文件读取代码截图、主活动代码截图、运行输出截图。
原有文件读取代码:
public Object[] createFolderList_rev001() { ArrayList<String> Pelvis_filenames = new ArrayList<String>(); ArrayList<String> R_thigh_filenames = new ArrayList<String>(); ArrayList<String> R_shank_filenames = new ArrayList<String>(); ArrayList<String> L_thigh_filenames = new ArrayList<String>(); ArrayList<String> L_shank_filenames = new ArrayList<String>(); Log.i(TAG, "Folder finding......"); try { //Create a file object File folder = new File("/Users/Aria_Z/AndroidStudioProjects/QZ_APP_V1/app/assets"); if (!folder.exists() || !folder.isDirectory()) { System.out.println("folder cannot found"); Log.i(TAG, "folder not found"); } else { System.out.println("folder exist"); Log.i(TAG, "folder exist"); } //Get all the names of the files present in the given directory File[] files = folder.listFiles(); System.out.println("length: " + files.length); for (int i=0;i<files.length;i++){ if (files[i].getName().contains("D422CD000561")){ Pelvis_filenames.add(files[i].getName()); }else if(files[i].getName().contains("D422CD000566")){ R_thigh_filenames.add(files[i].getName()); }else if(files[i].getName().contains("D422CD000553")){ R_shank_filenames.add(files[i].getName()); }else if (files[i].getName().contains("D422CD00053A")){ L_thigh_filenames.add(files[i].getName()); }else if (files[i].getName().contains("D422CD001764")){ L_shank_filenames.add(files[i].getName()); } } } catch(Exception e){ System.err.println(e.getMessage()); } Object[] folderList = new Object[]{Pelvis_filenames, R_thigh_filenames,R_shank_filenames,L_shank_filenames,L_thigh_filenames}; return folderList; }
原有MainActivity代码:
public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Object[] folderList = createFolderList_rev001(); } }
问题根因
代码中写死的PC本地绝对路径是开发机磁盘上的路径,Android应用运行在模拟器/真机的独立沙箱环境中,没有权限也没有对应路径可以直接访问电脑本地磁盘上的文件,必然提示文件夹找不到。
另外如果将CSV放在app的assets目录下,这个目录的内容会被打包进APK安装包,不会在设备上生成可直接访问的实体文件,不能直接用File类遍历读取。
分场景解决方案
PC端本地单元测试阶段(不启动模拟器/真机,快速验证计算逻辑)
- 将测试用CSV文件放到项目模块的
src/test/resources目录下,没有该目录就手动新建 - 单元测试中通过类加载器读取资源,不需要写死绝对路径,参考代码:
// 单元测试类中读取resources目录下的文件 URL resourceUrl = getClass().getClassLoader().getResource("目标csv文件名.csv"); File csvFile = new File(resourceUrl.getPath()); // 后续可正常遍历、读取文件内容,验证计算逻辑
- 该阶段代码运行在本地PC的JVM环境中,不依赖Android系统环境,测试运行速度快,适合快速校验计算函数正确性。
Android设备/模拟器运行阶段
- 将所有CSV测试文件放到
app/src/main/assets目录下,没有assets目录就右键app模块,依次选择New -> Folder -> Assets Folder 完成创建 - Android环境下不能直接用
File类访问assets内的资源,需要通过AssetManager完成枚举、读取操作,参考遍历代码:
// 在Activity中调用,遍历assets目录下的csv文件 try { AssetManager assetManager = getAssets(); // 传入空字符串表示遍历assets根目录,存在子目录则传入对应子目录路径 String[] fileList = assetManager.list(""); ArrayList<String> Pelvis_filenames = new ArrayList<>(); ArrayList<String> R_thigh_filenames = new ArrayList<>(); ArrayList<String> R_shank_filenames = new ArrayList<>(); ArrayList<String> L_thigh_filenames = new ArrayList<>(); ArrayList<String> L_shank_filenames = new ArrayList<>(); for (String fileName : fileList) { if (fileName.endsWith(".csv")) { if (fileName.contains("D422CD000561")){ Pelvis_filenames.add(fileName); // 读取文件内容时,调用assetManager.open(fileName)即可获取对应文件输入流 }else if(fileName.contains("D422CD000566")){ R_thigh_filenames.add(fileName); }else if(fileName.contains("D422CD000553")){ R_shank_filenames.add(fileName); }else if (fileName.contains("D422CD00053A")){ L_thigh_filenames.add(fileName); }else if (fileName.contains("D422CD001764")){ L_shank_filenames.add(fileName); } } } } catch (IOException e) { e.printStackTrace(); }
- 如果后续需要将CSV存放到设备存储中访问,不要写死固定路径,通过Android官方API获取合法路径,比如调用
context.getExternalFilesDir()获取应用专属外部存储目录,再将CSV文件推送到对应目录后读取。
原有代码问题说明
- 写死的
/Users/Aria_Z/AndroidStudioProjects/QZ_APP_V1/app/assets是Mac开发机上的本地路径,Android系统基于Linux内核,不存在该路径,必然判定文件夹不存在 - 即使用模拟器运行,也无法直接通过PC本地路径访问文件,必须使用Android系统可识别的合法路径
- assets目录内的资源打包后位于APK压缩包内部,不会在设备上解压为独立文件,
File类无法直接识别遍历,必须通过AssetManager访问。
内容的提问来源于stack exchange,提问作者Aria_Z
相关产品推荐
相关产品推荐

