[Include] file_system [reduce memory usage - faster than y_ini!]
#1

file_system.inc
sscanf2 - reduce memory usage - faster than y_ini!

(registration system example at the end)


Introduction
This include allow you to read/write in any file with any extension. Using te easiest way to do it and becoming it faster than y_ini!
From this new version you can handle many files at same time without warranties. Also you will save a lot of memory by using a new system of writing/reading dates!



Benchmarks:
Код:
Loop of 2000 rounds: open a file; write/read 3 values; close it.

* WRITE:
[y_ini] 10414ms
[file_system] 4406ms - 2.36x faster than y_ini
[file_system ex] 4208ms - 2.47x faster than y_ini


* READ:
[y_ini] 1664ms
[file_system] 524 - 3.18x faster than y_ini
[file_system ex] 475ms - 3.5x faster than y_ini
PHP код:
#include <a_samp>
#include <sscanf2>
#include <file_system>
#include <YSI\y_ini>
static abimy_intbool:my_boolFloat:my_floatmy_str[10], INI:INIFile:file;
public 
OnFilterScriptInit()
{
    
// WRITE
    // y_ini
    
print("* WRITE:");
    
GetTickCount();
    for(
02000i++)
    {
        
INI INI_Open("y_ini.txt");
        
INI_WriteInt(INI"1"123);
        
INI_WriteFloat(INI"2"123.0);
        
INI_WriteString(INI"3""abc");
        
INI_Close(INI);
    }
    
GetTickCount();
    
printf("[y_ini] %ims"a);
    
// file_system.inc
    
GetTickCount();
    for(
02000i++)
    {
        
file fopen("file_system.txt"io_write)
        
File_WriteInt(file"1"123);
        
File_WriteFloat(file"2"123.0);
        
File_WriteStr(file"3""abc");
        
fclose(file);
    }
    
GetTickCount();
    
printf("[file_system] %ims"a);
    
// write_ex
    
GetTickCount();
    for(
02000i++)
    {
        
file fopen("[ex]file_system.txt"io_write)
        
File_WriteEx(file"ifs"123123.0"abc");
        
fclose(file);
    }
    
GetTickCount();
    
printf("[file_system ex] %ims\n"a);
    
// READ
    // y_ini
    
print("* READ:");
    
GetTickCount();
    for(
02000i++)
    {
        
INI_ParseFile("y_ini.txt""Y_INI");
    }
    
GetTickCount();
    
printf("[y_ini] %ims"a);
    
// file_system
    
GetTickCount();
    for(
02000i++)
    {
        
file fopen("file_system.txt"io_read)
        
File_ReadInt(file"1"my_int);
        
File_ReadFloat(file"2"my_float);
        
File_ReadStr(file"3"my_str);
        
fclose(file);
    }
    
GetTickCount();
    
printf("[file_system] %i"a);
    
// ex
    
GetTickCount();
    for(
02000i++)
    {
        
file fopen("[ex]file_system.txt"io_read)
           
File_ReadEx(file"ifs[10]"my_intmy_floatmy_str);
         
fclose(file);
    }
    
GetTickCount();
    
printf("[file_system ex] %ims\n"a);
    return 
1;
}
forward Y_INI(name[], value[]);
public 
Y_INI(name[], value[])
{
    
INI_Int("1"my_int);
    
INI_Float("2"my_float);
    
INI_String("3"my_str10);
    return 
0;



How to use:

Writing
PHP код:
public OnFilterScriptInit()
{
    new 
File:my_file fopen("file.txt"io_write)
    
File_WriteStr(my_file"String""My String");
    
File_WriteInt(my_file"Int"90412);
    
File_WriteFloat(my_file"Float"3293.0341);
    
File_WriteBool(my_file"Bool"true);
    
fclose(my_file);
    return 
1;

In the file will output:
Код:
String = My String
Int = 90412
Float = 3293.0341
Bool = true
Reading
PHP код:
public OnFilterScriptInit()
{
    new 
File:my_filemy_str[10], my_intFloat:my_floatbool:my_bool;
    
    
my_file fopen("test.txt"io_read)
    
File_ReadStr(my_file"String"my_str);
    
File_ReadInt(my_file"Int"my_int);
    
File_ReadFloat(my_file"Float"my_float);
    
File_ReadBool(my_file"Bool"my_bool);
    
fclose(my_file);
    
printf("'%s' - %i - %f - %i"my_strmy_intmy_floatmy_bool);
    return 
1;

Output:
Код:
'MyString' - 90412 - 3293.0341 - 1

Be careful! You will get wrongs values if you wrote incorrect names.
For example, you saved a value as "Password", and you are trying to read it using "Paswor", it will read this:
Код:
= MyPassword
Anyway, there's no check for these issues. You can read same value even using another word.
Example, I wrote a value as "Password", and I'm trying to read it as "LastDead", it will return the correct value because "Password" and "LastDead" has same lenght.
(keep reading below!)




Debug Mode:
"debug mode" version will help you finding some typical issues.
Just use this as usual and check out your server console, and verify that all is going good!

What does this verify?
  • 1. Check if there's a separator (Name = Value) in file line.
    2. Check if there's a line splitter (\r\n).
    3. Check out values name match.
Anyway, if is an invalid value name, it will try to read the value that was stored.
For use it, just replace "#include <file_system>" to "#include <file_system_debug>".




Using "File_*Ex" functions:
This system of write/read will save memory and write/read faster than previous examples.
You only can read/write one line per file.

Writing
PHP код:
new File:file fopen("test.txt"io_write)
File_WriteEx(file"sif""MyString"123123.123);
fclose(file); 
Output:
Код:
MyString 123 123.123000
Reading
PHP код:
new File:filemy_str[10], my_intmy_float;
file fopen("test.txt"io_read)
File_ReadEx(file"s[10]if"my_strmy_intmy_float);
fclose(file);
printf("'%s' - %i - %f"my_strmy_intmy_float); 
Output:
Код:
'My String' - 123 - 123.123000
Specifiers:
WriteEx: https://sampwiki.blast.hk/wiki/Format
ReadEx: https://sampforum.blast.hk/showthread.php?tid=602923




Registration system example:
PHP код:
#include <a_samp>
#include <sscanf2>
#include <file_system>
#define DIALOG_LOGIN            (1)
#define DIALOG_REGISTER         (2)
enum pInfo_enum
{
    
bool:LoggedIn,
    
Password[21],
    
Kills,
    
Deaths,
    
JoinsCount
};
new 
pInfo[MAX_PLAYERS][pInfo_enum];
public 
OnPlayerConnect(playerid)
{
    new 
dir[34], name[21], File:fileany;
    
GetPlayerName(playeridnamesizeof(name));
    
format(dirsizeof(dir), "users/%s.txt"name);
    
file fopen(dirio_read);
    if(
file// Check if is an registered account
    
{
        
File_ReadEx(file"s[21]i"pInfo[playerid][Password], any); // "any" is used for avoid bugs!
        
ShowPlayerDialog(playeridDIALOG_LOGINDIALOG_STYLE_PASSWORD"{00FFFF}Welcome back!""{FFFFFF}Welcome back!\nType your password below to logg in.""Next""Exit");
    }
    else 
ShowPlayerDialog(playeridDIALOG_REGISTERDIALOG_STYLE_PASSWORD"{00FFFF}Sing In.""{FFFFFF}Welcome!\nType your password below to sign in and create your data file.""Next""Exit");
    
fclose(file);
    return 
1;
}
public 
OnPlayerDisconnect(playeridreason)
{
    if(!
pInfo[playerid][LoggedIn]) return 1// Avoid bugs
    
new File:filedir[34], name[21];
    
GetPlayerName(playeridnamesizeof(name));
    
format(dirsizeof(dir), "users/%s.txt"name);
    
file fopen(dirio_write);
    
File_WriteEx(file"siii"pInfo[playerid][Password], pInfo[playerid][Kills], pInfo[playerid][Deaths], pInfo[playerid][JoinsCount]);
    
fclose(file);
    return 
1;
}
public 
OnDialogResponse(playeriddialogidresponselistiteminputtext[])
{
    switch(
dialogid)
    {
        case 
DIALOG_LOGIN:
        {
            if(!
response) return Kick(playerid);
            if(!(
<= strlen(inputtext) <= 20)) return ShowPlayerDialog(playeriddialogidDIALOG_STYLE_PASSWORD"{00FFFF}Welcome back!""{FFFFFF}Password must be between 3 and 19 chars.\nTry again:""Next""Exit");
            if(
strcmp(pInfo[playerid][Password], inputtext)) return ShowPlayerDialog(playeriddialogidDIALOG_STYLE_PASSWORD"{00FFFF}Welcome back!""{FFFFFF}That password doesn't match with this account password.\nTry again:""Next""Exit");
            new 
File:filedir[128], name[21];
            
GetPlayerName(playeridnamesizeof(name));
            
format(dir34"users/%s.txt"name);
            
file fopen(dirio_read);
            
File_ReadEx(file"s[10]iii"pInfo[playerid][Password], pInfo[playerid][Kills], pInfo[playerid][Deaths], pInfo[playerid][JoinsCount]);
            
fclose(file);
            
format(dirsizeof(dir), "[ACC] %i kills - %i deaths - %i times joined"pInfo[playerid][Kills], pInfo[playerid][Deaths], ++pInfo[playerid][JoinsCount]);
            
SendClientMessage(playerid0x00FF00FF"[ACC] You logged in successfully!");
            
SendClientMessage(playerid0x00FF00FFdir);
            return 
1;
        }
        case 
DIALOG_REGISTER:
        {
            if(!
response) return Kick(playerid);
            new 
len strlen(inputtext);
            if(!(
<= len <= 20)) return ShowPlayerDialog(playeriddialogidDIALOG_STYLE_PASSWORD"{00FFFF}Welcome back!""{FFFFFF}Password must be between 3 and 19 chars.\nTry again:""Next""Exit");
            for(new 
0<= leni++)
            {
                if(
inputtext[i] == ' ') return ShowPlayerDialog(playeriddialogidDIALOG_STYLE_PASSWORD"{00FFFF}Welcome back!""{FFFFFF}Your password cannot have spaces.\nTry again:""Next""Exit");
            }
            new 
File:filedir[34], name[21];
            
GetPlayerName(playeridnamesizeof(name));
            
format(dir34"users/%s.txt"name);
            
file fopen(dirio_write);
            
format(pInfo[playerid][Password], 21"%s"inputtext);
            
File_WriteEx(file"siii"pInfo[playerid][Password], 000);
            
fclose(file);
            
SendClientMessage(playerid0x00FF00FF"[ACC] You has been registered successfully!");
            return 
1;
        }
    }
    return 
1;
}
public 
OnPlayerDeath(playeridkilleridreason)
{
    
pInfo[playerid][Deaths] ++;
    if(
killerid != 0xFFFpInfo[killerid][Kills] ++;
    return 
1;


Updates:
v06/12/16.
v11/12/16.


Download
http://pastebin.com/sSQWnwcc

Last compilation: 06/12/16:
Reply


Messages In This Thread

Forum Jump:


Users browsing this thread: 1 Guest(s)