str = oTR.ReadLine
If str = Null Then Exit
str = clsTR.ReadLine
If str.Length = 0 Then Exit
TextReader.ReadLine is declared as String return, but still for some reason the return value can be compared to Null.If you set the "ReadLine" method as Object you can return a string or a Null. You should show the ReadLine code.
Actually, even if it is declared as a string it can return Null. What error do you get?
Do While True
str = clsTR.ReadLine
If str = Null Then Exit
Loop
Sub Class_Globals
Private mstrCharSet As String
Private mbtEndOfLineByte As Byte
Private bFirstArrayDone As Boolean
Private lFilePos As Long
Private lArrayPos As Long
Private bNoEndOfLineFound As Boolean
Private bFinalArrayDone As Boolean
Private miMaxBytes As Int
Private RAF As RandomAccessFile
Private iBytes As Int
Private arrBytes() As Byte
Private strLine As String
End Sub
'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(tFF As tFolderAndFile, strCharSet As String, btEndOfLineByte As Byte, lMaxBytes As Long)
mstrCharSet = strCharSet
mbtEndOfLineByte = btEndOfLineByte
miMaxBytes = lMaxBytes
RAF.Initialize(tFF.strFolder, tFF.strFile, True)
lFilePos = 0
lArrayPos = 0
bNoEndOfLineFound = False
bFinalArrayDone = False
iBytes = Min(RAF.Size, miMaxBytes)
End Sub
Public Sub Close
RAF.Close
Dim arrBytes() As Byte 'clear some memory?
End Sub
Public Sub ReadLine As String 'ignore
Dim i As Long
Dim bRowReturned As Boolean
Do While bRowReturned = False 'to avoid returning an empty string
bRowReturned = False
If bFinalArrayDone = False Then
If bFirstArrayDone = False Then
'first byte array to process
Dim arrBytes(iBytes) As Byte
iBytes = RAF.ReadBytes(arrBytes, 0, iBytes, 0)
bNoEndOfLineFound = False
bFirstArrayDone = True
Else
If bNoEndOfLineFound Then
Dim arrBytes(iBytes) As Byte
iBytes = RAF.ReadBytes(arrBytes, 0, iBytes, lFilePos)
lArrayPos = 0
bNoEndOfLineFound = False
End If
End If
End If
For i = lArrayPos To iBytes - 1
If arrBytes(i) = mbtEndOfLineByte Then
If i > 0 Then
If arrBytes(i - 1) = 13 Then
strLine = BytesToString(arrBytes, lArrayPos, (i - lArrayPos) - 1, mstrCharSet)
Else
strLine = BytesToString(arrBytes, lArrayPos, i - lArrayPos, mstrCharSet)
End If
lArrayPos = i + 1
bRowReturned = True
Return strLine
End If
End If
Next
If bFinalArrayDone Then
bRowReturned = True
Return "" 'can we return Null here as in TextReader?
End If
bNoEndOfLineFound = True
If RAF.Size - lFilePos < miMaxBytes Then
bFinalArrayDone = True
Else
lFilePos = lFilePos + lArrayPos
End If
Loop
End Sub
Tried your idea, but it doesn't work. No error, but no loop exit.I seem to recall that if you set a String = Null in B4J the String will actually contain 'null' - this is going back a few years so could have changed by now.
Yes, I am aware of that one, but I was trying to make it behave as with TextReader. Also it seems better then to stick with str.Length = 0.B4X:Dim str As String = Null Log(str = "null") 'true
Tried that one, but that gives me this error:You should probably change the order, to this:
B4X:If Null = str Then Exit
Just wondering what the exact return is from TextReader.ReadLine, to make it work to compare a string with Null.
>>and to also make StrVar.Length crash after the end-of-file StrVar = TextReader.ReadLine causes StrVar to be Null and not a String.
I have tried all sorts of casting, with no success. The only way I've found to get StrVar to be Null (distinct from "null") is to save a copy of it from an end-of-file TextReader.ReadLine, and even then a Return will cast it back to the Sub's declared return type of String ie "null".
The source code for TextReader.ReadLine would probably explain what and how, but burgered if I can find it.
and also that makes StrVar.Length crash after the end-of-file strVar =
Did you find a bug there?
How to reproduce this?
Dim Reader As TextReader
Reader.Initialize(File.OpenInput(File.InternalDir, "1.txt"))
Dim line As String
line = Reader.ReadLine
Do While line <> Null
Log(line)
line = Reader.ReadLine
Loop
Reader.Close
Log(line.Length) 'hold on to your hat here, because line is Null, not String
OK, I get it. I don't think my class returns the final Null byte, but will check.It is more a consequence of design than a bug. If you know to sidestep the issue, then it's not a problem.
Use .Length on String variable that is actually the end-of-file Null from .ReadLine :
B4X:Dim Reader As TextReader Reader.Initialize(File.OpenInput(File.InternalDir, "1.txt")) Dim line As String line = Reader.ReadLine Do While line <> Null Log(line) line = Reader.ReadLine Loop Reader.Close Log(line.Length) 'hold on to your hat here, because line is Null, not String
Sub Class_Globals
Private mstrCharSet As String
Private mbtEndOfLineByte As Byte
Private bFirstArrayDone As Boolean
Private lFilePos As Long
Private lArrayPos As Long
Private bNoEndOfLineFound As Boolean
Private bFinalArrayDone As Boolean
Private bFinalLineDone As Boolean
Private miMaxBytes As Int
Private RAF As RandomAccessFile
Private iBytes As Int
Private arrBytes() As Byte
Private strLine As String
End Sub
'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(tFF As tFolderAndFile, strCharSet As String, btEndOfLineByte As Byte, lMaxBytes As Long)
mstrCharSet = strCharSet
mbtEndOfLineByte = btEndOfLineByte
miMaxBytes = lMaxBytes
RAF.Initialize(tFF.strFolder, tFF.strFile, True)
lFilePos = 0
lArrayPos = 0
bNoEndOfLineFound = False
bFinalArrayDone = False
bFinalLineDone = False
iBytes = Min(RAF.Size, miMaxBytes)
End Sub
Public Sub Close
RAF.Close
Dim arrBytes() As Byte 'clear some memory?
End Sub
Public Sub ReadLine As String 'ignore
Dim i As Long
Dim bRowReturned As Boolean
Do While bRowReturned = False 'to avoid returning an empty string
bRowReturned = False
If bFinalArrayDone = False Then
If bFirstArrayDone = False Then
'first byte array to process
Dim arrBytes(iBytes) As Byte
iBytes = RAF.ReadBytes(arrBytes, 0, iBytes, 0)
bNoEndOfLineFound = False
bFirstArrayDone = True
Else
If bNoEndOfLineFound Then
Dim arrBytes(iBytes) As Byte
iBytes = RAF.ReadBytes(arrBytes, 0, iBytes, lFilePos)
lArrayPos = 0
bNoEndOfLineFound = False
End If
End If
End If
For i = lArrayPos To iBytes - 1
If arrBytes(i) = mbtEndOfLineByte Then
If i > 0 Then
If arrBytes(i - 1) = 13 Then
strLine = BytesToString(arrBytes, lArrayPos, (i - lArrayPos) - 1, mstrCharSet)
Else
strLine = BytesToString(arrBytes, lArrayPos, i - lArrayPos, mstrCharSet)
End If
lArrayPos = i + 1
bRowReturned = True
Return strLine
End If
End If
Next
If bFinalLineDone Then
bRowReturned = True
Return "" 'can we return Null here as in TextReader?
End If
bNoEndOfLineFound = True
If RAF.Size - lFilePos < miMaxBytes Then
bFinalArrayDone = True
'Added this to avoid missing a final line
If lFilePos < RAF.Size - 1 Then
strLine = BytesToString(arrBytes, lArrayPos, iBytes - lArrayPos, mstrCharSet)
Log("final line: " & strLine)
bFinalLineDone = True
bRowReturned = True
Return strLine
End If
Else
lFilePos = lFilePos + lArrayPos
End If
Loop
End Sub
Will look at that, but the only reason to do strLine = Null was to keep it the same as TextReader.Try
B4X:If str Is Null Then Exit
Try
B4X:If str Is Null Then Exit
reason to do strLine = Null was to keep it the same as TextReader.
and @RB Smissaert is interested (I think) so that his hand-crafted text file reader can be a drop-in replacement for TextReader.ReadLine.
Well, just found another bug:Great minds think alike ?
...
If (Me).As(JavaObject).RunMethod("test",Null) <> Null Then
Log("Not null")
Else
Log("It's null")
End If
...
#if java
public static String test(){
String s = null;
System.out.println("s is null = " + (s==null));
return s;
}
#End If
Actually this is another reason why doing:Well, just found another bug:
ID
1
2
3
4
5
Will miss the last 2 lines.
Will fix later.
RBS
If strLine.Length = 0 Then Exit
If strLine = "Nil else found" Then Exit
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?