B4R Question SD-card: writing .CSV files

peacemaker

Expert
Licensed User
Longtime User
Hi, All

Just trying rSD lib with ESP32 and SPI card slot.
The main, it's usage "/" root prefix at the file names.

But how to save multiline text .CSV files correctly ?

Such sub...
B4X:
private Sub Savelog As Boolean
    If sd.OpenReadWrite("/log.dat") = True Then
        sd.Position = sd.CurrentFile.Size
        For i = 0 To 4
            Dim buff() As Byte
        
            buff = BC.StringToBytes(NumberFormat (i,10,0))
            sd.Stream.WriteBytes(buff,0,buff.Length)
        
            buff = BC.StringToBytes(";")
            sd.Stream.WriteBytes(buff,0,buff.Length)
        
            buff = BC.StringToBytes("Column_")
            sd.Stream.WriteBytes(buff,0,buff.Length)
          
            buff = BC.StringToBytes(NumberFormat(i, 2, 0))
            sd.Stream.WriteBytes(buff,0,buff.Length)
        
            buff = BC.StringToBytes(";")
            sd.Stream.WriteBytes(buff,0,buff.Length)
          
            buff = BC.StringToBytes(CRLF)
            sd.Stream.WriteBytes(buff,0,buff.Length)
       Next

        sd.Close
        Log("Saved to file OK")
        Return True
    Else
        Log("SD card writing error")
        Return False
    End If
End Sub

...gives this file content:

