インターネットからファイルをダウンロードして、ストリーミングデータをアプリの内部ストレージの一時ファイルに getFilesDir() で指定して保存しています。
ダウンロードが完了したら、一時ファイルを外部メモリ(通常はSDカード)のダウンロードディレクトリに移動する必要があります。しかし、何らかの理由で、File.renameTo()はこれに対して機能しません。 2つの個別のファイルシステムであるため問題があると思いますが、SDカードに直接ダウンロードでき、ファイルURIは正しいです。
そのファイルを内部メモリから外部に転送する別のシンプルで迅速な方法はありますか、またはバイトストリームのコピーを実行して元のファイルを削除する必要がありますか?
次のコードを使用して、内部メモリからSDカードにファイルをコピーする、またはその逆を行うには:
public static void copyFile(File src, File dst) throws IOException
{
FileChannel inChannel = new FileInputStream(src).getChannel();
FileChannel outChannel = new FileOutputStream(dst).getChannel();
try
{
inChannel.transferTo(0, inChannel.size(), outChannel);
}
finally
{
if (inChannel != null)
inChannel.close();
if (outChannel != null)
outChannel.close();
}
}
そして-それはうまくいきます...
内部メモリと外部メモリは、2つの異なるファイルシステムです。したがって、renameTo()は失敗します。
ファイルをコピーして元のファイルを削除する必要があります
ファイルをコピーした後( @ barmaley のすばらしい答えが示すように)、ユーザーが後で表示できるように、デバイスのギャラリーに公開することを忘れないでください。
手動で行わなければならない理由は
Androidは、再起動時とSDカードの(再)マウント時にのみ、完全なメディアスキャンを実行します
( このガイド が示すとおり)。
これを行う簡単な方法は、スキャンを呼び出すためのブロードキャストを送信することです。
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(outputFile));
context.sendBroadcast(intent);
そして出来上がり!これで、デバイスのギャラリーでファイルを表示できます。
独自の関数を使用してコピーする代わりに、 copyFile と呼ばれる関数で、Apacheのライブラリのクラス「FileUtils」を使用します。
FileUtils.copyFile(src, dst, true);
絵は:
このコードで試してください:
public void moveIn (String pathInternal, String pathExternal) {
File fInternal = new File (pathInternal);
File fExternal = new File (pathExternal);
if (fInternal.exists()) {
fInternal.renameTo(fExternal);
}
}
byte []の操作を使用してそれを行うことができます
クラスで定義します。
public static final String DATA_PATH =
Environment.getExternalStorageDirectory().toString() + "/MyAppName/";
次に:
AssetManager assetManager = context.getAssets();
InputStream in = assetManager.open("data/file.txt");
OutputStream out = new FileOutputStream(DATA_PATH + "data/file.txt");
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
@barmaleyのコードに簡単な変更を加えましたか
public boolean copyFile(File src, File dst) {
boolean returnValue = true;
FileChannel inChannel = null, outChannel = null;
try {
inChannel = new FileInputStream(src).getChannel();
outChannel = new FileOutputStream(dst).getChannel();
} catch (FileNotFoundException fnfe) {
Log.d(logtag, "inChannel/outChannel FileNotFoundException");
fnfe.printStackTrace();
return false;
}
try {
inChannel.transferTo(0, inChannel.size(), outChannel);
} catch (IllegalArgumentException iae) {
Log.d(logtag, "TransferTo IllegalArgumentException");
iae.printStackTrace();
returnValue = false;
} catch (NonReadableChannelException nrce) {
Log.d(logtag, "TransferTo NonReadableChannelException");
nrce.printStackTrace();
returnValue = false;
} catch (NonWritableChannelException nwce) {
Log.d(logtag, "TransferTo NonWritableChannelException");
nwce.printStackTrace();
returnValue = false;
} catch (ClosedByInterruptException cie) {
Log.d(logtag, "TransferTo ClosedByInterruptException");
cie.printStackTrace();
returnValue = false;
} catch (AsynchronousCloseException ace) {
Log.d(logtag, "TransferTo AsynchronousCloseException");
ace.printStackTrace();
returnValue = false;
} catch (ClosedChannelException cce) {
Log.d(logtag, "TransferTo ClosedChannelException");
cce.printStackTrace();
returnValue = false;
} catch (IOException ioe) {
Log.d(logtag, "TransferTo IOException");
ioe.printStackTrace();
returnValue = false;
} finally {
if (inChannel != null)
try {
inChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
if (outChannel != null)
try {
outChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return returnValue;
}