BufferedReader is closed

duneplodder

Active Member
Licensed User
Longtime User
I'm using a comma delimited text file to store data.
There is an occasional problem where if data has just been added, it is possible to open the file too quickly for viewing, giving a java.io.IOException: BufferedReader is closed error.

How can I check whether the BufferedReader is closed, before attempting to open the file?
Robert
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
I haven't checked your code. However there is no need to wait after closing a file.
Check this code which works perfectly and creates 20 files in a few milliseconds:
B4X:
Sub Activity_Create(FirstTime As Boolean)
For a = 1 To 20
   File.WriteString(File.DirInternal, a, a)
   Log(File.ReadString(File.DirInternal, a))
Next
End Sub
 
Upvote 0

duneplodder

Active Member
Licensed User
Longtime User
The problem seems to result from opening and reading a file very quickly after writing to & closing the same file. Not quite the same as your example.

I'll have a further look at this in a few days.
Thank you.
Robert
 
Upvote 0

duneplodder

Active Member
Licensed User
Longtime User
I'm sure it does, nevertheless I am seeing the error. It must be a different cause.
Hopefully I'll have some time to go through this again over the next couple of days.
If I make any progress I'll let you know.
Regards,
Robert
 
Upvote 0

duneplodder

Active Member
Licensed User
Longtime User
I've had a further look at this. The problem was not quite what I originally thought.
The software reads data in a text file into a user defined (Type) array. When I wish to display the data I read the array rather than the file.

What was happening was that on rare occasions the Display data routine was triggered very quickly & was trying to read the array before the file read into the array had been completed. Hence the "Buffer Reader is closed" error.

I now set a boolean "ReadingFile" flag which I can check before attempting to display the data.
Regards,
Robert
 
Upvote 0

TheWind777

Active Member
Licensed User
Longtime User
I've had a further look at this. The problem was not quite what I originally thought.
The software reads data in a text file into a user defined (Type) array. When I wish to display the data I read the array rather than the file.

What was happening was that on rare occasions the Display data routine was triggered very quickly & was trying to read the array before the file read into the array had been completed. Hence the "Buffer Reader is closed" error.

I now set a boolean "ReadingFile" flag which I can check before attempting to display the data.
Regards,
Robert

I'm having that error. I'm doing a similar thing to what you were doing.

The routine was working just fine... but now it's giving me that 'Buffered Reader is Closed' error.

It occurs when the program has just been run, and it goes directly to that routine.

B4X:
If File.Exists(File.DirAssets,"acimtoc.txt") = True Then

   'Read each Line from WB Table of Contents "acimtoc2.txt"
Reader.Initialize(File.OpenInput(File.DirAssets,"acimtoc.txt"))

TheLine="start"
EventCounter = 0

Do While TheLine <> Null
   TheLine = Reader.ReadLine
If TheLine<>Null Then
If DEBUG_Debugging1 Then Log("TheLine = " & TheLine)

rstACIMTOC.Initialize(TheLine)
rstACIMTOC.Style2(Typeface.STYLE_BOLD, "{B}")
rstACIMTOC.Style2(Typeface.STYLE_ITALIC, "{I}")
rstACIMTOC.Style2(Typeface.STYLE_BOLD_ITALIC, "{BI}")
rstACIMTOC.Style2(Typeface.STYLE_NORMAL, "{N}")
rstACIMTOC.Underscore2("{U}")
If DEBUG_Debugging1 Then Log("Set rstACIMTOC {B}, {I}, {BI}, {N}")

' http://www.rapidtables.com/web/color/RGB_Color.htm
rstACIMTOC.Color2(Colors.RGB(0,0,0), "{BL}")
rstACIMTOC.Color2(Colors.RGB(102,153,153), "{CC}")
rstACIMTOC.Color2(Colors.RGB(204,153,51), "{SC}")
rstACIMTOC.Color2(Colors.RGB(255,102,0), "{OR}")
rstACIMTOC.Color2(Colors.RGB(153,0,153), "{PU}")
If DEBUG_Debugging1 Then Log("Set rstACIMTOC {BL}, {CC}, {SC}, {OR} and {PU}")

FluidTextSizeFloat = FluidTextSize
lvACIMTOC.SingleLineLayout.Label.TextSize = FluidTextSizeFloat ' Gives error if not float
lvACIMTOC.SingleLineLayout.ItemHeight = TheItemHeight
lvACIMTOC.AddSingleLine(rstACIMTOC)
If DEBUG_Debugging1 Then Log("Doing lvACIMTOC.AddSingleLine(" & rstACIMTOC & ")")
End If

EventCounter = EventCounter + 1
If EventCounter Mod 20 = 0 Then DoEvents
Loop

Reader.Close

You say, "I now set a boolean "ReadingFile" flag which I can check before attempting to display the data."

But how can you set a Boolean that knows when it has finished reading the line?

You'd have to trigger the writing of the ReadingFile flag by some Event. What event are you using to set the flag... and how are you halting the progress until that event has occurred? Is there some sub Reader_Complete routine that can be called where I can then set the flag?

The error triggers on the 'TheLine = Reader.ReadLine' line.

B4X:
Error occurred on line: 2587 (main)


java.io.IOException: BufferedReader is closed
 at java.io.BufferedReader.checkNotClosed(BufferedReader.java:220)
 at java.io.BufferedReader.readLine(BufferedReader.java:377)
 at anywheresoftware.b4a.objects.streams.File$TextReaderWrapper.ReadLine(File.java:540)
 at java.lang.reflect.Method.invokeNative(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:515)
 at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:485)
 at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:229)
 at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:174)
 at java.lang.reflect.Method.invokeNative(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:515)
 at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:93)
 at anywheresoftware.b4a.BA$3.run(BA.java:318)
 at android.os.Handler.handleCallback(Handler.java:733)
 at android.os.Handler.dispatchMessage(Handler.java:95)
 at android.os.Looper.loop(Looper.java:136)
 at android.app.ActivityThread.main(ActivityThread.java:5017)
 at java.lang.reflect.Method.invokeNative(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:515)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
 at dalvik.system.NativeStart.main(Native Method)
 
Upvote 0

duneplodder

Active Member
Licensed User
Longtime User
I don't quite understand what your routine is doing but I think your situation is slightly different to mine.
I was reading data from a text file into arrays which happened in the background. It was however possible to start a display routine which used these arrays before the reading routine was completed causing the error.
I simply set a global boolean flag at the beginning of the reading procedure and cleared it after the file was closed.
The display routine first checked the status of this flag & if it was active displayed a message asking the user to wait a few moments.
 
Upvote 0
Top