Androidアプリケーションでファイルコンテンツをバイト単位で取得しようとしています。SDカードでファイルを取得しました。選択したファイルをバイト単位で取得したいと思います。
以下は、拡張子を持つファイルを取得するコードです。これにより、ファイルを取得し、スピナーで表示します。ファイルの選択では、バイト単位でファイルを取得します。
private List<String> getListOfFiles(String path) {
File files = new File(path);
FileFilter filter = new FileFilter() {
private final List<String> exts = Arrays.asList("jpeg", "jpg", "png", "bmp", "gif","mp3");
public boolean accept(File pathname) {
String ext;
String path = pathname.getPath();
ext = path.substring(path.lastIndexOf(".") + 1);
return exts.contains(ext);
}
};
final File [] filesFound = files.listFiles(filter);
List<String> list = new ArrayList<String>();
if (filesFound != null && filesFound.length > 0) {
for (File file : filesFound) {
list.add(file.getName());
}
}
return list;
}
ここでは簡単です:
File file = new File(path);
int size = (int) file.length();
byte[] bytes = new byte[size];
try {
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
buf.read(bytes, 0, bytes.length);
buf.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Manifest.xmlに許可を追加します。
<uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE" />
ファイル全体が確実に読み込まれることを保証し、ライブラリを必要とせず効率的なソリューションを次に示します。
byte[] fullyReadFileToBytes(File f) throws IOException {
int size = (int) f.length();
byte bytes[] = new byte[size];
byte tmpBuff[] = new byte[size];
FileInputStream fis= new FileInputStream(f);;
try {
int read = fis.read(bytes, 0, size);
if (read < size) {
int remain = size - read;
while (remain > 0) {
read = fis.read(tmpBuff, 0, remain);
System.arraycopy(tmpBuff, 0, bytes, size - remain, read);
remain -= read;
}
}
} catch (IOException e){
throw e;
} finally {
fis.close();
}
return bytes;
}
注:ファイルサイズがMAX_INTバイト未満であると想定していますが、必要に応じてその処理を追加できます。
今日最も簡単な解決策は、Apache common ioを使用することです:
byte bytes[] = FileUtils.readFileToByteArray(photoFile)
唯一の欠点は、この依存関係をbuild.gradle
アプリに追加することです:
implementation 'commons-io:commons-io:2.5'
+ 1562メソッドのカウント
受け入れられたBufferedInputStream#read
はすべてを読み取ることが保証されているわけではなく、自分でバッファサイズを追跡するのではなく、このアプローチを使用しました。
byte bytes[] = new byte[(int) file.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
DataInputStream dis = new DataInputStream(bis);
dis.readFully(bytes);
完全な読み取りが完了するまでブロックし、追加のインポートは不要です。
このためにコンテキストからopenFileInput
メソッドを使用する場合は、次のコードを使用できます。
これにより、BufferArrayOutputStream
が作成され、ファイルから読み取られた各バイトが追加されます。
/**
* <p>
* Creates a InputStream for a file using the specified Context
* and returns the Bytes read from the file.
* </p>
*
* @param context The context to use.
* @param file The file to read from.
* @return The array of bytes read from the file, or null if no file was found.
*/
public static byte[] read(Context context, String file) throws IOException {
byte[] ret = null;
if (context != null) {
try {
InputStream inputStream = context.openFileInput(file);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
int nextByte = inputStream.read();
while (nextByte != -1) {
outputStream.write(nextByte);
nextByte = inputStream.read();
}
ret = outputStream.toByteArray();
} catch (FileNotFoundException ignored) { }
}
return ret;
}
単純なInputStreamでできます
byte[] fileToBytes(File file){
byte[] bytes = new byte[0];
try(FileInputStream inputStream = new FileInputStream(file)) {
bytes = new byte[inputStream.available()];
//noinspection ResultOfMethodCallIgnored
inputStream.read(bytes);
} catch (IOException e) {
e.printStackTrace();
}
return bytes;
}
次の方法でもできます。
byte[] getBytes (File file)
{
FileInputStream input = null;
if (file.exists()) try
{
input = new FileInputStream (file);
int len = (int) file.length();
byte[] data = new byte[len];
int count, total = 0;
while ((count = input.read (data, total, len - total)) > 0) total += count;
return data;
}
catch (Exception ex)
{
ex.printStackTrace();
}
finally
{
if (input != null) try
{
input.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
return null;
}
以下は、ファイル全体をチャンクで読み取る実用的なソリューションと、スキャナークラスを使用して大きなファイルを読み取る効率的なソリューションです。
try {
FileInputStream fiStream = new FileInputStream(inputFile_name);
Scanner sc = null;
try {
sc = new Scanner(fiStream);
while (sc.hasNextLine()) {
String line = sc.nextLine();
byte[] buf = line.getBytes();
}
} finally {
if (fiStream != null) {
fiStream.close();
}
if (sc != null) {
sc.close();
}
}
}catch (Exception e){
Log.e(TAG, "Exception: " + e.toString());
}