Dosya Kaydetmek
Android,
diğer disk tabanlı platformlar ile benzer bir dosya sistemi kullanır. Bu
yazımızda File API ile Android dosya
sisteminde nasıl dosya yazıp, silebileceğimizi göreceğiz.
File nesnesi herhangi bir atlama yapmadan, baştan
başlayıp sona doğru sıralı bir şekilde çok büyük miktarlarda veri okuyup
yazabilme kabiliyetine sahiptir. Örneğin, görsel dosyaları ve network üzerinde
transfer edilebilen herhangi bir dosyanın aktarımı için iyi bir avantaj sağlar.
Bu yazı
ile, temel dosya ilişkili görevlerini nasıl yapacağımızı incelerken, sizin
Linux sistemindeki input/output API olan java.ioile
daha önce çalıştığınız varsayıyoruz.
Dahili veya Harici Hafıza Seçimi
Tüm
Android aygıtlar iki çeşit dosya depolama alanına sahiptir. Bunlar, Internal
(Dahili) ve External (harici)
alanlardır. Bu adlandırmalar Android’in ilk günlerinden,dahili hafızanın
yanında micro SD card gibi harici depolama alanlarının da birçok cihaz
tarafından desteklenmeye başlanmasından bu yana kullanılmaktadır. Bazı aygıtlar,
dahili depolama alanı içinde kalıcı olarak “dahili” ve “harici” bölümlere
ayırılmıştır. Her durumda sadece 2 depolama alanı olur ve API nin davranışı
tamamen harici veya dahili tanımlamasına göredir. Aşağıdaki tablo da Dahili ve
Harici depolama alanlarının özelliklerini görebilirsiniz.
Dahili Depolama Alanı
|
Harici Depolama Alanı
|
·
Her zaman erişilebilir
|
·
Her zaman erişilebilir olamayabilir, kullanıcı
çıkarıp takabilir veya bellek USB depolama aygıtı gibi kullanılabilir.
|
·
Buraya kaydedilen tüm dosyalar varsayılan
olarak sadece sizin uygulamanız tarafından okunabilir.
|
·
Burada yer alan dosyalar dış dünyaya açıktır
ve sizin kontrolünüz dışında erişilebilir
|
·
Kullanıcı uygulamanızı kaldırdığında,
uygulamanıza ait tüm dosyalar silinir.
|
·
Kullanıcı uygulamanızı kaldırdığı zaman,
sistem getExternalFilesDir() metoduyla kaydettiğiniz dosyalar dışındaki
dosyaları silmez
|
·
Harici depolama alanı, erişim kısıtlamaları
gerektirmeyen ve diğer uygulamalar için girdiler üreten uygulamalarınız için en
ideal dosya kaydetme alanıdır.
İPUCU:
Uygulamalar
varsayılan olarak dahili hafıza alanına kaydedilmesine rağmen, Manifesto
dosyanızda android:installLocationniteliği
ile yapacağınız düzenleme ile kurulum işlemini harici alana yapabilirsiniz.
Uygulamanızın APK dosya boyutu çok büyük olduğu durumlarda kullanıcı bu
özellikten memnun kalacaktır.AppInstallLocation
sayfasında daha fazla bilgi bulabilirsiniz.
Harici Depolama Alanı İçin İzin Almak
Harici
depolama alanına yazmak için, WRITE_EXTERNAL_STORAGE
izniniz manifestoya (AndroidManifest.xml) eklemelisiniz.
ÖRNEK:
<manifest ...>
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
...
</manifest>
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
...
</manifest>
UYARI:
Özel izin olmadan birçok uygulama harici alana yazma iznine
sahiptir. Fakat gelecek sürümlerde bu değiştirilmesi düşünülen bir özelliktir.
Uygulamanızın harici alana okuma için erişime ihtiyacı varsa( yazma için değil)
READ_EXTERNAL_STORAGE izni almanız yeterlidir.
Uygulamanızın beklendiği gibi çalıştığından emin olmak için, bu izni şimdi
sağlamalısınız.
ÖRNEK:
<manifest ...>
<uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"/>
...
</manifest>
<uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"/>
...
</manifest>
Dahili Depolama Alanına Dosya Kaydetmek
Dahili
depolama alanına dosya kaydederken, File nesnesinde yer alan iki metottan
birini çağırarak uygun dizin seçimini yapabilirsiniz.
·
getFilesDir()
– Uygulamanız için File gösteriminde dahili dizin döndürür.
·
getCacheDir()-Uygulamanız
için File gösteriminde geçici dahili dizin döndürür. Bu metot ile
oluşturduğunuz dosyaların, işiniz bittiğinde silindiğinden emin olun yoksa
burada oluşturulan tüm dosyalar bellekte yer tutacağından cihazın çalışmasını
yavaşlatabilir. Eğer ki siz silmezseniz bu yavaşlama sonucu sistemi
kendiliğinden bu dosyaları siler.
Bu dizinlerden birinde yeni bir dosya oluşturmak için, yukarıdaki metotlardan biri ile sağlanan
dahili alanı parametre olarak verip File() yapıcı metodunu
kullanabilirsiniz.
ÖRNEK:
Filefile=newFile(context.getFilesDir(),filename);
openFileOutput() metodunu çağırarak, FileOutputStrem ile
dahili dizininize yazılan dosyaları edinebilirsiniz. Örneğin, bir takım yazının
bir dosyaya nasıl kaydedildiğini görelim,
ÖRNEK:
Stringfilename="myfile";
Stringstring="Helloworld!";
FileOutputStreamoutputStream;
try{
outputStream=openFileOutput(filename,Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
}catch(Exception e){
e.printStackTrace();
}
Stringstring="Helloworld!";
FileOutputStreamoutputStream;
try{
outputStream=openFileOutput(filename,Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
}catch(Exception e){
e.printStackTrace();
}
Veya bazı dosyaları önbelleğe almaya ihtiyaç duyuyorsanız, createTempFile() metodunu kullanmalısınız.
Örneğin, Aşağıdaki kod örneği ile dosya ismini URL den çıkarıyor ve bu isim ile
uygulamanızın geçici dizininde dosya oluşturuyor.
publicFilegetTempFile(Contextcontext,Stringurl){
Filefile;
try{
StringfileName=Uri.parse(url).getLastPathSegment();
file =File.createTempFile(fileName,null,context.getCacheDir());
catch(IOException e){
// Errorwhilecreating file
}
return file;
}
Filefile;
try{
StringfileName=Uri.parse(url).getLastPathSegment();
file =File.createTempFile(fileName,null,context.getCacheDir());
catch(IOException e){
// Errorwhilecreating file
}
return file;
}
NOT:
Uygulamanızın dahili depolama dizin alanı, uygulamanızın
package ismi ile Android dosya sisteminde özel bir konumda belirlenir. Teknik
olarak, diğer uygulamalar dahili dosyalarınızı siz okunabilir ayarlarsanız,
okuyabilirler. Fakat diğer uygulamalar bu package ismini bilmelidirler. Siz
dosyalarınız açık bir şekilde okunabilir veya yazılabilir olarak ayarlamadıkça,
diğer uygulamalar bu erişimleri gerçekleştiremezler. MODE_PRIVATE
kullandığınızda ise dosyalarınız asla erişilemez olur.
Harici Depolama Alanına Dosya Kaydetmek
Bu
alana erişim gerçekleştirmeden önce her zaman bu alanın müsait olup olmadığını
kontrol etmelisiniz. Çünkü kullanıcı mSD kartı çıkarabilir veya USB Depolama
alanı olarak PC’ye bağlanmış olabilir. getExternalStorageState() metodu ile bu sorgulamayı
yapabilirsiniz. Eğer dönüş değeri MEDIA_MOUNTED ise dosyalarınızı okuyup
yazabilirsiniz. Örneğin, aşağıdaki metot depolama alanını kontrol etmek için
kullanışlı bir kod bloğuna sahiptir.
ÖRNEK:
/* Checksifexternalstorage is availableforreadandwrite
*/
publicbooleanisExternalStorageWritable(){
Stringstate=Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state)){
returntrue;
}
returnfalse;
}
/* Checksifexternalstorage is availableto at leastread */
publicbooleanisExternalStorageReadable(){
Stringstate=Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state)||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)){
returntrue;
}
returnfalse;
}
publicbooleanisExternalStorageWritable(){
Stringstate=Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state)){
returntrue;
}
returnfalse;
}
/* Checksifexternalstorage is availableto at leastread */
publicbooleanisExternalStorageReadable(){
Stringstate=Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state)||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)){
returntrue;
}
returnfalse;
}
Harici depolama alanı diğer kullanıcılar ve uygulamalar
tarafından değiştirilebilir olmasına rağmen, buraya kaydedebileceğiniz iki
dosya kategorisi vardır.
PUBLIC FILES:
Bu dosyalar diğer uygulama ve kullanıcılar için tamamen serbestçe erişilebilir. Kullanıcı uygulamayı kaldırdığında bu dosyalar silinmez.
Bu dosyalar diğer uygulama ve kullanıcılar için tamamen serbestçe erişilebilir. Kullanıcı uygulamayı kaldırdığında bu dosyalar silinmez.
PRIVATE FILES:
Bu
dosyalar tamamen uygulamanıza ait olup, kullanıcı uygulamanızı kaldırdığında
sistemden tamamen silinirler. Bu dosyalar dışarıdan erişime açık olmalarına
rağmen, dış dünyaya veri sağlamazlar. Uygulama silindiğinde harici alandaki tüm
öze dosyalar sistem tarafından silinir.
Uygulamanız tarafından indirilen ek kaynak dosyaları veya
geçici medya dosyaları bu dosyalara örnektir.
Eğer harici depolama alanına public dosya kaydetmek
isterseniz, getExternalStoragePublicDirectory()
metodunu kullanarak uygun harici File dizini
edinebilirsiniz. Kaydetmek istediğiniz dosya türünü parametre olarak alır ve
mantık olarak örneğin DIRECTORY_MUSIC veya DIRECTORY_PICTURES gibi diğer public dosyalar ile
organize olur.
ÖRNEK:
publicFilegetAlbumStorageDir(StringalbumName){
// Getthedirectoryfortheuser'spublicpicturesdirectory.
Filefile=newFile(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES),albumName);
if(!file.mkdirs()){
Log.e(LOG_TAG,"Directory not created");
}
return file;
}
// Getthedirectoryfortheuser'spublicpicturesdirectory.
Filefile=newFile(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES),albumName);
if(!file.mkdirs()){
Log.e(LOG_TAG,"Directory not created");
}
return file;
}
Uygulamanıza ait dosyaları özel olarak kaydetmek isterseniz
bunun için uygun dizini, getExternalFilesDir()
metodunu çağırmalı ve dizine vermek istediğiniz ismi bu metoda parametre
vermelisiniz. Bu şekilde oluşturulan her dizin parent dizinin alt dizini olur
ve uygulamanızın harici dosyalarının tamamı tarafından kapsüllenir (kapsanır
erişilebilir). Bu dizinler kullanıcı uygulamayı kaldırdığı zaman cihazdan
silinir.
ÖRNEK:
Kişisel fotoğraf albümü oluşturmanızı sağlayacak olan metot
örneği
public File getAlbumStorageDir(Context context, String albumName) { // Get the directory for the app's private pictures directory. File file = new File(context.getExternalFilesDir( Environment.DIRECTORY_PICTURES), albumName); if (!file.mkdirs()) { Log.e(LOG_TAG, "Directory not created"); } return file; }
Önceden tanımlı olan alt dizinler hiç biri sizin
dosyalarınıza uyumlu değilse, bir önceki metot yerine getExternalFilesDir()
metodu parametresiz olarak çağırılır. Bu metot ile harici depolama alanında
uygulamanıza ait kök dizin bilgisi döndürülür.
getExternalFilesDir()
metodunun kullanıcı tarafından uygulama silindiğinde, silinecek olan dizin
içersinde klasör oluşturduğunu unutmamak lazım. Kamera uygulaması gibi bir
uygulama yaptığınız durumlarda uygulamanıza ait klasörlerin ve dosyaların
kalmasını istiyorsanız yukarıdaki metot yerine getExternalStoragePublicDirectory()
metodunu kullanmak daha faydalı olacaktır.
Yukarıda bahsettiğimiz her iki metottan hangisini
kullanırsanız kullanın unutmamanız gereken en önemli nokta, DIRECTORY_PICTURES gibi API’ler ile sağlanan sabit
dizin isimlerini kullanmanız gerekir. Bu isimler uygulamanıza ait dosyaların
Android Sistemi ile uygun bir şekilde çalışmasını garanti eder. Örneğin, DIRECTORY_RINGTONES ismiyle sınıflandırılan
dosyalarınız sistem tarafından müzik olarak değil de Ringtone olarak tanınır.
Boş Alan Sorgulama
İlerleyen zamanlarda hangi
büyüklükte dosya saklayacağınızı biliyorsanız IOException hataları ile
karşılaşmadan yeterli alan olup olmadığını, getFreeSpace()
veya getTotalSpace() metotları yardımıyla
kolaylıkla sorgulayabilirsiniz. Bu metotlar sırasıyla, müsait kullanılabilir
alan miktarı ile toplam disk kapasitesi hakkında bilgi sağlar. Bu bilgi,
depolama alanının kritik doluluk değerini kontrol etmenize de yardım eder.
Sistem getFreeSpace()
metoduyla döndürülen değer kadar veri yazmanızı garanti etmez ancak, bu metot
ile dönen değer kaydetmek istediğiniz veriden bir miktar fazla ise veya depolama
alanı kapasitesinin %90 nından daha az bir doluluğa sahip ise kayıt işlemi
güvenli bir şekilde yapılabilir. Aksi durumlarda, verinizi depolama birimine
yazamayabilirsiniz.
NOT:
Dosyanızı kaydederken müsait alan sorgulaması yapmak zorunda
değilsiniz. Bunun yerine dosyanızı direk yazmayı deneyebiliri ve olası bir
hatayı yakalama yöntemini tercih edebilirsiniz. Tabii ki bu yöntemi kaydetmek
istediğiniz verinin boyutu hakkında herhangi bir fikriniz yok ise yapmalısınız.
Örneğin, kamera uygulamanız ile çektiğiniz görselleri JPEG’den PNG’ye
dönüştürerek kaydediyorsanız, ne kadar depolama alanı gerektiğini önceden
bilemeyeceksinizdir.
Bir Dosya Silmek
Kaydetmiş olduğunuz bu dosyalara zaman ile ihtiyaç
duyulmayacağından bunlar gerektiğinde silmeniz gerekir. En basit dosya silme
yöntemi delete() metodunu çağırmaktır.
ÖRNEK:
myFile.delete();
Eğer dosyanı dahili depolama alanında saklanıyorsa, dosyanın
yerini bulup silmek için Context’i sorgulamanız da gerekecektir.
ÖRNEK:
myContext.deleteFile(fileName);
NOT:
Kullanıcı uygulamanızı kaldırdığında Android Sistem
aşağıdaki verileri siler.
·
Dahili depolama alanındaki tüm veriler silinir
·
getExternalFilesDir() metoduyla tüm harici alanda
oluşturulan dosyalar silinir.
Ancak ön belleklenmiş tüm verileri sizin kendiniz silmeniz
gerekir, bunun yanında geçici ihtiyaç durumu ortadan kalktığında da bu
dosyaları cache bellekten silmeniz gerekir.
androidde dosya kaydetmek , DB , dosya işlemek android , dosya kaydetmek , Saving Files in android
outputStream.write(Metin1) outputStream.write(Metin2) Myfile.txt dosyamda Metin2'yi Metin1'in alt satırına nasıl yazdırabilirim?
YanıtlaSil