Q:

Error con el FileOutputStream

Estoy intentando guardar una imagen de un ImageView en la galería de mi dispositivo móvil y el problema está en que me crea todo el rato el directorio sobre el que quiero guardar la imagen y luego la ruta cuando voy a hacer el FileOutputStream me dice que no existe. Adjunto el código donde me está dando el fallo:
 public void SaveImage(Context context, Bitmap ImageToSave) {

    TheThis = context;
    NameOfFolder = context.getString(R.string.app_name);
    String estado=Environment.getExternalStorageState();
    Boolean sdDisponible=false;
    Boolean sdAccesoEscritura=false;

    if(estado.equals(Environment.MEDIA_MOUNTED)){
        sdDisponible=true;
        sdAccesoEscritura=true;
        Log.v("IMAGEN","true todo");
    }else if(estado.equals(Environment.MEDIA_MOUNTED_READ_ONLY)){
        sdDisponible=true;
        sdAccesoEscritura=false;
    }else{
        sdAccesoEscritura=false;
        sdDisponible=false;
    }

    if(sdDisponible && sdAccesoEscritura) {
        String file_path = Environment.getExternalStorageDirectory().getAbsolutePath() + NameOfFolder;
        String CurrentDateAndTime = getCurrentDateAndTime();
        File dir = new File(file_path);

        if (!dir.exists()) {
            dir.mkdirs();
            Log.v("IMAGEN","crea carpeta");
        }

        File file = new File(dir, NameOfFile + CurrentDateAndTime + ".jpg");
        Log.v("IMAGEN", "Pasa el file");

        try {
            FileOutputStream fOut = new FileOutputStream(file);
            Log.v("IMAGEN", "Pasa el output");

            ImageToSave.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
            Log.v("IMAGEN", "Pasa el output2");
            fOut.flush();
            Log.v("IMAGEN", "Pasa el output3");
            fOut.close();
            Log.v("IMAGEN", "Pasa el output4");
            MediaStore.Images.Media.insertImage(context.getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
            MakeSureFileWasCreatedThenMakeAvabile(file);
            Log.v("IMAGEN", "Pasa el output5");
            AbleToSave();
        } catch (FileNotFoundException e) {
            UnableToSave();
            Log.v("IMAGEN", e.toString());
        } catch (IOException e) {
            UnableToSave();
            Log.v("IMAGEN", e.toString());
        }
    }else{
        UnableToSave();
    }

}

Paso la consola con el Logde hasta donde se ejecuta el código:
08-29 14:28:13.374 8582-8582/es.aandg.demo V/IMAGEN: true todo
08-29 14:28:13.386 8582-8582/es.aandg.demo V/IMAGEN: crea carpeta
08-29 14:28:13.386 8582-8582/es.aandg.demo V/IMAGEN: Pasa el file
08-29 14:28:13.409 8582-8582/es.aandg.demo V/IMAGEN: 
    java.io.FileNotFoundException: /storage/emulated/0Demo/IMG-2017-08-
    29_14-28-
    13.jpg: open failed: ENOENT (No such file or directory)

A:

Si usas mkdirs() para crear el directorio:
 dir.mkdirs();

y comentas que siempre lo esta creando, en realidad lo esta tratando de crear si no existe, el problema aquí es que seguramente no tienes los permisos necesarios, recuerda que el permiso WRITE_EXTERNAL_STORAGE es indispensable.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

de hecho cuando tratas de salvar el archivo, guardarlo en la instancia File, este archivo no existe,
 FileOutputStream fOut = new FileOutputStream(file);

ya que no pudo ser creado, por esta razón tienes el mensaje de error:

open failed: ENOENT (No such file or directory)

Otra razón para que no pueda crear el archivo es  sin duda en donde lo estas generando, en este caso usas 
Environment.getExternalStorageDirectory().getAbsolutePath() 

por lo tanto se crearía dentro de: 
/storage/emulated/0

Es importante agregar un "/" al final para crear correctamente la ruta del folder, de otra forma este también puede ser un problema, esta sería la solución.
String file_path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + NameOfFolder;

Como dato extra, puedes validar la creación del directorio de esta forma, ya que  mkdirs() entrega true si se creo sin problema el directorio, en cualquier otro caso false:
  if (!dir.exists()) {
            String message = dir.mkdirs()?"Se creo carpeta correctamente!": "No se pudo crear =(";
            Log.v("IMAGEN","crea carpeta " + message);
        }

Si usas Android 6.0 o posterior, la petición del permiso debe ser manual, ya que no es suficiente declararlo dentro del archivo AndroidManifest.xml, puedes llamar este método en onCreate() para obtener los permisos:
private void revisaPermisosAlmacenamiento() {
    int permissionCheck = ContextCompat.checkSelfPermission(
            this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
        Log.i("Mensaje", "No se tiene permiso para leer.");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 225);
    } else {
        Log.i("Mensaje", "Se tiene permiso para leer!");
    }
}

revisa esta pregunta:
Error al mostrar el directorio externo de archivos en un AlertDialog en android 6.0 (READ_EXTERNAL_STORAGE / WRITE_EXTERNAL_STORAGE )

