Android Tutorial Text files

Many applications require access to a persistent storage. The two most common storage types are files and databases.
We will cover text files in this tutorial.

The predefined Files object has several utility methods for working with text files which are pretty easy to use.

Files locations - There are several important locations where you can read or write files.

File.DirAssets
The assets folder includes the files that were added with the file manager. These files are read-only. You can not create new files in this folder (which is actually located inside the apk file).

File.DirInternal / File.DirInternalCache
These two folders are stored in the main memory and are private to your application. Other applications cannot access these files.
The cache folder may get deleted by the OS if it needs more space.

File.DirRootExternal
The storage card root folder.

File.DirDefaultExternal
The default folder for your application in the SD card.
The folder is: <storage card>/Android/data/<package>/files/
It will be created if required.

Note that calling any of the two above properties will add the EXTERNAL_STORAGE permission to your application.

Tip: You can check if there is a storage card and whether it is available with File.ExternalReadable and File.ExternalWritable.

The predefined File object (predefined means that you do not need to declare it yourself) includes several methods for writing and reading to files.
You can also use TextReader and TextWriter to do it manually.
Note that TextReader and TextWriter are not limited to files and can work with other streams.

TextReader and TextWriter have an advantage over the File read/write methods when working with large files. The File methods read the file completely and store its content in memory. In many cases this is the most convenient solution, however if you work with large files (more than 1-2mb) you may prefer to work with TextReader or TextWriter.

File.WriteString - Writes the given text to a new file.
File.ReadString - Reads a file and returns it content as a string.
File.WriteList - Writes all values stored in a list to a file. All values are converted to string type if required. Each value will be stored in its own line.
Note that if a value contains the new line character it will saved over more than one line and when you read it, it will be read as multiple items.
File.ReadList - Reads a file and stores each line as an item in a list.
File.WriteMap - Takes a map object which holds pairs of key and value elements and stores it in a text file. The file format is known as Java Properties file: .properties - Wikipedia, the free encyclopedia
The file format is not too important unless the file is supposed to be edited manually. This format makes it easy to edit it manually.
One common usage of File.WriteMap is to save a map of "settings" to a file.
File.ReadMap - Reads a properties file and returns its key/value pairs as a Map object. Note that the order of entries returned might be different than the original order.

Example:
B4X:
Sub Process_Globals

End Sub

Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)
    If File.ExternalWritable = False Then
        Msgbox("Cannot write on storage card.", "")
        Return
    End If
    SaveStringExample
    ReadStringExample
    
    WriteListExample
    ReadListExample
    
    WriteMapExample
    ReadMapExample
    
    WriteTextWriter
    ReadTextReader
End Sub

Sub SaveStringExample
    File.WriteString(File.DirRootExternal, "String.txt", _
        "This is some string" & CRLF & "and this is another one.")
End Sub

Sub ReadStringExample
    Msgbox(File.ReadString(File.DirRootExternal, "String.txt"), "")
End Sub

Sub WriteListExample
    Dim List1 As List
    List1.Initialize
    For i = 1 To 100
        List1.Add(i)
    Next
    File.WriteList(File.DirRootExternal, "List.txt", List1)
End Sub

Sub ReadListExample
    Dim List1 As List
    'We are not initializing the list because it just holds the list that returns from File.ReadList
    List1 = File.ReadList(File.DirRootExternal, "List.txt")
    Msgbox("List1.Size = " & List1.Size & CRLF & "The third item is: " & List1.Get(2), "")
End Sub

Sub WriteMapExample
    Dim Map1 As Map
    Map1.Initialize
    For i = 1 To 10
        Map1.Put("Key" & i, "Value" & i)
    Next
    File.WriteMap(File.DirRootExternal, "Map.txt", Map1)
End Sub

Sub ReadMapExample
    Dim Map1 As Map
    'Again we are not initializing the map.
    Map1 = File.ReadMap(File.DirRootExternal, "Map.txt")
    'Append all entries to a string builder
    Dim sb As StringBuilder
    sb.Initialize
    sb.Append("The map entries are:").Append(CRLF)
    For i = 0 To Map1.Size - 1
        sb.Append("Key = ").Append(Map1.GetKeyAt(i)).Append(", Value = ")
        sb.Append(Map1.GetValueAt(i)).Append(CRLF)
    Next
    Msgbox(sb.ToString,"")
End Sub

