二進(jìn)制數(shù)據(jù)編程指南--<Binary Data Programming Guide>翻譯

翻譯連接https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/BinaryData/BinaryData.html#//apple_ref/doc/uid/10000037-SW1

簡介

在Foundation框架和Core Foundation框架可以將二進(jìn)制封裝為對(duì)象并對(duì)其進(jìn)行操作。因?yàn)閿?shù)據(jù)對(duì)象是橋接對(duì)象樊展,所以開發(fā)者可以交替使用Core Foundation數(shù)據(jù)對(duì)象和Foundation對(duì)象腾窝。數(shù)據(jù)對(duì)象可以自動(dòng)管理字節(jié)緩沖區(qū)的內(nèi)存開辟和內(nèi)存釋放。數(shù)據(jù)對(duì)象可以被存儲(chǔ)在集合中井氢,吸入屬性列表,存儲(chǔ)在文件中岳链,以及在通訊端口之間進(jìn)行傳輸花竞。

本文檔的結(jié)構(gòu)

下面的文章介紹了數(shù)據(jù)對(duì)象是如何運(yùn)作的
《數(shù)據(jù)對(duì)象》描述了數(shù)據(jù)對(duì)象是如何對(duì)緩沖字節(jié)進(jìn)行封裝的

下面的文章介紹了一般的任務(wù)
《二進(jìn)制數(shù)據(jù)的使用》解釋了如何創(chuàng)建和使用二進(jìn)制數(shù)據(jù)對(duì)象
《可變二進(jìn)制數(shù)據(jù)的使用》解釋了如何修改二進(jìn)制數(shù)據(jù)對(duì)象中的字節(jié)緩沖

數(shù)據(jù)對(duì)象

數(shù)據(jù)對(duì)象就是對(duì)緩沖字節(jié)進(jìn)行面向?qū)ο蠡姆庋b宅静。在這些數(shù)據(jù)對(duì)象中糟描,簡單開辟的緩存區(qū)(也就是不包含嵌套指針)具有其他對(duì)象的一些行為—也就是說碑定,它們既能夠包含數(shù)據(jù)叁扫,又能提供對(duì)這些數(shù)據(jù)的操作方法吼鱼。數(shù)據(jù)對(duì)象通常被用來存儲(chǔ)數(shù)據(jù)供鸠。數(shù)據(jù)對(duì)象在互聯(lián)網(wǎng)以及內(nèi)部網(wǎng)絡(luò)的應(yīng)用中非常有用密末,因?yàn)閿?shù)據(jù)對(duì)象中被包含的數(shù)據(jù)可以在應(yīng)用之間進(jìn)行傳輸抢腐。
一個(gè)NSData或者NSMutableData對(duì)象所能夠封裝的數(shù)據(jù)大小取決于對(duì)應(yīng)的平臺(tái)限制摔癣,相關(guān)細(xì)節(jié)請(qǐng)參照NSData文檔奴饮。當(dāng)數(shù)據(jù)大小略大于幾個(gè)內(nèi)存頁的時(shí)候,目標(biāo)對(duì)象就會(huì)使用虛擬內(nèi)存管理機(jī)制择浊。數(shù)據(jù)對(duì)象還可以對(duì)已有數(shù)據(jù)進(jìn)行封裝拐云,而不用考慮這些數(shù)據(jù)是如何被創(chuàng)建的。數(shù)據(jù)對(duì)象不會(huì)保存和緩沖數(shù)據(jù)有關(guān)的其他信息(比如數(shù)據(jù)的類型)近她;如何使用數(shù)據(jù)取決于客戶端叉瘩。尤其要注意的是,數(shù)據(jù)對(duì)象并不負(fù)責(zé)在大小端設(shè)備之間的相關(guān)轉(zhuǎn)換粘捎。取而代之的方案是薇缅,針對(duì)相關(guān)類型對(duì)象使用NSValue進(jìn)行管理危彩。
數(shù)據(jù)對(duì)象提供了一種與操作系統(tǒng)無關(guān)的方式來實(shí)現(xiàn)寫時(shí)拷貝。所謂的寫時(shí)拷貝技術(shù)就是說泳桦,當(dāng)數(shù)據(jù)從虛擬內(nèi)存進(jìn)行拷貝的時(shí)候汤徽,只有操作方試圖對(duì)目標(biāo)數(shù)據(jù)進(jìn)行修改的時(shí)候,才會(huì)真正地執(zhí)行拷貝操作灸撰。
一種典型操作就是當(dāng)創(chuàng)建一個(gè)數(shù)據(jù)對(duì)象的時(shí)候谒府,可以指定緩存區(qū)的大小。開發(fā)者還可以提取指定范圍的緩存數(shù)據(jù)浮毯,對(duì)兩個(gè)數(shù)據(jù)對(duì)象的數(shù)據(jù)進(jìn)行比較完疫,以及將數(shù)據(jù)寫入到對(duì)應(yīng)的URL中。當(dāng)創(chuàng)建了對(duì)應(yīng)的對(duì)象之后债蓝,如果還有修改對(duì)象的需求壳鹤,那么就應(yīng)該使用可修改對(duì)象。在可修改對(duì)象中饰迹,開發(fā)者可以對(duì)數(shù)據(jù)進(jìn)行截?cái)喾际摹U(kuò)展、添加啊鸭,以及替換锹淌。

使用二進(jìn)制數(shù)據(jù)

本節(jié)包含NSData以及NSMutableData的相關(guān)代碼示例。因?yàn)镕oundation中的類簇機(jī)制赠制,數(shù)據(jù)對(duì)象并不是NSData或者NSMutableData的實(shí)例葛圃,而是某個(gè)對(duì)應(yīng)的私有子類的實(shí)例。盡管一個(gè)數(shù)據(jù)對(duì)象的類是私有的憎妙,但是接口是公開的,這些接口在父類NSData和NSMutableData中進(jìn)行了聲明曲楚。

基于原始字節(jié)創(chuàng)建數(shù)據(jù)對(duì)象

通常厘唾,開發(fā)者可以在NSData或者NSMutableData中通過那些以data...開頭的方法來基于原始字節(jié)創(chuàng)建數(shù)據(jù)對(duì)象。這些方法可以返回包含開發(fā)者指定原始字節(jié)的數(shù)據(jù)對(duì)象龙誊。
通常初始化方法(諸如dataWithBytes:length:)會(huì)對(duì)傳入的緩沖區(qū)字節(jié)進(jìn)行拷貝抚垃。在這種情況下,被拷貝的
字節(jié)擁有者就是數(shù)據(jù)對(duì)象趟大,由數(shù)據(jù)對(duì)象來負(fù)責(zé)對(duì)相關(guān)內(nèi)存的釋放鹤树。而原有緩沖字節(jié)的內(nèi)存釋放則由原有對(duì)象負(fù)責(zé)。
但是逊朽,如果開發(fā)者使用了帶有NoCopy相關(guān)字樣的初始化函數(shù)罕伯,那么對(duì)應(yīng)的緩沖字節(jié)就不會(huì)被拷貝。這種情況下的數(shù)據(jù)對(duì)象會(huì)持有通過參數(shù)傳入的緩沖字節(jié)叽讳,然后在對(duì)象釋放的時(shí)候追他, 緩沖字節(jié)對(duì)應(yīng)的內(nèi)存可會(huì)被釋放掉坟募。(NSMutableData同樣也有這些方法,但是緩沖字節(jié)會(huì)被拷貝邑狸,對(duì)應(yīng)的緩沖區(qū)可會(huì)被立刻釋放掉)懈糯。基于上述原因单雾,通過NoCopy方法傳入的數(shù)據(jù)必須是通過malloc創(chuàng)建的赚哗。
如果開發(fā)者傾向于不拷貝數(shù)據(jù)或者當(dāng)對(duì)象釋放的時(shí)候,緩存字節(jié)不被釋放硅堆,那么就可以使用dataWithBytesNoCopy:length:freeWhenDone:以及initWithBytsNoCopy:length:freeWhenDone屿储,然后通過對(duì)freeWhenDone:參數(shù)傳入NO來達(dá)到目的。

基于文件或者URL創(chuàng)建數(shù)據(jù)對(duì)象

開發(fā)者可以使用dataWithContentsOfFile:以及dataWithContentsOfURL:這兩個(gè)方法來創(chuàng)建數(shù)據(jù)對(duì)象硬萍。下面是實(shí)例代碼扩所,注意,路徑必須是絕對(duì)路徑朴乖。

NSString *thePath = @"/u/smith/myFile.txt";
NSData *myData = [NSData dataWithContentsOfFile:thePath];

訪問和比較緩沖字節(jié)

NSData中的兩個(gè)基礎(chǔ)方法bytes和length為這個(gè)類的其他方法提供了基礎(chǔ)操作祖屏。bytes方法返回一個(gè)指向緩沖字節(jié)數(shù)據(jù)的指針。length方法則返回了緩沖字節(jié)的長度买羞。
NSData提供了從數(shù)據(jù)對(duì)象中拷貝到指定緩沖區(qū)的數(shù)據(jù)訪問方法袁勺。getBytes:length:方法將字節(jié)拷貝到指定緩沖區(qū)去。比如說畜普,下面的代碼段就是初始化一個(gè)數(shù)據(jù)對(duì)象myData期丰,參數(shù)是myString,然后使用了getByts:length:方法來將myData的數(shù)據(jù)拷貝到aBuffer中吃挑。

unsigned char aBuffer[20];

NSString *myString = @"Test string.";

const char *utfString = [myString UTF8String];

NSData *myData = [NSData dataWithBytes: utfString length: strlen(utfString)];

[myData getBytes:aBuffer length:20];

getBytes:range:方法將指定范圍內(nèi)的字節(jié)進(jìn)行拷貝钝荡。
為了提取某個(gè)數(shù)據(jù)對(duì)象的字節(jié)數(shù)據(jù)子集,開發(fā)者可以使用subDataWithRange:方法舶衬。舉例來說埠通,下面的代碼段會(huì)初始化一個(gè)數(shù)據(jù)對(duì)象data2來包含data1的數(shù)據(jù)子集。

NSString *myString = @"ABCDEFG";

const char *utfString = [myString UTF8String];

NSRange range = {2, 4};

NSData *data1, *data2;

data1 = [NSData dataWithBytes:utfString length:strlen(utfString)];

data2 = [data1 subdataWithRange:range];

如果想要比較兩個(gè)數(shù)據(jù)對(duì)象是否相同逛犹,可以調(diào)用isEqualToData:方法端辱,這個(gè)方法提供逐個(gè)字節(jié)的比較。

拷貝數(shù)據(jù)對(duì)象

開發(fā)者可以以拷貝的方式來創(chuàng)建一個(gè)只讀的或者可修改的數(shù)據(jù)對(duì)象虽画。NSData和NSMutableData實(shí)現(xiàn)了NSCopying協(xié)議以及NSMutableCopying協(xié)議舞蔽,這就確保了可以在支隊(duì)對(duì)象和可修改對(duì)象之間進(jìn)行方便的轉(zhuǎn)換。開發(fā)者可以通過調(diào)用copy方法來創(chuàng)建只讀的拷貝码撰,也可以通過mutableCopy來創(chuàng)建可修改的拷貝渗柿。

存儲(chǔ)數(shù)據(jù)對(duì)象

開發(fā)者可以將字節(jié)數(shù)據(jù)存儲(chǔ)在本地文件或者互聯(lián)網(wǎng)中。writeToFile:atomically:方法以及writeToURL:atomically:方法可以讓開發(fā)者將字節(jié)數(shù)據(jù)保存在本地文件中脖岛。

使用可變二進(jìn)制數(shù)據(jù)

本節(jié)包含了一些和可變數(shù)據(jù)對(duì)象(也就是NSMutableData)有關(guān)的代碼示例做祝。開發(fā)者可以通過直接修改字節(jié)數(shù)組砾省、添加新數(shù)據(jù)以及替換指定范圍內(nèi)的數(shù)據(jù)這些方式來改變可修改數(shù)據(jù)對(duì)象。

修改字節(jié)

NSMutableData的兩個(gè)方法mutableBytes以及setLength:為本類的其他方法提供了基礎(chǔ)混槐。其中编兄,mutableBytes返回的是一個(gè)指向可修改字節(jié)數(shù)據(jù)的指針。而setLength:方法允許開發(fā)者對(duì)數(shù)據(jù)對(duì)象中的緩沖字節(jié)進(jìn)行范圍擴(kuò)展或者截?cái)嗌恰ncreaseLengthBy:方法同樣可以讓開發(fā)者改變可修改數(shù)據(jù)對(duì)象中的數(shù)據(jù)長度狠鸳。
在下面代碼段中,mutableBytes可以返回一個(gè)指向data2的指針悯嗓。然后使用data1的數(shù)據(jù)覆蓋data2的數(shù)據(jù)件舵。

代碼段1,修改字節(jié)

NSMutableData *data1, *data2;

NSString *myString = @"string for data1";

NSString *yourString = @"string for data2";

const char *utfMyString = [myString UTF8String];

const char *utfYourString = [yourString UTF8String];

unsigned char *firstBuffer, secondBuffer[20];

/* initialize data1, data2, and secondBuffer... */

data1 = [NSMutableData dataWithBytes:utfMyString length:strlen(utfMyString)+1];

