You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中FileWriter无法创建文件,请求排查异常原因

解决Android中FileWriter创建失败的问题

看起来你在尝试用FileWriter写入传感器数据时踩了Android存储权限和路径的常见坑,我来帮你一步步解决这个问题:

核心问题分析

你的代码主要有三个关键问题导致FileWriter创建失败:

  • 路径无效:直接使用"mySensorData.txt"作为路径,FileWriter会尝试写入App的默认工作目录,这个目录通常没有写入权限;而且你onCreate里的路径还多了个空格" \filename.txt",进一步导致路径无效。
  • 权限缺失:Android 6.0(API 23)及以上版本,写入外部存储需要动态申请WRITE_EXTERNAL_STORAGE权限;Android 10(API 29)及以上的分区存储机制,还限制了直接写入外部根目录的操作。
  • 资源管理不规范:没有确保FileWriter在异常情况下也能被关闭,存在资源泄漏风险。

修改后的完整代码

package com.example.jiajunyang.bowdetection;

import android.Manifest;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements SensorEventListener {
    // 权限申请请求码
    private static final int REQUEST_WRITE_STORAGE = 1001;
    // 目标文件对象(使用应用专属外部存储目录)
    private File destFile;

    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化目标文件:应用专属外部存储的Documents目录下
        File externalFilesDir = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
        if (externalFilesDir != null) {
            destFile = new File(externalFilesDir, "mySensorData.txt");
            Log.d("TAG", "目标文件路径:" + destFile.getAbsolutePath());
        } else {
            Toast.makeText(this, "无法获取有效存储目录", Toast.LENGTH_SHORT).show();
        }

        // 提前检查并申请存储权限
        checkStoragePermission();
    }

    // 检查并申请存储权限
    private void checkStoragePermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        REQUEST_WRITE_STORAGE);
            }
        }
    }

    // 处理权限申请结果
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_WRITE_STORAGE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "存储权限已获取", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "需要存储权限才能写入数据", Toast.LENGTH_SHORT).show();
            }
        }
    }

    public void onStartClick(View view) {
        // 前置检查:文件是否初始化成功
        if (destFile == null) {
            Toast.makeText(this, "目标文件初始化失败", Toast.LENGTH_SHORT).show();
            return;
        }

        // 前置检查:权限是否已获取(针对Android 6.0+)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "请先授予存储权限", Toast.LENGTH_SHORT).show();
                checkStoragePermission();
                return;
            }
        }

        FileWriter writer = null;
        try {
            // 通过File对象创建FileWriter,确保路径有效
            writer = new FileWriter(destFile, true);
            Toast.makeText(getApplicationContext(), "开始写入数据", Toast.LENGTH_SHORT).show();
            writer.write("hi \n");
            writer.write("hi \n");
            writer.write("hi \n");
            writer.flush();
            Toast.makeText(getApplicationContext(), "写入成功", Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            // 显示具体错误信息,方便调试
            Toast.makeText(getApplicationContext(), "写入失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
            Log.e("FILE_WRITE_ERROR", "写入异常详情", e);
        } finally {
            // 确保FileWriter无论是否异常都能关闭,避免资源泄漏
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        // 后续可以在这里处理传感器数据,写入到destFile中
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {
        // 传感器精度变化的处理逻辑
    }
}

关键修改说明

  1. 使用合规的存储路径
    用getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)获取应用专属的外部存储目录,这个目录:

    • Android 10+不需要额外权限
    • 卸载App时会自动删除,不会残留垃圾文件
    • 符合Android官方的存储规范
  2. 完善权限处理
    针对Android 6.0+版本添加了动态权限申请逻辑,确保写入文件前拥有足够的权限。

  3. 优化错误处理

    • 增加了文件初始化和权限的前置检查,提前拦截无效操作
    • 把异常信息打印到Log中,方便定位具体问题
    • 在finally块中关闭FileWriter,避免IO资源泄漏

额外注意事项

  • 如果需要将文件共享给其他App,Android 10+建议使用MediaStore或存储访问框架(SAF),不要直接写入公共目录
  • 测试时确保设备外部存储可用(内部存储有剩余空间或SD卡正常)

内容的提问来源于stack exchange,提问作者J_yang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:38:23