Sub WriteTextWriter
    Dim TextWriter1 As TextWriter
    TextWriter1.Initialize(File.OpenOutput(File.DirRootExternal, "Text.txt", False))
    For i = 1 To 10
        TextWriter1.WriteLine("Line" & i)
    Next
    TextWriter1.Close
End Sub

Sub ReadTextReader
    Dim TextReader1 As TextReader
    TextReader1.Initialize(File.OpenInput(File.DirRootExternal, "Text.txt"))
    Dim line As String
    line = TextReader1.ReadLine    
    Do While line <> Null
        Log(line) 'write the line to LogCat
        line = TextReader1.ReadLine
    Loop
    TextReader1.Close
End Sub
 

vb1992

Well-Known Member
Licensed User
Longtime User
B4X:
ret = fd.Show("Choose a file to load:", "Okay", "Cancel", "", Null)   
If ret = -3 OR fd.ChosenName = "" Then 
   Return
End If
If File.Exists("/mnt/external_sd", fd.ChosenName) = False Then
   Msgbox(fd.ChosenName & " does not exist.", "")
   Return
End If
Dim TR As TextReader
Dim s As String
TR.Initialize(File.OpenInput("/mnt/external_sd", fd.ChosenName))
   s = TR.ReadLine
   ...
TR.Close
 

salmander

Active Member
Licensed User
Longtime User
B4X:
If File.Exists(File.DirInternalCache, "image.jpg") = True Then
      File.Copy(File.DirInternalCache, "image.jpg", File.DirDefaultExternal, "image.jpg")
   End If
This is not working. The program gives error. And the file.dirInternalCache is true.

Any suggestion?

Ok poblem solved. I had to manually add in the manifest file this line, "<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>" as I have checked do not write to manifest file in the project menu.
 
Last edited:

salmander

Active Member
Licensed User
Longtime User
If you are using B4A v1.8 then there is no reason to use this option. If you need help in recreating the manifest file then please start a new thread and I'll help you.
I had to check that option because I was using C2DM framework tutorial. I wanted to keep every message I receive into a permanent storage. So when I was writing to a file on the external storage, I keep getting the error, then, it occurred to me that I may need to check the permissions in the manifest file. Bingo, the IDE wasn't adding WRITE EXTERNAL STORAGE to the manifest file, as I have checked in the project menu, DO NOT OVERWRITE MANIFEST FILE (as recommended in the C2DM framework tutorial). So all I did is added the permission manually in the manifest file. And voila, I was able to receive push notifications and save it to the external storage at the same time.
In v1.8 indeed the problem can be overcome by using Manifest editor.
Thank you for the reply and amazing work Erel.
 
Last edited:

Dallas Williams

Member
Licensed User
Longtime User
The initial code posted in here writes all the files however instead of writing them to the Storage Card it appears to write them to the /Root directory of the tablets internal memory.

Could someone show me where I may be going wrong please.
 

Dallas Williams

Member
Licensed User
Longtime User
File.DirRootExternal returns the external storage directory as reported by the OS.

Running the example from your first post, saves everything into the /Root directory of the tablet. Nothing to the external storage

Maybe this is only a problem with the Samsung Galaxy Tablet running 3.2
 

JonPM

Well-Known Member
Licensed User
Longtime User
We need to declare a Lib before we can use RandomAccessFile right? I'm getting a

Error description: Unknown type: randomaccessfile
Are you missing a library reference?

compiler message.

Did you check RandomAccessFile from the Libs tab??
 

rfresh

Well-Known Member
Licensed User
Longtime User
I've since found out that's my problem. There is no listing for RandonAccessFile in my Lib tab so nothing to check mark. Where do I download it from? I know how to add it to my Lib path folder.
 

JonPM

Well-Known Member
Licensed User
Longtime User
What version of B4A are you using? This is a standard library, it should come installed with it.
 

positrom2

Active Member
Licensed User
Longtime User
How to save full screen image?

Hi,
does anybody know how to save on the phone the full screen image (not just a canvas) in gif or png format?
Thanks, positrom2
 

rfresh

Well-Known Member
Licensed User
Longtime User
What about this code below? I use it take screen shots.

