SD 카드에서 자동으로 디렉토리를 만드는 방법


189

파일을 다음 위치에 저장하려고하는데
FileOutputStream fos = new FileOutputStream("/sdcard/Wallpaper/"+fileName); 예외가 발생합니다. java.io.FileNotFoundException
그러나 경로를 다음과 같이 입력하면"/sdcard/" 작동 합니다.

이제는이 방법으로 디렉토리를 자동으로 만들 수 없다고 가정합니다.

누군가가 directory and sub-directory사용 코드 를 만드는 방법을 제안 할 수 있습니까 ?

답변:


449

당신이 작성하는 경우 파일의 최상위 디렉토리를 래핑 개체를 당신은 그것의 호출 할 수 있습니다 () 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);

참고 : "SD 카드"디렉토리를 가져 오기 위해 Environment.getExternalStorageDirectory () 를 사용하는 것이 현명 할 수 있습니다. 전화기가 SD 카드 이외의 다른 장치 (예 : 내장 플래시, iPhone). 어느 쪽이든 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

1
/sdcard/com.my.code/data와 같은 하위 하위 폴더가 있으면 작동하지 않습니다. 어떻게 해결할 수 있습니까?
lony

이 디렉토리를 만드는 것 외에도? 유닉스 mkdir에 'force'와 같은 명령이 있습니까?
lony

4
외부 물리적 SD 카드 인 KitKat에서는 작동하지 않습니다.
celoftis

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

그것은 예외 때 java.io.IOException를 던졌습니다 : 개방 실패 : ENOENT (해당 파일 또는 디렉토리)
아난드 Savjani에게

24

실제로 나는 @fiXedd asnwer의 일부를 사용했고 그것은 나를 위해 일했다 :

  //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");

전체 경로를 작성하기 위해 mkdir ()이 아닌 mkdirs ()를 사용하고 있는지 확인하십시오.


@fixedd 의이 "부분"은 어떻게 대답합니까? 그의 대답은를 사용하는 것이었다 File.mkdirs(). 그런 다음 그것을 사용하는 예를 보여주었습니다.
Doomsknight

실제로 차이점이 무엇인지 기억할 수 없지만 몇 가지 수정 사항이 있다고 생각합니다 ... 내가 대답을 얻기 위해 그의 대답을 사용했다고 언급 한 것처럼
Amt87

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

파일 / 폴더 이름에 특수 문자가 없는지 확인하십시오. 변수를 사용하여 폴더 이름을 설정할 때 ":"로 나에게 일어났습니다.

파일 / 폴더 이름에 허용되지 않는 문자

"* / : <>? \ |

이런 경우이 코드가 도움이 될 수 있습니다.

아래 코드는 모든 ":"를 제거하고 "-"로 바꿉니다.

//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();

sdcard에 dor라는 폴더가 생성됩니다. 그런 다음 dor 폴더에 수동으로 삽입 된 eg- filename.json에 대한 파일을 가져옵니다 . 처럼:

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

<uses-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

Environment.getExternalStorageDirectory () 대신 / sdcard /를 사용할 수 있습니다.

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

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

4
아니요, 적절한 API를 호출하는 대신 하드 코딩 된 경로를 사용해서는 안됩니다. 그렇게하면 특정 구현의 세부 사항에 대한 현명하지 않은 의존이 발생합니다.
Chris Stratton

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);

        }
    });`
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.