QByteArray用來存儲元字節(包含'\0')和傳統的以'\0'結尾的8位字符串。QByteArray比直接用const char*好得多。QByteArray在後臺,能確保數據之後始終跟隨着'\0'終止符,並用隱式共享(copy-
on-write)減少內存使用和避免不必要的數據拷貝。
此外,QByteArray可供QString存儲字符串數據。通常,你多用QString。QString存儲的是Unicode(16bit)字符,你可在應中,自由地存儲非ASCII和非-Latin-1字符。並且,QString貫穿於整個Qt API。若
你需存儲原始二進制數據或系統(例:嵌入式linux版Qt)內存保護高,QByteArray更合適。
給構造函數傳一個const char*即可初始化QByteArray。
例如:以下代碼創建了1個大小爲5的字節數組,內含數據"Hello":
QByteArray ba("Hello");
QByteArray在字節數組尾自動添加了'\0'終止符,size()返回值是5。
當外部請求原始數據時,QByteArray返回一個以'\0'終止符結尾底層數據指針。
使用const char*初始化,QByteArray將做深拷貝,因此你可隨意編輯它,無需擔心會引起任何其他影響。(如你想提高性能,不想要深拷貝,用QByteArray::fromRawData())。
初始化QByteArray的另一個方法是,先用resize()設置數組大小,之後再一個一個地初始化每個字節。與C++索引一樣,QByteArr位y使用0基索引,用運算符[]指定索引,可訪問對應數據。對非常量字節數
組non-const byte array,operator[]()能返回一個可用在等式左邊的字節引用,如下所示:
QByteArray ba;
ba.resize(5);
ba[0] = 0x3c;
ba[1] = 0xb8;
ba[2] = 0x64;
ba[3] = 0x18;
ba[4] = 0xca;
僅是隻讀訪問,用at()代替[]:
for (int i = 0; i < ba.size(); ++i) {
if (ba.at(i) >= 'a' && ba.at(i) <= 'f')
cout << "找出[a-f]" << endl;
}
at()不做深拷貝,比運算符[]()運行更快。
若需一次提取多個字節,用left()、right()、或mid()。
QbyteArray能存放'\0'。對於內存'\0'的QByteArray,size()返回值爲數組整體長度,包含已存'\0',但不包含被QByteArray自動添加'\0'終止符。
QByteArray ba1("ca\0r\0t");
ba1.size(); // Returns 2.
ba1.constData(); // Returns "ca" with terminating \0.
QByteArray ba2("ca\0r\0t", 3);
ba2.size(); // Returns 3.
ba2.constData(); // Returns "ca\0" with terminating \0.
QByteArray ba3("ca\0r\0t", 4);
ba3.size(); // Returns 4.
ba3.constData(); // Returns "ca\0r" with terminating \0.
const char cart[] = {'c', 'a', '\0', 'r', '\0', 't'};
QByteArray ba4(QByteArray::fromRawData(cart, 6));
ba4.size(); // Returns 6.
ba4.constData(); // Returns "ca\0r\0t" without terminating \0.
如果你想知道字節數組中第一個'\0'前有幾個字符,用qstrlen()。
resize()調用後,新申請的內存爲初始化,內含未定義值。用fill()將所有字節初始化爲指定值。
data()或constData()都能返回一個指向原始字節數組頭的指針。只要不調用non-const函數,該指針將一直有效。除了由原始數據(raw data)創建QByteArray外,QByteArray確保該指針指向的字節數組末
尾有'\0'終止符。由QByteArray自動添加的'\0'不計入size())。
QByteArray用於編輯字節字節數據的函數有:append(),prepend(),insert(),replace(),remove()。例如:
QByteArray x("and");
x.prepend("rock "); // x == "rock and"
x.append(" roll"); // x == "rock and roll"
x.replace(5, 3, "&"); // x == "rock & roll"
replace()和remove()前兩個參數分別是擦寫起始位置和擦寫字節數量。
當向非空non-empty數組append()數據時,array將重新分配內存,並將新數據拷貝給他。若你要規避該類操作,可用reserve。reserve能預分配指定長度的內存。用capacity能查明QByteArray實際被分配
了多少內存。若將數據添加到空字節數組,不會發生拷貝。
從字節數組中刪除空白字符('\n','\t'等)是一個高頻需求。若你要刪除QByteArray兩端的空白字符,使用trimmed()。若你不僅要刪除QByteArray兩端的空白字符,並想將QByteArray內的多個連續空白
字符替換爲一個簡單的空白字符,用simplified()。
若你想從QByteArray中找出所有的特定字符或子字符串,使用indexOf()或lastIndexOf()。former從指定索引位置向前搜索,latter向後搜索,發現指定字符或子字符串返回對應索引,其他情況,都返
回-1。例如:以下是一個典型的循環去尋找所有特定子串。
QByteArray ba("We must be <b>bold</b>, very <b>bold</b>");
int j = 0;
while ((j = ba.indexOf("<b>", j)) != -1) {
cout << "Found <b> tag at index position " << j << endl;
++j;
}
若你僅想知道,QByteArray是否含有特定字符或子符串,用contains()。若你想找出在字節數組中,特定字符或子符串有多少個,用count()。如果你想用另一個內容替代所有的特定字符或子符串,用
replace()
QByteArrays可用重載的操作符進行比較,例如<(), <=(), ==(), >=()等。比較基於字節數組內字符的數值,速度非常快,但這不是大家想要的。QString::localeAwareCompare()是一個用戶自定義比較接
口,更好用。
歷史原因,對單null字節數組和空字節數組,QByteArray是區別待遇的。
單null字節數組由QByteArray的默認構造函數或給構造函數傳(const char*)0產生的。
空字節數組size()返回值爲0的任何字節數組。
單null字節數組肯定是空字節數組,但是空字節數組不一定是單null字節數組。
QByteArray().isNull(); // returns true
QByteArray().isEmpty(); // returns true
QByteArray("").isNull(); // returns false
QByteArray("").isEmpty(); // returns true
QByteArray("abc").isNull(); // returns false
QByteArray("abc").isEmpty(); // returns false
除了isNull(),所有函數都認爲單null字節數組爲空字節數組。例如:對只含一個'\0'的字節數組,data()可返回一個有效的指針,與QByteArray("")比較,是相等的。所有,我們建議你儘管避免使用
isNull(),始終用isEmpty()。
最大尺寸和內存不足條件
當前版本的QByteArray大小限制在2GB(2^31 Byte)下。爲滿足數據塊管理需求,該值是architecture-dependent。
原數據塊在本版本中,限制在2GB,最小1字節。
若內存分配失敗,QByteArray將拋出std::bad_alloc異常。Qt容器中,只有不滿足內存條件,纔會拋出異常。
注意:操作系統會對申請大內存的應用施加更多的限制,特別是大的、連續的數據塊。操作系統對大內存的關注,該類操作的配置以及超出了QByteArray API範圍了。
注意:
數字字符串轉換
數字與字符串之間的轉換操作基於本地C,與用戶的本地設置無關。使用QString執行數字與字符串操作,使用本地轉換,
8-bit字符比較
在QByteArray中,字符基於Latin-1。如果兩方字符串只含有Latin-1字符,大小寫區分、比較纔是準確的。contain(),indexOf(),lastIndexof(),<(),<=(),>(),>=(),siLower(),isUpper(),toLower()和
toUpper()都受此影響。
本問題不適用於QString相關,因爲他們使用Unicode表示字符。