如何在SD卡上自动创建目录


189

我正在尝试将文件保存到以下位置,
FileOutputStream fos = new FileOutputStream("/sdcard/Wallpaper/"+fileName); 但是却遇到异常,java.io.FileNotFoundException
但是,当我将路径设置为"/sdcard/"有效时。

现在,我假设无法以这种方式自动创建目录。

有人可以建议如何创建directory and sub-directory使用代码吗?

Answers:


449

如果创建一个包装顶级目录的File对象,则可以调用它的mkdirs()方法来构建所有需要的目录。就像是:

// create a File object for the parent directory
File wallpaperDirectory = new File("/sdcard/Wallpaper/");
// have the object build the directory structure, if needed.
wallpaperDirectory.mkdirs();
// create a File object for the output file
File outputFile = new File(wallpaperDirectory, filename);
// now attach the OutputStream to the file object, instead of a String representation
FileOutputStream fos = new FileOutputStream(outputFile);

注意:明智的做法是使用Environment.getExternalStorageDirectory()获取“ SD卡”目录,因为如果随身携带的手机带有SD卡以外的其他东西(例如内置闪存,苹果手机)。无论哪种方式,您都应记住,由于SD卡可能已卸下,因此需要检查以确保它确实存在。

更新:从API级别4(1.6)开始,您还必须请求权限。这样的事情(在清单中)应该起作用:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

1
是的,随后发布的三星平板电脑使用内置闪存
CQM

2
不要忘了向AndroidManifest.xml添加编写stackoverflow.com/a/4435708/579646
max4ever,2012年

1
如果我有一个sub-sub文件夹,如/sdcard/com.my.code/data,它表明这不起作用。我该如何解决?
2012年

除了创建这个目录之外?Unix mkdir中是否有类似“ force”的命令?
2012年

4
在KitKat外部物理sdcard上不起作用。
celoftis 2014年

57

遇到相同的问题,只想添加AndroidManifest.xml也需要此权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

39

这是对我有用的。

 uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" 

在清单和下面的代码中

public static boolean createDirIfNotExists(String path) {
    boolean ret = true;

    File file = new File(Environment.getExternalStorageDirectory(), path);
    if (!file.exists()) {
        if (!file.mkdirs()) {
            Log.e("TravellerLog :: ", "Problem creating Image folder");
            ret = false;
        }
    }
    return ret;
}

path是您要创建的文件夹的名称。如果您发送了类似MusicDownload的路径。它将自动变为/ sdcard / MusicDownload。Shajeel Afzal
shehzy 2015年

它引发异常java.io.IOException:打开失败:ENOENT(没有此类文件或目录)
Anand Savjani

24

实际上,我使用了@fiXedd解决方案的一部分,它对我有用:

  //Create Folder
  File folder = new File(Environment.getExternalStorageDirectory().toString()+"/Aqeel/Images");
  folder.mkdirs();

  //Save the path as a string value
  String extStorageDirectory = folder.toString();

  //Create New file and name it Image2.PNG
  File file = new File(extStorageDirectory, "Image2.PNG");

确保您使用的是mkdirs()而不是mkdir()来创建完整路径


@fixedd答案的“部分”如何?他的答案是使用File.mkdirs()。然后,他展示了一个使用它的示例。
Doomsknight

实际上,我不记得有什么区别,但是我认为有一些编辑...顺便说一句,我提到我使用他的答案来获取解决方案
Amt87 2013年

12

使用API​​ 8和更高版本时,SD卡的位置已更改。@fiXedd的回答很好,但是为了获得更安全的代码,您应该使用该Environment.getExternalStorageState()命令检查媒体是否可用。然后,您可以使用getExternalFilesDir()导航到所需的目录(假设您使用的是API 8或更高版本)。

您可以在SDK文档中阅读更多内容


8

确保存在外部存储:http : //developer.android.com/guide/topics/data/data-storage.html#filesExternal

private boolean isExternalStoragePresent() {

        boolean mExternalStorageAvailable = false;
        boolean mExternalStorageWriteable = false;
        String state = Environment.getExternalStorageState();

        if (Environment.MEDIA_MOUNTED.equals(state)) {
            // We can read and write the media
            mExternalStorageAvailable = mExternalStorageWriteable = true;
        } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            // We can only read the media
            mExternalStorageAvailable = true;
            mExternalStorageWriteable = false;
        } else {
            // Something else is wrong. It may be one of many other states, but
            // all we need
            // to know is we can neither read nor write
            mExternalStorageAvailable = mExternalStorageWriteable = false;
        }
        if (!((mExternalStorageAvailable) && (mExternalStorageWriteable))) {
            Toast.makeText(context, "SD card not present", Toast.LENGTH_LONG)
                    .show();

        }
        return (mExternalStorageAvailable) && (mExternalStorageWriteable);
    }

