/*
* Copyright (C) 2011 The original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.zapta.apps.maniana.util;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.annotation.Nullable;
import android.content.Context;
import android.graphics.Bitmap;
import com.zapta.apps.maniana.annotations.ApplicationScope;
import com.zapta.apps.maniana.util.FileUtil.FileReadResult.FileReadOutcome;
/**
* File read/write utils.
*
* @author Tal Dayan
*/
@ApplicationScope
public final class FileUtil {
/** Do not instantiate */
private FileUtil() {
}
/** The result of a file read operation. */
public static class FileReadResult {
public static enum FileReadOutcome {
READ_OK,
NOT_FOUND,
READ_ERROR;
public final boolean isOk() {
return this == READ_OK;
}
}
public final FileReadOutcome outcome;
@Nullable
public final String content;
private FileReadResult(FileReadOutcome outcome, @Nullable String content) {
this.outcome = outcome;
this.content = content;
}
}
/**
* Read a file into a string.
*
* @param context the activity context.
* @param fileName the file name.
* @param isAsset if true, the file is an asset file. Otherwise, it is a private app file.
*/
@Nullable
public static FileReadResult readFileToString(Context context, String fileName, boolean isAsset) {
// Open
final InputStream in;
try {
in = isAsset ? context.getAssets().open(fileName) : context.openFileInput(fileName);
} catch (IOException e) {
// This is normal when opening the file after first installation since it
// does not exist.
LogUtil.warning(e, "Error opening a file");
return new FileReadResult(FileReadOutcome.NOT_FOUND, null);
}
// This always closes in.
return readFileToString(in, fileName);
}
/**
* Read a file into a string. Upon return, in is guaranteed to be closed.
*/
@Nullable
public static FileReadResult readFileToString(InputStream in, String fileDescription) {
// Read
try {
final ByteArrayOutputStream builder = new ByteArrayOutputStream();
final byte bfr[] = new byte[100];
for (;;) {
final int n = in.read(bfr);
if (n < 1) {
break;
}
builder.write(bfr, 0, n);
}
return new FileReadResult(FileReadOutcome.READ_OK, builder.toString());
} catch (IOException e) {
LogUtil.error(e, "Error reading file %s", fileDescription);
return new FileReadResult(FileReadOutcome.READ_ERROR, null);
} finally {
// Close
try {
in.close();
} catch (IOException e) {
LogUtil.error("Failed to close file from reading: " + fileDescription);
}
}
}
/** Write a string to a file */
public static void writeStringToFile(Context context, String content, String fileName,
int contextMode) {
FileOutputStream out = null;
try {
out = context.openFileOutput(fileName, contextMode);
out.write(content.getBytes());
} catch (Exception e) {
// TODO: more graceful error handling?
throw new RuntimeException(e);
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
LogUtil.error(e, "Error closing written model file: " + fileName);
}
}
}
}
/** Write a bitmap to a file */
public static void writeBitmapToPngFile(Context context, Bitmap bitmap, String fileName,
boolean isPublic) {
FileOutputStream out = null;
try {
final int permission = isPublic ? Context.MODE_WORLD_READABLE : Context.MODE_PRIVATE;
out = context.openFileOutput(fileName, permission);
final boolean ok = bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
if (!ok) {
throw new RuntimeException("Error writing bitmap to file: " + fileName);
}
} catch (Exception e) {
// TODO: more graceful error handling?
throw new RuntimeException(e);
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
LogUtil.error(e, "Error closing written bitmap file: " + fileName);
}
}
}
}
/**
* Path is relative to .../assets/.
* If not null, caller should eventually close the returned stream.
*/
@Nullable
public static InputStream openAssert(Context context, String path) {
try {
return context.getAssets().open(path);
} catch (IOException e) {
LogUtil.info("Asset %s did not open (%s)", path, e.getClass().getSimpleName());
return null;
}
}
}