0000000004;Column_04;
•щжеті”$дПФo’4ѓ¦Ўq ы c'.ђУСЖЧА[ј8ћ! •)¶ї“ћНaС‰ьъW7hRРkЂЇєR яy®ЌЇ7Сё, 6ЫАгЂ8€gЪњ\ѕN»Бhѓд}MJ%Xu
Џcз$ТѕќљuЌѓЁ–u№В·=}Бє¦lXwЉ:ВХvЫ™;УцЎзІ2;)ь„«Б:„!i»’;CЉh§?ЇCхe%> ыOtШрЮ@ђZЇdгIђ1ZЙЛЙrЇ{ВЁWJЃ*s*РщЭэьW0бзI^zHАю јёVш3]ЪwlЕ5;ёњђг}Ґ]^ЦЧ1H0IЪP
ЬнсВ#фо!Z}±Ћwт}‚
)%>d“ЖVяЫЎЛn©Цdєq)Аj9ЧнxZTђ5!7ҐРЭфлщ¶¦=жБ•{=РА› ЖоОюHV(™Ѕр[Э8–3(MЭXF‹›1VG‹§iїГeГlъ©kЁџ]„.9кЕ–ЩzАЄ‰уКtЂк[0000000000;Column_00;
l™оЃI“Ф`лESMл±AN©q
;gЃmeНМkзЪљўДшіМ~Н[уёіЙ"_ЬVМмн/‹ґЫ§(Е‡Љmv*uє`gBЇ0000000000;Column_00;
No idea why...
Any help ?
 

hatzisn

Expert
Licensed User
Longtime User
Try to set the buffer as fixed array and for each BC.StringToBytes create a new fixed array with length equal to string length, and BC.ArrayCopy it to buffer and write the buffer.
 
Last edited:
Upvote 0

peacemaker

Expert
Licensed User
Longtime User
B4X:
Private Sub SaveToLog As Boolean
    Dim fn As String = "/log.dat"
    Dim i As ULong = 5
   
    Do While i > 0
        Dim a As String = JoinStrings(Array As String(NumberFormat (i,10,0), ";", "Column_", NumberFormat(i, 2, 0)))
        If Save_FileLine(fn, a) = False Then
            Log("SD card writing error")
            Return False
        End If
        i = i - 1
    Loop
    Log("Saved log file OK")
    Return True
End Sub

Public Sub Save_FileLine (filename As String, line As String) As Boolean
    If sd.OpenReadWrite(filename) = True Then
        sd.Position = sd.CurrentFile.Size
       
        Dim a As String = JoinStrings(Array As String(line, CRLF))
       
        Dim buff(a.Length) As Byte = Array As Byte(0)
        buff = BC.StringToBytes(a)
        sd.Stream.WriteBytes(buff,0,buff.Length)

        sd.Close
        Return True
    Else
        Return False
    End If
End Sub

It looks like the latest buffer is ... big and random:
0000000004;Column_04;

•щжеті”$дПФo’4ѓ¦Ўq ы c'.ђУСЖЧА[ј8ћ! •)¶ї“ћНaС‰ьъW7hRРkЂЇєR яy®ЌЇ7Сё, 6ЫАгЂ8€gЪњ\ѕN»Бhѓд}MJ%Xu
Џcз$ТѕќљuЌѓЁ–u№В·=}Бє¦lXwЉ:ВХvЫ™;УцЎзІ2;)ь„«Б:„!i»’;CЉh§?ЇCхe%> ыOtШрЮ@ђZЇdгIђ1ZЙЛЙrЇ{ВЁWJЃ*s*РщЭэьW0бзI^zHАю јёVш3]ЪwlЕ5;ёњђг}Ґ]^ЦЧ1H0IЪP
ЬнсВ#фо!Z}±Ћwт}‚
)%>d“ЖVяЫЎЛn©Цdєq)Аj9ЧнxZTђ5!7ҐРЭфлщ¶¦=жБ•{=РА› ЖоОюHV(™Ѕр[Э8–3(MЭXF‹›1VG‹§iїГeГlъ©kЁџ]„.9кЕ–ЩzАЄ‰уКtЂк[0000000000;Column_00;
l™оЃI“Ф`лESMл±AN©q
;gЃmeНМkзЪљўДшіМ~Н[уёіЙ"_ЬVМмн/‹ґЫ§(Е‡Љmv*uє`gBЇ0000000005;Column_05
0000000004;Column_04
0000000003;Column_03
0000000002;Column_02
0000000001;Column_01
0000000005;Column_05
0000000004;Column_04
0000000003;Column_03
0000000002;Column_02
0000000001;Column_01
0000000005;Column_05
0000000004;Column_04
0000000003;Column_03
0000000002;Column_02
0000000001;Column_01
0000000005;Column_05
0000000004;Column_04
0000000003;Column_03
0000000002;Column_02
0000000001;Column_01

What is wrong here ?
 
Upvote 0

hatzisn

Expert
Licensed User
Longtime User
Try with this:

B4X:
private Sub Savelog As Boolean
    If sd.OpenReadWrite("/log.dat") = True Then
        sd.Position = sd.CurrentFile.Size
        For i = 0 To 4
            Dim buff(10) As Byte
            
            Dim sI As String = NumberFormat (i,10,0)
            Dim b1(sI.GetBytes.Length) As Byte
            b1 = BC.StringToBytes(sI)
            BC.ArrayCopy(b1, buff)
            sd.Stream.WriteBytes(buff,0,buff.Length)
            
            Dim b2(";".GetBytes.Length) As Byte
            b2 = BC.StringToBytes(";")
            BC.ArrayCopy(b2, buff)
            sd.Stream.WriteBytes(buff,0,buff.Length)
        
            Dim b3("Column_".GetBytes.Length) As Byte
            b3 = BC.StringToBytes("Column_")
            BC.ArrayCopy(b3, buff)
            sd.Stream.WriteBytes(buff,0,buff.Length)
          
            Dim sC As String = NumberFormat(i, 2, 0)
            Dim b4(sC.GetBytes.Length) As Byte
            b4 = BC.StringToBytes(sC)
            BC.ArrayCopy(b4, buff)
            sd.Stream.WriteBytes(buff,0,buff.Length)
        
            BC.ArrayCopy(b2, buff)
            sd.Stream.WriteBytes(buff,0,buff.Length)
            
            Dim sCRLF As String = CRLF
            Dim b5(sCRLF.GetBytes.Length) As Byte
            b5 = BC.StringToBytes(sCRLF)
            BC.ArrayCopy(b5, buff)
            sd.Stream.WriteBytes(buff,0,buff.Length)
        Next

        sd.Close
        Log("Saved to file OK")
        Return True
    Else
        Log("SD card writing error")
        Return False
    End If
End Sub
 
Upvote 0

peacemaker

Expert
Licensed User
Longtime User
Try with this
Thanks, better, but anyway strange:
0000000000;Column_00
0000000001;Column_01
0000000002;Column_02
0000000003;Column_03
0000000004;Column_04
0000000005;Column_05
0000000006;Column_06
0000000007;Column_07
0000000008;Column_08
0000000009;Column_09
0000000010;Column_10
0000000011;Column_11
0000000012;Column_12
0000000013;Column_13
0000000014;Column_14
0000000015;Column_15
0000000016;Column_16
0000000017;Column_17
0000000018;Column_18
0000000019;Column_19
0000000020;Column_20
0000000021;Column_21
0000000022;Column_22
0000000023;Column_23
0000000024;Column_24
0000000025;Column_25
0000000026;Column_26
0000000027;Col0000000000;Column_00;
0000000001;Column_01;
0000000002;Column_02;
0000000003;Column_03;
0000000004;Column_04;

It seems to me, that here better to jump into the inline C++ https://www.b4x.com/android/forum/threads/rsd32-lib-and-rsd-lib-with-esp32.162629/, it works faster and without strange file content...
But as usual, impossible without puzzles: https://www.b4x.com/android/forum/threads/how-to-use-2-string-vars-in-inline-c.162641/ :)
 
Upvote 0
Top