package com.kenny.openimgur.util;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import com.kenny.openimgur.classes.ImgurPhoto;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by kcampagna on 6/22/14.
*/
public class FileUtil {
private static final String TAG = "FileUtil";
public static final String EXTENSION_JPEG = ".jpeg";
public static final String EXTENSION_PNG = ".png";
public static final String EXTENSION_GIF = ".gif";
public static final String EXTENSION_MP4 = ".mp4";
private static final String FOLDER_NAME = "Opengur";
/**
* Saves a url to a given file
*
* @param url The url to save
* @param file The file to save to
* @return If successful
*/
public static boolean saveUrl(String url, @NonNull File file) {
if (TextUtils.isEmpty(url)) {
return false;
}
if (file.exists()) {
file.delete();
}
InputStream in;
try {
in = new URL(url).openStream();
} catch (IOException e) {
LogUtil.e(TAG, "Unable to open stream from url", e);
return false;
}
return writeInputStreamToFile(in, file);
}
/**
* Writes an input stream to a file. The input stream will be closed.
*
* @param in
* @param file
* @return
*/
public static boolean writeInputStreamToFile(@NonNull InputStream in, @NonNull File file) {
BufferedOutputStream buffer = null;
boolean didFinish = false;
try {
buffer = new BufferedOutputStream(new FileOutputStream(file));
byte byt[] = new byte[1024];
int i;
for (long l = 0L; (i = in.read(byt)) != -1; l += i) {
buffer.write(byt, 0, i);
}
buffer.flush();
didFinish = true;
} catch (IOException e) {
LogUtil.e(TAG, "Error saving photo", e);
didFinish = false;
} finally {
closeStream(in);
closeStream(buffer);
}
return didFinish;
}
/**
* Returns a human readable file size
*
* @param bytes
* @param si
* @return
*/
public static String humanReadableByteCount(long bytes, boolean si) {
int unit = si ? 1000 : 1024;
if (bytes < unit) return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(unit));
String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
}
/**
* Returns the file size of the directory
*
* @param directory
* @return
*/
public static long getDirectorySize(File directory) {
if (!isFileValid(directory) || !directory.isDirectory()) {
return 0;
}
long size = 0;
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
if (!file.isDirectory()) size += file.length();
}
}
return size;
}
/**
* Creates a new file
*
* @param extension The extension of the file
* @return
*/
public static File createFile(String extension) {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), FOLDER_NAME);
dir.mkdirs();
File file = new File(dir.getAbsolutePath(), timeStamp + extension);
try {
if (file.createNewFile()) {
return file;
}
} catch (Exception e) {
LogUtil.e(TAG, "Error creating file", e);
}
return null;
}
/**
* Takes a Uri and saves it to a file
*
* @param uri
* @param context
* @return
*/
public static File createFile(Uri uri, @NonNull Context context) {
InputStream in;
ContentResolver resolver = context.getContentResolver();
String type = resolver.getType(uri);
String extension;
if (ImgurPhoto.IMAGE_TYPE_GIF.equals(type)) {
extension = EXTENSION_GIF;
} else if (ImgurPhoto.IMAGE_TYPE_PNG.equals(type)) {
extension = EXTENSION_PNG;
} else {
extension = EXTENSION_JPEG;
}
try {
in = resolver.openInputStream(uri);
} catch (FileNotFoundException e) {
LogUtil.e(TAG, "Unable to open input stream", e);
return null;
}
// Create files from a uri in our cache directory so they eventually get deleted
String timeStamp = String.valueOf(System.currentTimeMillis());
File cacheDir = ImageUtil.getImageLoader(context).getDiskCache().getDirectory();
File tempFile = new File(cacheDir, timeStamp + extension);
if (writeInputStreamToFile(in, tempFile)) {
return tempFile;
} else {
// If writeInputStreamToFile fails, delete the excess file
tempFile.delete();
}
return null;
}
/**
* Tells the Media Scanner that a new file is present
*
* @param file
* @param context
*/
public static void scanFile(Uri file, Context context) {
Intent scan = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
scan.setData(file);
context.sendBroadcast(scan);
}
/**
* Tells the Media Scanner to scan an entire directory if present
*
* @param directory
* @param context
*/
public static void scanDirectory(@Nullable File directory, Context context) {
if (isFileValid(directory) && directory.isDirectory()) {
File[] files = directory.listFiles();
if (files != null) {
for (File f : files) {
scanFile(Uri.fromFile(f), context);
}
}
}
}
/**
* Returns if the given file is not null and exists in the file system
*
* @param file
* @return
*/
public static boolean isFileValid(@Nullable File file) {
return file != null && file.exists();
}
/**
* Closes a stream of data
*
* @param closeable
*/
public static void closeStream(@Nullable Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ex) {
LogUtil.e(TAG, "Unable to close stream", ex);
}
}
}
/**
* Copies one file to another
*
* @param sourceFile The file to copy
* @param destFile The destination file to copy to
* @return If successful
*/
public static boolean copyFile(File sourceFile, File destFile) {
if (isFileValid(destFile)) {
destFile.delete();
}
FileChannel source = null;
FileChannel destination = null;
boolean success = false;
try {
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();
destination.transferFrom(source, 0, source.size());
success = true;
} catch (Exception e) {
LogUtil.e(TAG, "Error whiling copying file", e);
success = false;
} finally {
closeStream(source);
closeStream(destination);
}
return success;
}
/**
* Deletes all the files in a given directory
*
* @param dir
*/
public static void deleteDirectory(File dir) {
if (isFileValid(dir) && dir.isDirectory()) {
File[] files = dir.listFiles();
if (files != null && files.length > 0)
for (File f : files) {
f.delete();
}
}
}
}