forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   BlitzMax (http://forum.boolean.name/forumdisplay.php?f=104)
-   -   Сохранение/чтение данных в/из файла (http://forum.boolean.name/showthread.php?t=20450)

edgemza 21.10.2016 11:33

Сохранение/чтение данных в/из файла
 
Приветствую!
Пожалуйста помогите мне, как можно организовать запись необходимых переменных различного типа (int, float, string и т.д.) в файл, а потом загрузку этих данных из файла.
В сети очень мало информации вообще по Блицу и по работе с файлами (в частности).
Как можно сохранять/читать так, чтобы потом не запутаться в очередности сохраненных данных и не загрузить вместо одних данных другие?
========
Вот что мне нужно:
есть переменные, например,
Global BoxMainX=BoxBsX
Global BoxMainY=BoxBsY+BoxBsH+26
Global BoxMainW=650
Global BoxMainH=470
Global BoxMainY2=BoxMainY+BoxMainH
V[1]=2000
V[2]=3000
V[3]=4000
V[4]=6000
V[5]=8000
V[6]=10000
V[7]=15000
V[8]=25000
Global FileBall$="Ball03s.wav"
и т.д.
'читаем переменные из файла
'используем/изменяем переменные
'сохраняем все нужные переменные обратно в файл
' в идеале будет, если при смене 2-х, 3-х переменных их нужно сразу же записать в файл "на своё место", иначе при выключении света или др.критических ситуациях ("вылете" и т.п.) они не будут сохранены
================
Я так понял, что есть специально ini-файлы.
Какие файлы лучше использовать ini-файлы или обычные (бинарные) и как с ними работать?

mingw 20.11.2016 13:26

Ответ: Сохранение/чтение данных в/из файла
 
Использовать отражение.

По этому случаю есть отличный модуль :

Код:

SuperStrict

Rem
bbdoc: 0==K5
End Rem
Module data.TData

ModuleInfo "5@A8O: 1.21"
ModuleInfo "2B>@ : ;L15@B 0A:0@>2"
ModuleInfo "!5@25@: API"

ModuleInfo "AB>@8O: 1.21"
ModuleInfo "AB>@8O: >@01>B:8"
ModuleInfo "AB>@8O: 1.20"
ModuleInfo "AB>@8O: 5@5@01>B:0 <>4C;O"
ModuleInfo "AB>@8O: 1.16"
ModuleInfo "AB>@8O: >102;5=K <5B>4K Write\ReadCString 2 :0G5AB25 M:A?5@8<5=B0"
ModuleInfo "AB>@8O: 1.15"
ModuleInfo "AB>@8O: >102;5= D;03 'no_save' :;0AA0<"
ModuleInfo "AB>@8O: 1.14"
ModuleInfo "AB>@8O: 5@58<5=>20= <5B>4 Tag() -> ToString()"
ModuleInfo "AB>@8O: "5?5@L 2 <5B>45 ToString() <>6=> 704020BL D8;LB@"
ModuleInfo "AB>@8O: 1.12"
ModuleInfo "AB>@8O: >@01>B:8 2 45AB@C:B>@5"
ModuleInfo "AB>@8O: !>740=85 >1L5:B=>3> ?>B>:0 B5?5@L ?@>8AE>48B G5@57 <5B>4-:>=AB@C:B>@"
ModuleInfo "AB>@8O: 1.10"
ModuleInfo "AB>@8O: #;CGH5=8O"
ModuleInfo "AB>@8O: #;CGH5=8O"
ModuleInfo "AB>@8O: 1.00"
ModuleInfo "AB>@8O: 5@2K9 @5;87"

Import brl.blitz      ' import BlitzMax
Import brl.stream    ' import TStream class
Import brl.reflection ' import Objects reflection

Public

Rem
bbdoc: 1L5:B 40==KE
End Rem
Type TData Abstract
        Method New()
                TObjectStream._datas:+[Self]
        End Method
       
        Rem
        bbdoc: "M3"
        End Rem
        Method ToString:String() Abstract
       
        Rem
        bbdoc: $C=:F8O GB5=8O >1L5:B0
        End Rem
        Method ReadObject:Object(stream:TStream) Abstract
       
        Rem
        bbdoc: $C=:F8O 70?8A8 >1L5:B0
        End Rem
        Method WriteObject(obj:Object, stream:TStream) Abstract
End Type

Rem
bbdoc: 1L5:B 40==KE
End Rem
Function CreateObjectStream:TStream(stream:TStream)
        Return New TObjectStream.Create(stream)
End Function

Function LoadObject:Object(url:Object)
        Local stream:TStream = TStream(url)
        If Not stream Then stream = ReadStream(url)
        Return CreateObjectStream(stream).ReadObject()       
End Method

Function SaveObject(obj:Object, url:Object)
        Local stream:TStream = TStream(url)
        If Not stream Then stream = WriteStream(url)
        CreateObjectStream(stream).WriteObject(obj)
End Function

Function CopyObject:Object(obj:Object, tid:TTypeId = Null)
       
        If Not tid
                tid:TTypeId = TTypeId.ForObject(obj)
        End If
       
        If tid.MetaData("no_copy") Then Return tid.NewObject()
       
        Select tid ' awesome!
        Case ByteTypeId, ShortTypeId, IntTypeId, LongTypeId, FloatTypeId, DoubleTypeId, StringTypeId
                Return String(obj)
        End Select
       
        Local copy:Object
       
        If tid.Name().EndsWith("]") 'ElementType() ' array
               
                copy = tid.NewArray(tid.ArrayLength(obj)) ' 1d array
               
               
               
                Return copy
               
        End If
       
        copy = tid.NewObject()
       
        For Local f:TField = EachIn tid.EnumFields()
       
                If f.MetaData("no_copy") Then Continue
               
                Local etid:TTypeId = TTypeId.ForName(f.TypeId().Name())
               
                Select etid
                Case ByteTypeId, ShortTypeId, IntTypeId
                        f.SetInt(copy, f.GetInt(obj))
                Case LongTypeId
                        f.SetLong(copy, f.GetLong(obj))
                Case FloatTypeId
                        f.SetFloat(copy, f.GetFloat(obj))
                Case DoubleTypeId
                        f.SetDouble(copy, f,GetDouble(obj))
                Case StringTypeId
                        f.SetString(copy, f.GetString(obj))
                Default
                        f.Set(copy, CopyObject(f.Get(obj), etid))
                End Select
               
        Next
       
        Return copy
       
End Function

Private

Rem       
        ------OBJECT-STREAMS------
        | PROTOCOL  : "object"  |
        | NOSAVE TAG : "no_save" |
        --------------------------
       
        -------------------------READING--------------------------
        | Local stream:TStream = ReadStream("object::file.txt")  |
        | Local obj:Object = stream.ReadObject()                |
        ----------------------------------------------------------
       
        -------------------------WRITEING-------------------------
        | Local stream:TStream = WriteStream("object::file.txt") |
        | stream.WriteObject(obj)                                |
        ----------------------------------------------------------
EndRem

Type TObjectStream Extends TStreamWrapper
        Global _datas:TData[]
        Global _tid:TTypeId = Null
       
        Method Close()
                _stream.Close()
                SetStream(Null)
        End Method
       
        Method Delete()
                If _stream Then Close()
        End Method
       
        Method Create:TStream(stream:TStream)
                SetStream(stream)
                Return Self
        End Method
       
        Method ClearArrayName:String(name:String)
                Return name[..name.FindLast("[")]
        End Method
       
        Method DataTypeId:TData(tid:TTypeId)
                Local tags:String[], i:Int
                For Local data:TData = EachIn _datas
                        tags = data.ToString().Split(" ")
                        If tid.Name().ToLower() <> tags[0].ToLower() Then Continue
                        For i = 1 Until tags.Length
                                If Not tid.MetaData(tags[i])
                                        i = 0
                                        Exit
                                End If
                        Next
                        If i = 0 Then Continue
                        Return data
                Next
        End Method
       
        Rem
        Method WriteCString:Int(str:String)
                Return Write(str + "~0", str.Length + 1)
        End Method
       
        Method ReadCString:String()
                Local mem:Byte Ptr = MemAlloc(Size() - pos())
                Local i:Int
                While Not Eof()
                        mem[i] = ReadByte()
                        If mem[i] = 0 Then Exit
                        i:+1
                Wend
                Local str:String = String.FromCString(mem)
                MemFree(mem)
                Return str
        End Method
        end rem
       
        '--------------------------------------------------------------------------------------------------------------
       
        Method ReadObject:Object()
                Select ReadByte()
                        Case 59 Return Null
                        Case 123
                        Default Throw New TStreamReadException
                End Select
       
                Local tid:TTypeId = ReadTypeId()
               
                Local obj:Object = ReadSingle(tid)
                If obj Then Return obj
               
                If tid.MetaData("no_save") Then Return tid.NewObject()
               
                obj = ReadArray(tid)
                If obj Then Return obj
               
                obj = ReadFromData(tid)
                If obj Then Return obj
               
                Return ReadFields(tid)
        End Method
       
        Method ReadTypeId:TTypeId()
                Local mem:Byte Ptr = MemAlloc(Size() - pos())
                Local i:Int
                While Not Eof()
                        mem[i] = ReadByte()
                        If mem[i] = 125
                                mem[i] = 0
                                Exit
                        End If
                        i:+1
                Wend
                Local name:String = String.FromCString(mem)
                MemFree(mem)
?Debug
                Local t:TTypeId = TTypeId.ForName(name)
                If Not t Then WriteStdout("WARNING! Type id not created -> " + name + "~n")
                Return t
?
                Return TTypeId.ForName(name)
        End Method
       
        Method ReadSingle:Object(tid:TTypeId)
                Select tid
                Case ByteTypeId Return String.FromInt(ReadByte())
                Case ShortTypeId Return String.FromInt(ReadShort())
                Case IntTypeId Return String.FromInt(ReadInt())
                Case LongTypeId Return String.FromLong(ReadLong())
                Case FloatTypeId Return String.FromFloat(ReadFloat())
                Case DoubleTypeId Return String.FromDouble(ReadDouble())
                Case StringTypeId Return ReadString(ReadInt())
                End Select
        End Method
       
        Method ReadArray:Object(tid:TTypeId)
       
                If tid.ElementType()
               
                        Local dims:Int = ReadInt()
                        Local array:Int[] = New Int[dims]
                        Local ln:Int
                        For Local i:Int = 0 Until dims
                                array[i] = ReadInt()
                                If i = 0
                                        ln = array[i]
                                Else
                                        array[i + ~0] :/array[i]
                                End If
                        Next
                        Local obj:Object = tid.NewArray(ln, array)
                        Local etid:TTypeId = TTypeId.ForName(ClearArrayName(tid.Name()))
                        For Local pos:Int = 0 Until ln
                                Select etid
                                        Case ByteTypeId tid.SetArrayElement(obj, pos, Object(String(ReadByte())))
                                        Case ShortTypeId tid.SetArrayElement(obj, pos, Object(String(ReadShort())))
                                        Case IntTypeId tid.SetArrayElement(obj, pos, Object(String(ReadInt())))
                                        Case LongTypeId tid.SetArrayElement(obj, pos, Object(String(ReadLong())))
                                        Case FloatTypeId tid.SetArrayElement(obj, pos, Object(String(ReadFloat())))
                                        Case DoubleTypeId tid.SetArrayElement(obj, pos, Object(String(ReadDouble())))
                                        Case StringTypeId tid.SetArrayElement(obj, pos, Object(ReadString(ReadInt())))
                                        Default tid.SetArrayElement(obj, pos, ReadObject())
                                End Select
                        Next
                        Return obj
                End If
        End Method
       
        Method ReadFromData:Object(tid:TTypeId)
                Local data:TData = DataTypeId(tid)
                If data Then Return data.ReadObject(Self)
        End Method
       
        Method ReadFields:Object(tid:TTypeId)
                Local obj:Object = tid.NewObject()
                For Local f:TField = EachIn tid.EnumFields()
                        If f.MetaData("no_save") Then Continue
                        Local etid:TTypeId = TTypeId.ForName(f.TypeId().Name())
                        'DebugLog "Reading field : " + etid.Name()
                        Select etid
                                Case ByteTypeId f.SetInt(obj, ReadByte())
                                Case ShortTypeId f.SetInt(obj, ReadShort())
                                Case IntTypeId f.SetInt(obj, ReadInt())
                                Case LongTypeId f.SetLong(obj, ReadLong())
                                Case FloatTypeId f.SetFloat(obj, ReadFloat())
                                Case DoubleTypeId f.SetDouble(obj, ReadDouble())
                                Case StringTypeId f.SetString(obj, ReadString(ReadInt()))
                                Default f.Set(obj, ReadObject())
                        End Select
                Next
                Return obj
        End Method
       
        '--------------------------------------------------------------------------------------------------------------
       
        Method WriteObject:Int(obj:Object)
                If obj = Null
                        WriteByte(59)
                        _tid = Null
                        Return False
                End If
                WriteByte(123)
               
                Local tid:TTypeId = _tid
                _tid = Null
                If tid = ObjectTypeId Then tid = TTypeId.ForObject(obj)
                If Not tid Then tid = TTypeId.ForObject(obj)
               
                DebugLog "TID = " + tid.Name()
               
                If Not WriteTypeId(tid) Then Return False
               
                If WriteSingle(tid, obj) Then Return True
               
                If tid.MetaData("no_save") Then Return True
               
                If WriteArray(tid, obj) Then Return True
               
                If WriteData(tid, obj) Then Return True
               
                Return WriteFields(tid, obj)
        End Method
       
        Method WriteTypeId:Byte(tid:TTypeId)
                'DebugLog "Writing : " + tid.Name()
                Local name:String = tid.Name() + "}"
                Return WriteBytes(name, name.Length) = name.Length
        End Method
       
        Method WriteSingle:Byte(tid:TTypeId, obj:Object)
                Select tid
                        Case ByteTypeId WriteByte(Byte(obj.ToString())) ; Return True
                        Case ShortTypeId WriteShort(Short(obj.ToString())) ; Return True
                        Case IntTypeId WriteInt(Int(obj.ToString())) ; Return True
                        Case LongTypeId WriteLong(Long(obj.ToString())) ; Return True
                        Case FloatTypeId WriteFloat(Float(obj.ToString())) ; Return True
                        Case DoubleTypeId WriteDouble(Double(obj.ToString())) ; Return True
                        Case StringTypeId
                                WriteInt(obj.ToString().Length)
                                WriteString(obj.ToString())
                                Return True
                End Select
        End Method
       
        Method WriteArray:Byte(tid:TTypeId, obj:Object)
                If tid.Name().EndsWith("]")
                        DebugLog "Array : " + tid.Name()
                        Local etid:TTypeId = TTypeId.ForName(ClearArrayName(tid.Name()))
                        WriteInt(tid.ArrayDimensions(obj))
                        DebugLog "Array Dims : " + tid.ArrayDimensions(obj)
                        For Local i:Int = 0 Until tid.ArrayDimensions(obj)
                                WriteInt(tid.ArrayLength(obj, i))
                                DebugLog "Array DIM Length : " + tid.ArrayLength(obj, i)
                        Next
                        DebugLog "Array FULL LENGTH : " + tid.ArrayLength(obj)
                       
                        For Local pos:Int = 0 Until tid.ArrayLength(obj)
                                Select etid
                                        Case ByteTypeId WriteByte(tid.GetArrayElement(obj, pos).ToString().ToInt())
                                        Case ShortTypeId WriteShort(tid.GetArrayElement(obj, pos).ToString().ToInt())
                                        Case IntTypeId WriteInt(tid.GetArrayElement(obj, pos).ToString().ToInt())
                                        Case LongTypeId WriteLong(tid.GetArrayElement(obj, pos).ToString().ToLong())
                                        Case FloatTypeId WriteFloat(tid.GetArrayElement(obj, pos).ToString().ToFloat())
                                        Case DoubleTypeId WriteDouble(tid.GetArrayElement(obj, pos).ToString().ToDouble())
                                        Case StringTypeId
                                                WriteInt(tid.GetArrayElement(obj, pos).ToString().Length)
                                                WriteString(tid.GetArrayElement(obj, pos).ToString())
                                        Default
                                                _tid = Null
                                                WriteObject(tid.GetArrayElement(obj, pos))
                                End Select
                        Next
                        Return True
                End If
        End Method
       
        Method WriteData:Byte(tid:TTypeId, obj:Object)
                Local data:TData = DataTypeId(tid)
                If data
                        data.WriteObject(obj, Self)
                        Return True
                End If
        End Method
       
        Method WriteFields:Byte(tid:TTypeId, obj:Object)
                For Local f:TField = EachIn tid.EnumFields()
                        If f.MetaData("no_save") Then Continue
                        Local etid:TTypeId = f.TypeId()
                        'DebugLog "Write field : " + etid.Name()
                        Select etid
                                Case ByteTypeId WriteByte(f.GetInt(obj))
                                Case ShortTypeId WriteShort(f.GetInt(obj))
                                Case IntTypeId WriteInt(f.GetInt(obj))
                                Case LongTypeId WriteLong(f.GetLong(obj))
                                Case FloatTypeId WriteFloat(f.GetFloat(obj))
                                Case DoubleTypeId WriteDouble(f.GetDouble(obj))
                                Case StringTypeId
                                        WriteInt(f.GetString(obj).Length)
                                        WriteString(f.GetString(obj))
                                Default
                                        _tid = etid
                                        WriteObject(f.Get(obj))
                        End Select
                Next
                Return True
        End Method
End Type

Type TObjectStreamFactory Extends TStreamFactory
        Method CreateStream:TStream(url:Object, proto:String, path:String, readable:Int, writeable:Int)
                If proto = "object" Then
                        Local stream:TStream = OpenStream(path, readable, writeable)
                        If stream Then Return New TObjectStream.Create(stream)
                End If
        End Method
End Type

Function Free()
        TObjectStream._datas = Null
        TObjectStream._tid = Null
End Function

Function install()
        New TObjectStreamFactory
        OnEnd(Free)
End Function

install()

Только помни, юный падаван... это добро работает только с обьектами на верхнем уровне.


Часовой пояс GMT +4, время: 14:00.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot