Friday, June 6, 2014

Using Files to write data/values - Sử dụng tập tin để ghi dữ liệu / giá trị


Đây là một ít hướng dẫn về đọc / ghi tập tin để lưu trữ một cái gì đó. 
Hướng dẫn này cần điều cơ bản trong amxx Scripting. 
Tôi không tốt trong giải thích và viết Hướng dẫn, do đó hầu hết được viết như mã. 
Tôi không giải thích mỗi lệnh. 
Nếu có gì đó sai hoặc tốt hơn xin vui lòng gửi.

Cho phép bắt đầu với các lệnh tập tin cũ (dễ dàng và ngắn).

Code:
read_file ( const file[], line, text[], len, &txtLen )
Đọc một dòng cụ thể với chiều dài được vào một mảng. 
Nó trả về chỉ số của dòng tiếp theo hoặc 0 khi kết thúc các tập tin được đạt tới. 

Số ký tự đọc được lưu trữ trong txtLen.
Code:
write_file ( const file[], const text[], [ line ] )
Viết một mảng cho tập tin vào dòng nhất định, nếu dòng là -1 nó viết ở cuối của tập tin

Code:
#include <amxmodx> #include <amxmisc> #define PLUGIN "Filehandle" #define VERSION "1.0" #define AUTHOR "Administrator" new filename[256] public plugin_init() {     register_plugin(PLUGIN, VERSION, AUTHOR)         /*Lấy thư mục cấu hình của amxx*/     get_configsdir(filename,255)     format(filename,255,"%s/filehandle.txt",filename)     register_concmd("amx_filetestwrite","filewritetest")     register_concmd("amx_filetestread","filereadtest") } public filewritetest(id){     new writedata[128]     new steamid[32],name[32],anyvalue,Float:anyfloatvalue         /*Cho phép tạo và sao chép một số dữ liệu giả*/     get_user_authid(id,steamid,31)     get_user_name(id,name,31)     anyvalue = 10     anyfloatvalue = 5.5         formatex(writedata,127,"%s %s %d %f",steamid,name,anyvalue,anyfloatvalue)         /*Bây giờ viết data vào cuối dòng
write_file( const file[], const text, [ line ] )
DÒng mặc định tham số -1, là ghi thêm vào cuối tập tin, nếu không một dòng cụ thể được ghi đè. Nếu tập tin không tồn tại thì amxx sẽ tự tạo ra nó. */     write_file(filename,writedata) } public filereadtest(id){     new readdata[128],steamid[32],anyvalue,Float:anyfloatvalue,txtlen     new parsedsteamid[32],parsedname[32],parsedanyvalue[8],parsedanyfloatvalue[8]         /*Bây giờ chúng ta sẽ đọc dữ liệu từ file*/     /*Có 2 cách để đọc cho đến khi hết file*/         /*Cách 1*/     /*file_size - Trả về kích thước file.     Nếu flag là 0, kích thước trả về là byte.     Nếu flag là 1, trả về số dòng của file.     Nếu flag là 2, 1 is returned if the file ends in a line feed.     If the file doesn't exist, -1 is returned. */     new fsize = file_size(filename,1)     for (new line=0;line<=fsize;line++)     {         /*read_file ( const file[], line, text[], len, &txtLen )*/         read_file(filename,line,readdata,127,txtlen)         /*We must parse the readata in somthing that we can use*/         parse(readdata,parsedsteamid,31,parsedname,31,parsedanyvalue,7,parsedanyfloatvalue,7)                 /*check if steamid the same as in file*/         get_user_authid(id,steamid,31)         if(equal(steamid,parsedsteamid))         {             /*steamid is same as in file,the do somthing with the rest of parsed values*/             anyvalue = str_to_num(parsedanyvalue)             anyfloatvalue = str_to_float(parsedanyfloatvalue)             client_print(id,print_chat,"Your saved Steamid:%s Name:%s Value:%d FloatValue:%f",parsedsteamid,parsedname,anyvalue,anyfloatvalue)             /*i use break to stop the loop to save more performance.On big files this is good*/             break             //...         }     }         /*Cachs2 Cách tốt nhất*/     new line = 0     while(!read_file(filename,line++,readdata,127,txtlen))     {         parse(filename,parsedsteamid,31,parsedname,31,parsedanyvalue,7,parsedanyfloatvalue,7)                 get_user_authid(id,steamid,31)         if(equal(steamid,parsedsteamid))         {             anyvalue = str_to_num(parsedanyvalue)             anyfloatvalue = str_to_float(parsedanyfloatvalue)             client_print(id,print_chat,"Your saved Steamid:%s Name:%s Value:%d FloatValue:%f",parsedsteamid,parsedname,anyvalue,anyfloatvalue)             break             //...         }     }    }

Tiếp theo là các lệnh tập tin mới (nhiều và rất mạnh mẽ)

Cho phép bắt đầu với những điều cơ bản của lệnh tập tin mới và ghi / đọc một chuỗi bên trong một file.

Điều này là tốt cho textfiles nơi dễ dàng có thể đọc các tập tin 

Các lệnh tập tin mới không đọc linespecific, họ sử dụng một con trỏ bên trong tập tin để đọc dữ liệu. 

Vị trí con trỏ này có thể nhận được với
Code:
ftell(file)
Và con trỏ có thể thiết lập với
Code:
fseek ( file, position, start )
"position" là độ lệch từ đầu
start có thể là:
Code:
SEEK_SET //bắt đầu file
SEEK_CUR //vị trí con trỏ hiện tại
SEEK_END //Kết thúc file
Code:
rewind ( file )
di chuyển vị trí con trỏ để bắt đầu của tập tin.

Code:
fopen ( filename[], mode[] )
Mở một tập tin với tên tập tin nhất định và chế độ. 
Nó trả về một con trỏ vào tập tin.

Code:
fputs ( file, const text[])
Viết một chuỗi vào một tập tin văn bản tại vị trí filecursor hiện hành. 

"file" phải là một con trỏ đến một tập tin từ lệnh fopen.
Code:
fprintf ( file, const buffer[], ... )
Viết một chuỗi formated một file.Same văn bản như lệnh định dạng / formatex, nhưng cho các tập tin. 


fputs / fprint không thêm một dòng mới vào cuối chuỗi, vì vậy nó phải thiết lập bằng tay.
Code:
fgets ( file, buffer[], maxlength )
Đọc một dòng (bao gồm cả dòng mới) từ một tập tin văn bản từ vị trí hiện tại cho đến khi filecursor maxlenght đạt hoặc xuống dòng / kết thúc của tập tin được thành lập.
Code:
#include <amxmodx> #include <amxmisc> #define PLUGIN "Filehandle" #define VERSION "1.0" #define AUTHOR "Administrator" new filename[256] public plugin_init() {     register_plugin(PLUGIN, VERSION, AUTHOR)         get_configsdir(filename,255)     format(filename,255,"%s/filehandle.txt",filename)     register_concmd("amx_filetestwrite","filewritetest")     register_concmd("amx_filetestread","filereadtest") } public filewritetest(id){     new writedata[128]     new steamid[32],name[32],anyvalue,Float:anyfloatvalue         get_user_authid(id,steamid,31)     get_user_name(id,name,31)     anyvalue = 10     anyfloatvalue = 5.5         /*fopen - Returns a file handle for advanced file functions.     Mode uses the standard C library of mode types.     The first character can be:     "a" - append     "r" - read     "w" - write         The second character can be:     "t" - text     "b" - binary         You can also append a "+" to specify both read and write.     Open a file in append+read+write mode     On mode "a+"/"w+" it create a file if there no exist     Mode "w+" overwrite a file if one exist*/     new filepointer = fopen(filename,"a+")     /*check if file is open,on an error filepointer is 0*/     if(filepointer)     {         /*It give 2 ways to write a string inside a file*/                 /*First way*/         formatex(writedata,127,"%s %s %d %f^n",steamid,name,anyvalue,anyfloatvalue)         //The new file commands need to create a newline manual with "^n"                 /*write the string to the file*/         /*another commands are:         fputc - Writes a char (1 byte) to a file handle.         fputf - Writes a float (4 bytes, 8 on AMD64) to a file handle.         fputi - Writes an integer (4 bytes) to a file handle.         fputl - Writes a long (4 bytes) to a file handle. */         fputs(filepointer,writedata)                 /*Second way*/         /*fprintf - Writes a line to a file */         fprintf(filepointer,"%s %s %d %f^n",steamid,name,anyvalue,anyfloatvalue)                 /*close the file,this is optional,but better is it to close the file*/         fclose(filepointer)     } } public filereadtest(id){     /*open file in read-mode*/     new filepointer = fopen(filename,"r")     /*check if file is open,on an error filepointer is 0*/     if(filepointer)     {         new readdata[128],steamid[32],anyvalue,Float:anyfloatvalue         new parsedsteamid[32],parsedname[32],parsedanyvalue[8],parsedanyfloatvalue[8]             /*Read the file until it is at end of file*/         /*fgets - Reads a line from a text file -- includes newline!*/         while(fgets(filepointer,readdata,127))         {                parse(readdata,parsedsteamid,31,parsedname,31,parsedanyvalue,7,parsedanyfloatvalue,7)                     get_user_authid(id,steamid,31)             if(equal(steamid,parsedsteamid))             {                 anyvalue = str_to_num(parsedanyvalue)                 anyfloatvalue = str_to_float(parsedanyfloatvalue)                 client_print(id,print_chat,"Your saved Steamid:%s Name:%s Value:%d FloatValue:%f",parsedsteamid,parsedname,anyvalue,anyfloatvalue)                 break                 //...             }         }         fclose(filepointer)     } }

Để viết một tập tin mà phải tiết kiệm rất nhiều dữ liệu, các plugin đang phát triển lớn và rất nhiều công việc để viết với cách sử dụng màu Tây Nguyên, str_to_, ...

Dưới đây là một mẹo nhỏ mà tôi đã học cách sử dụng strucs trong Pawn.
Điều này là rất dễ dàng để quản lý các fileData và thêm dữ liệu mới, nhưng mọi thay đổi cần phải thay đổi / chuyển đổi cũng tập tin.

Code:
enum enumname{}
enum cho biến bên trong {} một số. Nó bắt đầu với số 0. 

Với "variablename mới [enumname]" nó tạo ra một biến với arraylenght của enum định.
Code:
fwrite_raw ( file, const stream[], blocksize, mode )
Viết một mảng tới các tập tin ở vị trí con trỏ hiện tại. "blocksize" là kích thước của mảng hoặc chiều dài những người muốn viết.
Mode có thể là:
Code:
BLOCK_INT //Good to write any value/char
BLOCK_SHORT //For writing values -32767 -> 32767 and chars
BLOCK_CHAR //Good for writing chars/values -127 -> 127
BLOCK_BYTE //Same as char
Code:
fread_raw ( file, stream[], blocksize, blocknum )
Đọc khối blocknum từ một tập tin tại vị trí con trỏ tập tin hiện tại cho đến khi đạt được blocksize hoặc cuối của tập tin được tìm thấy. Nó trả về số lượng các khối thành công readed.

Code:
#include <amxmodx> #include <amxmisc> #define PLUGIN "Filehandle" #define VERSION "1.0" #define AUTHOR "Administrator" new filename[256] enum PLAYER_DATABASE {     STEAMID[32],     NAME[32],     ANYVALUE,     ANYFLOATVALUE,         PLAYER_DATABASE_END } new player_data[33][PLAYER_DATABASE] public plugin_init() {     register_plugin(PLUGIN, VERSION, AUTHOR)         get_configsdir(filename,255)     format(filename,255,"%s/filehandle.txt",filename)     register_concmd("amx_filetestwrite","filewritetest")     register_concmd("amx_filetestread","filereadtest") } public filewritetest(id){     /*Lets create and copy some dummy data into data*/     get_user_authid(id,player_data[id][STEAMID],31)     get_user_name(id,player_data[id][NAME],31)     player_data[id][ANYVALUE] = 10     /*theres a little problem with enum and floats:player_data[id][ANYFLOATVALUE] = 5.5 return an tag mismatch error     this error can be ignored but a better way is using _: in front of the float value*/     player_data[id][ANYFLOATVALUE] = _:5.5         new fp=fopen(filename,"a+")     if(fp)     {         /*There exist 3 commands         fwrite - Writes an element to a file (for single chars)         fwrite_blocks - Writes a block of data in a file (for unknown,havent get any good results with this)         fwrite_raw - Writes blocks of data to a file (for strings/arrays)*/         fwrite_raw(fp,player_data[id][PLAYER_DATABASE:0],sizeof(player_data[]),BLOCK_INT)         /*Now i explain the fwrite_raw         fp is the filepointer         player_data[id] is the data from player         [PLAYER_DATABASE:0] is the begining of the data who want to write,         to write only Steamid it need to use player_data[id][PLAYER_DATABASE:STEAMID]         sizeof(player_data[]) is the lenght of data which want to write,         to write somthing like only steamid it need "player_data[id][PLAYER_DATABASE:STEAMID],32"         */     }     fclose(fp)  } public filereadtest(id){     new readdata[PLAYER_DATABASE],steamid[32]     new fp=fopen(filename,"r")     if(fp)     {         while(fread_raw(fp,readdata[PLAYER_DATABASE:0],sizeof(player_data[]),1))         {                get_user_authid(id,steamid,31)             if(equal(steamid,readdata[STEAMID]))             {                 player_data[id][ANYVALUE] = readdata[ANYVALUE]                 player_data[id][ANYFLOATVALUE] = _:readdata[ANYFLOATVALUE]                 copy(player_data[id][STEAMID],31,readdata[STEAMID])                 copy(player_data[id][NAME],31,readdata[NAME])                 client_print(id,print_chat,"Your saved Steamid:%s Name:%s Value:%d FloatValue:%f",readdata[STEAMID],readdata[NAME],readdata[ANYVALUE],readdata[ANYFLOATVALUE])                 client_print(id,print_chat,"Your saved Data:%s Name:%s Value:%d FloatValue:%f",player_data[id][STEAMID],player_data[id][NAME],player_data[id][ANYVALUE],player_data[id][ANYFLOATVALUE])                 break                 //...             }         }     }     fclose(fp) }

Tôi hy vọng tôi có thể giúp một số với hướng dẫn này rất ít. 

Cuối cùng tôi thêm Plugin thức có thể được sử dụng như là cốt lõi để viết / đọc dữ liệu từ tập tin.

0 nhận xét:

Post a Comment