B4X:
      Dim Obj1, Obj2 As Reflector
      Dim bmp As Bitmap
      Dim c As Canvas
      Dim now, i As Long
      Dim dt As String
      DateTime.DateFormat = "yyMMddHHmmss"
      now = DateTime.now
      dt = DateTime.Date(now) ' e.g.: "110812150355" is Aug.12, 2011, 3:03:55 p.m.
      Obj1.Target = Obj1.GetActivityBA
      Obj1.Target = Obj1.GetField("vg")
      bmp.InitializeMutable(Activity.Width, Activity.Height)
      c.Initialize2(bmp)
      Dim args(1) As Object
      Dim types(1) As String
      Obj2.Target = c
      Obj2.Target = Obj2.GetField("canvas")
      args(0) = Obj2.Target
      types(0) = "android.graphics.Canvas"
      Obj1.RunMethod4("draw", args, types)
      Dim Out As OutputStream
      Out = File.OpenOutput(File.DirRootExternal, dt & ".png", False)
      bmp.WriteToStream(Out, 100, "PNG")
      Out.Close
 

positrom2

Active Member
Licensed User
Longtime User
rfresh, thank you very much!
Does what I was looking for, although I don't understand most of the code...:signOops:.. And nice feature that it will never overwrite an existing file.
Regards, positrom2
 

positrom2

Active Member
Licensed User
Longtime User
Screen shot

On the Archos 70b internet tablet with Honeycomb 3.2. (and some other tablets from Archos) one gets a screen shot by pressing the power buttom (this function first to be enabled in "development, Take a screenshot instead of suspending). I wonder if this function can be accessed by code.

positrom2
 

BarrySumpter

Active Member
Licensed User
Longtime User
Hi all,
I'm building an app that will write my lat lng
(using the b4a example GPS.b4a)
to a .txt or .ini file.
I'm hoping to find a timer routine that will allow me to
save once right now or every 5 mins or so.

Then I want to either lets say
send that .txt or .ini file in an email as an attachment
or open that .txt or .ini file and place in an email body, etc
by using another propriatary app or 3rd party app.

If I use the Text Files code in this thread will another app be able to find it and read it
when its on the internal data storage?

I'm leaning more towards putting on the SD card /GPSLoc/GPS.ini
Same question will it be available to other apps?

tia


ummm - nevermind
it took longer to write this post than to implement and test the code.
Very Very frekin' cool.
Just Brilliant!
:) :sign0188:

B4X:
Sub GPS_LocationChanged (Location1 As Location)

  Dim dt As String
   Dim now As Long
  
   DateTime.DateFormat = "yyyy-MM-dd HH:mm:ss"
   
   now = DateTime.now
   dt = DateTime.Date(now)

   lblLat.Text = "Lat = " & Location1.ConvertToMinutes(Location1.Latitude)
   lblLon.Text = "Lon = " & Location1.ConvertToMinutes(Location1.Longitude)
   lblSpeed.Text = "Speed = " & Location1.Speed
   lblDateTimeStamp.text = dt

   Map1.Put ("Lat", Location1.ConvertToMinutes(Location1.Latitude))
   Map1.Put ("Lon", Location1.ConvertToMinutes(Location1.Longitude))
   Map1.Put ("Speed", Location1.Speed)
   Map1.Put ("DateTimeStamp", dt)
  File.WriteMap(File.DirRootExternal, "GPS.txt", Map1)

End Sub

I love that date format yyyy-MM-dd HH:mm:ss
not only is it visually pleasing and I can read it in the database as is as a string,
it sorts properly as well.

But the only prob is that the : (colons) in the date and lat and lon display/store as \: :BangHead:


Is there a setting I can use so the WriteMap won't insert \ in front of : ?

I have not changed anything as far as I know.
But now I'm getting a permission denied.

And found it.
It was me.
I was connect via usb to run the app and debugger on my physical phone.
Once the app started writting the GPS coordinates to the file to the proper android folder,
I wanted to retrieve the file.
So I closed the app and the debugger would close as well.
Then I would Turn on USB storage.
Browse to the file using WinExploerer on the PC.
And retrieve the file by copying it to the PC desktop.
THen I would forget that the USB sotrage connection was still active.
And try to debug run my app again and would receive permission denied.
Now I turn USB storage OFF and the app debugs runs properly.

hth anyone in the same situation.


.
 
Last edited:

davidjjdj

New Member
Folder views

Hello im building up to making a program that requires a way to select files in certain folders. What I need is a way to have 1 spinner show folders inside a folder and the second spinner would show up as folders inside the folder selected by the first spinner, and yet a third spinner to display another folder inside the second folder. I couldn't find anything like this online.
Thanks for the help

davidjjdj
 
Top