Ошибка: open failed: ENOENT (Нет такого файла или каталога)
Я пытался создать файл для сохранения фотографий с камеры, оказалось, что я не могу создать файл. Но я действительно не могу найти ошибку. Можете ли вы взглянуть на нее и дать мне несколько советов?
private File createImageFile(){
File imageFile=null;
String stamp=new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File dir= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String imageFileName="JPEG_"+stamp+"_";
try {
imageFile=File.createTempFile(imageFileName,".jpg",dir);
} catch (IOException e) {
Log.d("YJW",e.getMessage());
}
return imageFile;
}
И я добавил разрешение.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Метод всегда дает такие ошибки:
open failed: ENOENT (Нет такого файла или каталога)
Ответы
Ответ 1
Возможно, каталог "Фотографии" еще не существует. Это не гарантировано.
В документации API для getExternalStoragePublicDirectory()
код гарантирует, что каталог существует с помощью mkdirs
:
File path = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File file = new File(path, "DemoPicture.jpg");
try {
// Make sure the Pictures directory exists.
path.mkdirs();
... так что это может быть так же просто, как добавить этот path.mkdirs()
в ваш существующий код перед createTempFile
.
Ответ 2
Заменить:
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
С:
private File createImageFile() throws IOException {
// Create an image file name
убедитесь, что вы звоните:
mkdirs() // and not mkdir()
Вот код, который должен работать для вас:
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = new File(Environment.getExternalStorageDirectory().toString(), "whatever_directory_existing_or_not/sub_dir_if_needed/");
storageDir.mkdirs(); // make sure you call mkdirs() and not mkdir()
File image = File.createTempFile(
imageFileName, // prefix
".jpg", // suffix
storageDir // directory
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
Log.e("our file", image.toString());
return image;
}
У меня был плохой опыт следования примеру, приведенному в документации Android Studio, и я обнаружил, что многие другие испытывают то же самое по этой конкретной теме здесь в stackoverflow, потому что даже если мы установим
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
проблема сохраняется в некоторых устройствах.
По моему опыту, этот пример работал, когда я попробовал его в режиме отладки, после того, как прошло еще 3 теста, так случилось, что моя SD внезапно повредилась, но я не думаю, что это связано с их примером (забавно). Я купил новую SD-карту и попробовал ее снова, только чтобы понять, что все еще и режим выпуска, и режим отладки делали один и тот же журнал ошибок: каталог не существует ENOENT. Наконец, мне пришлось самому создавать каталоги, которые будут содержать захваченные снимки с камеры телефона. И я был прав, это работает просто отлично.
Я надеюсь, что это поможет вам и другим людям в поисках ответов.
Ответ 3
Я использовал contentResolver с URI, и это сработало для меня. Увидел его в другом столбце, который я не могу найти.
private String getRealPathFromURI(Uri contentURI) {
String result;
Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) {
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
Надеюсь, поможет....
Ответ 4
Я решил так:
public Intent getImageCaptureIntent(File mFile) {
Intent mIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri photoURI = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", mFile);
mIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
// The tip is this code below
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(mIntent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
grantUriPermission(packageName, photoURI, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
return mIntent;
}
Ответ 5
Попробуй это:
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName="JPEG_"+stamp+".jpg";
File photo = new File(Environment.getExternalStorageDirectory(), imageFileName);
return photo;
}
Ответ 6
У меня точно такая же проблема, может быть файл в галерее является миниатюрой. и кэш миниатюр не обновлен. так что получить файл не найден исключение
Ответ 7
Если вы используете kotlin, используйте функцию ниже.
Вы должны указать путь для сохранения изображения, Растровое изображение (в данном случае изображение), и если вы хотите снизить качество изображения, укажите% age, то есть 50%.
fun cacheLocally(localPath: String, bitmap: Bitmap, quality: Int = 100) {
val file = File(localPath)
file.createNewFile()
val ostream = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, ostream)
ostream.flush()
ostream.close()
}
надеюсь, что это сработает.