data2 = [NSMutableData dataWithBytes:utfYourString length:strlen(utfYourString)+1];

[data2 getBytes:secondBuffer length:20];

NSLog(@"data2 before: \"%s\"\n", (char *)secondBuffer);

firstBuffer = [data2 mutableBytes];

[data1 getBytes:firstBuffer length:[data2 length]];

NSLog(@"data1: \"%s\"\n", (char *)firstBuffer);

[data2 getBytes:secondBuffer length:20];

NSLog(@"data2 after: \"%s\"\n", (char *)secondBuffer);

下面是代碼段1的輸出:

Oct 3 15:59:51 [1113] data2 before: "string for data2"

Oct 3 15:59:51 [1113] data1: "string for data1"

Oct 3 15:59:51 [1113] data2 after: "string for data1"

添加字節(jié)

appendBytes:length:方法以及appendData:方法可以讓開發(fā)者在可修改數(shù)據(jù)對(duì)象中進(jìn)行數(shù)據(jù)添加脯厨。比如說铅祸,代碼段2就是將data2中的數(shù)據(jù)拷貝到aBuffer中,然后將aBuffer中的數(shù)據(jù)添加到data1中

NSMutableData *data1, *data2;

NSString *firstString = @"ABCD";

NSString *secondString = @"EFGH";

const char *utfFirstString = [firstString UTF8String];

const char *utfSecondString = [secondString UTF8String];

unsigned char *aBuffer;

unsigned len;

data1 = [NSMutableData dataWithBytes:utfFirstString length:strlen(utfFirstString)];

data2 = [NSMutableData dataWithBytes:utfSecondString length:strlen(utfSecondString)];

len = [data2 length];

aBuffer = malloc(len);

[data2 getBytes:aBuffer length:[data2 length]];

[data1 appendBytes:aBuffer length:len];

程序的輸出為ASCII的字符數(shù)組“ABCDEFGH”

替換字節(jié)

開發(fā)者可以通過方法resetBytesInRange:或者使用replaceBytesInRange:withBytes方法來將可修改數(shù)據(jù)對(duì)象中的指定范圍的字節(jié)重置為0合武。在代碼段3中临梗,data1中的指定范圍的數(shù)據(jù)被data2中的數(shù)據(jù)替代了,然后data1中的數(shù)據(jù)就從”Liz and John”變成了”Liz and Larry”稼跳。

NSMutableData *data1, *data2;

NSString *myString = @"Liz and John";

NSString *yourString = @"Larry";

const char *utfMyString = [myString UTF8String];

const char *utfYourString = [yourString UTF8String];

unsigned len;

unsigned char *aBuffer;

NSRange range = {8, strlen(utfYourString)};

data1 = [NSMutableData dataWithBytes:utfMyString length:strlen(utfMyString)];

data2 = [NSMutableData dataWithBytes:utfYourString length:strlen(utfYourString)];

len = [data2 length];

aBuffer = malloc(len);

[data2 getBytes:aBuffer length:len];

[data1 replaceBytesInRange:range withBytes:aBuffer];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末盟庞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子汤善,更是在濱河造成了極大的恐慌什猖,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件红淡,死亡現(xiàn)場離奇詭異不狮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)在旱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門摇零,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人颈渊,你說我怎么就攤上這事≈辗穑” “怎么了俊嗽?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铃彰。 經(jīng)常有香客問我绍豁,道長,這世上最難降的妖魔是什么牙捉? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任竹揍,我火速辦了婚禮敬飒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘芬位。我一直安慰自己无拗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布昧碉。 她就那樣靜靜地躺著英染,像睡著了一般。 火紅的嫁衣襯著肌膚如雪被饿。 梳的紋絲不亂的頭發(fā)上四康,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音狭握,去河邊找鬼闪金。 笑死,一個(gè)胖子當(dāng)著我的面吹牛论颅,可吹牛的內(nèi)容都是我干的哎垦。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼嗅辣,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼撼泛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起澡谭,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤愿题,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蛙奖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體潘酗,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年雁仲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了仔夺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡攒砖,死狀恐怖缸兔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吹艇,我是刑警寧澤惰蜜,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站受神,受9級(jí)特大地震影響抛猖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一财著、第九天 我趴在偏房一處隱蔽的房頂上張望联四。 院中可真熱鬧,春花似錦撑教、人聲如沸朝墩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鱼辙。三九已至,卻和暖如春玫镐,著一層夾襖步出監(jiān)牢的瞬間倒戏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國打工恐似, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杜跷,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓矫夷,卻偏偏與公主長得像葛闷,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子双藕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容