6

不要忘记确保文件/文件夹名称中没有特殊字符。当我使用变量设置文件夹名称时,出现了“:”

文件/文件夹名称中不允许使用字符

“ * /:<>?\ |

在这种情况下,U可能会发现此代码很有帮助。

以下代码删除了所有“:”并将其替换为“-”

//actualFileName = "qwerty:asdfg:zxcvb" say...

    String[] tempFileNames;
    String tempFileName ="";
    String delimiter = ":";
    tempFileNames = actualFileName.split(delimiter);
    tempFileName = tempFileNames[0];
    for (int j = 1; j < tempFileNames.length; j++){
        tempFileName = tempFileName+" - "+tempFileNames[j];
    }
    File file = new File(Environment.getExternalStorageDirectory(), "/MyApp/"+ tempFileName+ "/");
    if (!file.exists()) {
        if (!file.mkdirs()) {
        Log.e("TravellerLog :: ", "Problem creating Image folder");
        }
    }

+1是,我也尝试过:并出错,最后发现该问题并删除了:和所有其他特殊字符。
Ganapathy C

6

我遇到了同样的问题。Android中有两种类型的权限:

  • 危险(访问联系人,写入外部存储...)
  • 普通 (普通权限由Android自动批准,而危险权限则需要由Android用户批准。)

这是在Android 6.0中获取危险权限的策略

  • 检查您是否已授予权限
  • 如果您的应用已被授予许可,请继续正常执行。
  • 如果您的应用尚未获得许可,请要求用户批准
  • 在听取用户的批准 onRequestPermissionsResult

这是我的情况:我需要写入外部存储。

首先,请检查我是否具有以下权限:

...
private static final int REQUEST_WRITE_STORAGE = 112;
...
boolean hasPermission = (ContextCompat.checkSelfPermission(activity,
            Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
if (!hasPermission) {
    ActivityCompat.requestPermissions(parentActivity,
                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);
    switch (requestCode)
    {
        case REQUEST_WRITE_STORAGE: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                //reload my activity with permission granted or use the features what required the permission
            } else
            {
                Toast.makeText(parentActivity, "The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
            }
        }
    }    
}

5

我遇到了同样的问题,无法在Galaxy S上创建目录,但能够在Nexus和Samsung Droid上成功创建目录。我的解决方法是添加以下代码行:

File dir = new File(Environment.getExternalStorageDirectory().getPath()+"/"+getPackageName()+"/");
dir.mkdirs();

5
File sdcard = Environment.getExternalStorageDirectory();
File f=new File(sdcard+"/dor");
f.mkdir();

这将在您的SD卡中创建一个名为dor的文件夹。然后为手动插入dor文件夹中的eg- filename.json获取文件。喜欢:

 File file1 = new File(sdcard,"/dor/fitness.json");
 .......
 .....

<users-permission android:name =“ android.permission.WRITE_EXTERNAL_STORAGE” />

并且不要忘记在清单中添加代码


4
     //Create File object for Parent Directory
File wallpaperDir = new File(Environment.getExternalStorageDirectory().getAbsoluteFile() +File.separator + "wallpaper");
if (!wallpaperDir.exists()) {
wallpaperDir.mkdir();
}


File out = new File(wallpaperDir, wallpaperfile);
FileOutputStream outputStream = new FileOutputStream(out);

3

刚刚完成了Vijay的帖子...


表现

uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"

功能

public static boolean createDirIfNotExists(String path) {
    boolean ret = true;

    File file = new File(Environment.getExternalStorageDirectory(), path);
    if (!file.exists()) {
        if (!file.mkdirs()) {
            Log.e("TravellerLog :: ", "Problem creating Image folder");
            ret = false;
        }
    }
    return ret;
}

用法

createDirIfNotExists("mydir/"); //Create a directory sdcard/mydir
createDirIfNotExists("mydir/myfile") //Create a directory and a file in sdcard/mydir/myfile.txt

您可以检查错误

if(createDirIfNotExists("mydir/")){
     //Directory Created Success
}
else{
    //Error
}

3

这将使sdcard中的文件夹具有您提供的文件夹名称。

File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Folder name");
        if (!file.exists()) {
            file.mkdirs();
        }

1

您可以使用/ sdcard /代替Environment.getExternalStorageDirectory()

private static String DB_PATH = "/sdcard/Android/data/com.myawesomeapp.app/";

File dbdir = new File(DB_PATH);
dbdir.mkdirs();

4
不,您不应使用硬编码路径,而不能调用适当的API。这样做会导致对特定实现细节的不明智的依赖。
克里斯·斯特拉顿

1
ivmage.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent i = new Intent(
                    Intent.ACTION_PICK,
                    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

            startActivityForResult(i, RESULT_LOAD_IMAGE_ADD);

        }
    });`
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.