Delphi中流的使用(比較全面)
Delphi 中流的使用(1) 用 TMemoryStream(記憶體流) 入門
前言:
所謂"流", 就是一段資料或是一塊記憶體;
在進行流操作時, 我們不必關心流中的資料到底是什麼; 只需要知道流的大小和當前的指標位置. 所以流只有兩個屬性:
Size、Position.
對流的操作, 不過就是讀取和寫入. 所以流最主要的方法就是 Read 和 Write.
在很多控制元件的使用中, 讀取主要用 LoadFromStream; 寫入主要用 SaveToStream.
舉個例子: (建立新工程, 新增兩個 Memo、兩個 Button)
unit Unit1; interface usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; Memo2: TMemo; Button1: TButton; Button2: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedureButton2Click(Sender: TObject); procedure FormDestroy(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} var mStream: TStream; {宣告一個流物件} procedure TForm1.FormCreate(Sender: TObject); begin mStream := TMemoryStream.Create; {TStream 是抽象類, 只能通過其子類例項化; 這裡我們用了記憶體流來生成例項}Memo1.Lines.Text := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; {給 Memo1 個初始值} end; procedure TForm1.Button1Click(Sender: TObject); begin Memo1.Lines.SaveToStream(mStream); {把 Memo1 中的內容寫入到流} ShowMessage(IntToStr(mStream.Size)); {26, 當前流的大小} ShowMessage(IntToStr(mStream.Position)); {26, 當前流的指標} end; procedure TForm1.Button2Click(Sender: TObject); begin mStream.Position := 4; {調整流的當前指標位置} Memo2.Lines.LoadFromStream(mStream); {讀出流中的內容到 Memo2} { 現在 Memo2 中的內容應該是: EFGHIJKLMNOPQRSTUVWXYZ 如果 Position 是 0, Memo2 讀出的內容會是: ABCDEFGHIJKLMNOPQRSTUVWXYZ 如果 Position 等於 Size, 在這裡如果是 26, Memo2 就讀不出什麼了. } end; procedure TForm1.FormDestroy(Sender: TObject); begin mStream.Free; {流釋放時, 所用記憶體當然也會同時釋放} end; end.
用TFileStream(檔案流進行讀寫)
TStream 是一個抽象的基類, 不能直接生成物件. 在具體的應用中, 主要使用它的子孫類:
TFileStream: 檔案流
TStringStream: 字串流
TMemoryStream: 記憶體流
TResourceStream: 資原始檔流
THandleStream: 是 TFileStream 的父類、TStream 的子類
TCustomMemoryStream: 是 TMemoryStream 和 TResourceStream 的父類、TStream 的子類
與流相關的常用類還有: TReader、TWriter、TCompressionStream、TDecompressionStream
來一個檔案流的例子:
procedure TForm1.Button1Click(Sender: TObject); var getStream,setStream: TFileStream; {宣告一個檔案流} getPath,setPath: string; begin getPath := 'c:/temp/get.jpg'; {需要這個檔案存在} setPath := 'c:/temp/set.jpg'; {這個會自動建立} if not FileExists(getPath) then begin ShowMessage('找不到我們要測試的圖片檔案: ' + getPath); Exit; end; getStream := TFileStream.Create(getPath, fmOpenRead or fmShareExclusive); setStream := TFileStream.Create(setPath, fmCreate); {建立檔案流需要兩個引數: 引數 1 是路徑, 引數 2 是開啟模式} getStream.Position := 0; {流指標移到開始, 複製時從這裡開始} setStream.CopyFrom(getStream, getStream.Size); {Copy 流} {CopyFrom 的引數 2 是要複製的內容大小; 如果為 0 , 不管指標在什麼位置都會複製所有內容} {CopyFrom 返回實際拷貝的位元組數} {這時硬碟上就有 set.jpg 檔案, 與 get.jpg 一麼一樣} {其實就是複製檔案, 不過這裡我們是用檔案流實現的} getStream.Free; setStream.Free; end;TFileStream 開啟模式與共享模式:
分類 | 引數 | 說明 |
---|---|---|
打 開 模 式 |
fmCreate | 建立檔案, 如果存在則開啟它。 |
fmOpenRead | 只讀開啟 | |
fmOpenWrite | 只寫開啟 | |
fmOpenReadWrite | 讀寫開啟 | |
共 享 模 式 |
fmShareCompat | 共享模式, 相容 Dos |
fmShareExclusive | 不允許別人以任何方式開啟 | |
fmShareDenyWrite | 允許別人以只寫方式開啟 | |
fmShareDenyRead | 允許別人以只讀方式開啟 | |
fmShareDenyNone | 允許別人以任何方式開啟 |
通過記憶體流讀取檔案
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; Button2: TButton; Button3: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} var mStream: TMemoryStream; procedure TForm1.FormCreate(Sender: TObject); //程式開始先建立一個準備要測試的檔案 var strList: TStringList; begin strList := TStringList.Create; strList.Add('aaaaaaaa'); strList.Add('bbbbbbbb'); strList.Add('cccccccc'); strList.Add('dddddddd'); strList.SaveToFile('c:/temp/test.txt'); strList.Free; {同時建立記憶體流} mStream := TMemoryStream.Create; end; procedure TForm1.Button1Click(Sender: TObject); //通過流讀檔案到 Memo begin mStream.LoadFromFile('c:/temp/test.txt'); {把檔案讀入記憶體流} Memo1.Lines.LoadFromStream(mStream); {把記憶體流載入 Memo1} end; procedure TForm1.Button2Click(Sender: TObject); //用字元指標讀取流中的內容 var pc: PChar; begin pc := mStream.Memory; {把字元指標指向記憶體流} ShowMessage(pc[0]); {a; 第一個字元} ShowMessage(pc[10]); {b; 這個第二行的第一個字元; 每行8個字再加換行與回車共10個字元} ShowMessage(pc[20]); {c} ShowMessage(pc[30]); {d} end; procedure TForm1.Button3Click(Sender: TObject); //從流讀入到緩衝區 var buffer: array[0..2] of Char; {定義個字元緩衝區} begin mStream.Seek(0, soFromBeginning); mStream.Read(buffer, SizeOf(buffer)); ShowMessage(buffer); {aaa} mStream.Seek(10, soFromBeginning); mStream.Read(buffer, SizeOf(buffer)); ShowMessage(buffer); {bbb} mStream.Seek(20, soFromBeginning); mStream.Read(buffer, SizeOf(buffer)); ShowMessage(buffer); {ccc} mStream.Seek(30, soFromBeginning); mStream.Read(buffer, SizeOf(buffer)); ShowMessage(buffer); {ddd} {關於 Seek 函式: 引數1: Offset 是偏移量; 引數2: Origin 是指標的基準位置, 有三個選值: soFromBeginning、soFromCurrent、soFromEnd soFromBeginning: 以開始為基準, 此時引數 Offset 要 >= 0; soFromCurrent: 以當前位置為基準; soFromEnd: 以結束為基準; 此時引數 Offset 要 <= 0; 返回: 指標新位置 } end; procedure TForm1.FormDestroy(Sender: TObject); begin mStream.Free; end; end.
遍歷讀取流中的所有資料
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; Memo2: TMemo; {需要新增兩個 Memo 用於顯示} Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} //先製造一個測試檔案 procedure TForm1.FormCreate(Sender: TObject); var strList: TStringList; begin strList := TStringList.Create; strList.Add('ABCDEFGHIJKLMNOPQRSTUVWXYZ'); strList.SaveToFile('c:/temp/test.txt'); strList.Free; end; procedure TForm1.Button1Click(Sender: TObject); var ms: TMemoryStream; c: Char; s1,s2: string; begin ms := TMemoryStream.Create; ms.LoadFromFile('c:/temp/test.txt'); {讀入記憶體流} s1 := ''; s2 := ''; ms.Position := 0; {指標到開始} while ms.Position < ms.Size do {迴圈讀出} begin ms.Read(c,1); {每讀出一個位元組, 指標會自動移到新的位置} s1 := s1 + c + ' '; {用文字記錄} s2 := s2 + IntToHex(Byte(c),2) + ' '; {用兩位數的十六進位制記錄} end; Memo1.Lines.Text := s1; Memo2.Lines.Text := s2; {Memo1 會顯示: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z } {Memo2 會顯示: 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 0D 0A} ms.Free; end; end.
元件序列化
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} //新增一個 Memo1 然後修改其內容 procedure TForm1.Button1Click(Sender: TObject); begin WriteComponentResFile('c:/temp/memo.dat', Memo1); {只此一句就可以把當前的 Memo 的狀態序列化到檔案} end; //反序列化, 讀回 procedure TForm1.Button2Click(Sender: TObject); begin ReadComponentResFile('c:/temp/memo.dat', Memo1); {一句話就可以讀回, 不管是經過了什麼操作(甚至是關機)} end; { 這好像和流沒什麼關係, 其實這就是流的典型操作, WriteComponentResFile 和 ReadComponentResFile 分別呼叫了流類的 WriteComponentRes 與 ReadComponentRes 方法. 下面用更直接的流的方式重新實現一次: } //序列化 procedure TForm1.Button3Click(Sender: TObject); var stream: TStream; const strPath = 'c:/temp/m.dat'; begin stream := TFileStream.Create(strPath, fmCreate); stream.WriteComponentRes(Memo1.ClassName, Memo1); {WriteComponentRes 有兩個引數: 檔名和元件名} stream.Free; end; //反序列化 procedure TForm1.Button4Click(Sender: TObject); var stream: TStream; const strPath = 'c:/temp/m.dat'; begin stream := TFileStream.Create(strPath, fmOpenRead); stream.ReadComponentRes(Memo1); {ReadComponentRes 只有一個引數: 元件名} stream.Free; end; end.
用流讀寫結構化檔案
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; {新增 Memo 顯示內容} Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} type TRec = record {定義一個記錄} name: string[8]; age: Word; end; //寫入 procedure TForm1.Button1Click(Sender: TObject); var rec: TRec; ms: TMemoryStream; begin ms := TMemoryStream.Create; rec.name := '張三'; rec.age := 8; ms.Write(rec, SizeOf(rec)); rec.name := '李四'; rec.age := 81; ms.Write(rec, SizeOf(rec)); rec.name := '王二麻子'; rec.age := 18; ms.Write(rec, SizeOf(rec)); ms.SaveToFile('c:/temp/rec.dat'); ms.Free; end; //讀取 procedure TForm1.Button2Click(Sender: TObject); var rec: TRec; ms: TMemoryStream; begin ms := TMemoryStream.Create; ms.LoadFromFile('c:/temp/rec.dat'); Memo1.Clear; ms.Position := 0; while ms.Position < ms.Size do begin ms.Read(rec, SizeOf(rec)); Memo1.Lines.Add(rec.name + ' ' + IntToStr(rec.age)); end; {Memo1 的顯示結果會是: 張三 8 李四 81 王二麻子 18 } ms.Free; end; end.
壓縮與解壓
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} uses Zlib; {壓縮流 TCompressionStream 與解壓縮流 TDecompressionStream 來自 Zlib 單元} //壓縮 procedure TForm1.Button1Click(Sender: TObject); var cs: TCompressionStream; {定義壓縮流} fs,ms: TMemoryStream; {fs 是要壓縮的流; ms 是接收壓縮後文件的流} num: Integer; {原始檔案大小} begin {第一步: 調入要壓縮的檔案, 並獲取大小} fs := TMemoryStream.Create; fs.LoadFromFile('c:/temp/test.txt'); {檔案要存在啊} num := fs.Size; {第二步: 建立接收的流, 並先寫入原始檔案大小} ms := TMemoryStream.Create; ms.Write(num, SizeOf(num)); {第三步: 壓縮} cs := TCompressionStream.Create(clMax, ms); {引數1是壓縮比; 引數2是接收流} fs.SaveToStream(cs); {傳入要壓縮的資料} cs.Free; {壓縮流 Free 後才真正完成壓縮, 所以提前 Free} {第四步: 儲存} ms.SaveToFile('c:/temp/test.zipx'); {第五步: 釋放} ms.Free; fs.Free; {壓縮比引數: clNone 無壓縮 clFastest 快速 clDefault 預設 clMax 最大比例 } end; //解壓縮 procedure TForm1.Button2Click(Sender: TObject); var ds: TDecompressionStream; {解壓流} fs,ms: TMemoryStream; {fs 是準備要解壓的流; ms 是接受解壓資料的流} num: Integer; {接受檔案壓縮前的大小} begin {第一步: 準要解壓的檔案} fs := TMemoryStream.Create; fs.LoadFromFile('c:/temp/test.zipx'); {必須是上一個壓縮方法生成的檔案} {第二步: 讀出檔案壓縮前的大小} fs.Position := 0; fs.ReadBuffer(num,SizeOf(num)); {第三步: 準備好要接收的流, 並設定需要的大小} ms := TMemoryStream.Create; ms.SetSize(num); {第四步: 解壓} ds := TDecompressionStream.Create(fs); {引數是要解壓的流} {第五步: 把解壓後的資料讀出存放到已準備好接收的流} ds.Read(ms.Memory^, num); {第六步: 儲存} ms.SaveToFile('c:/temp/test2.txt'); ds.Free; ms.Free; fs.Free; end; end.
壓縮與解壓縮的函式
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} uses Zlib; //壓縮函式 procedure Zip(var fs: TMemoryStream); var cs: TCompressionStream; ms: TMemoryStream; num: Integer; begin if not(Assigned(fs) and (fs.Size>0)) then Exit; num := fs.Size; ms := TMemoryStream.Create; cs := TCompressionStream.Create(clMax, ms); try fs.SaveToStream(cs); cs.Free; //ms.Position := 0; fs.Clear; fs.WriteBuffer(num, sizeof(num)); fs.CopyFrom(ms, 0); finally ms.Free; end; end; //解壓函式 procedure UnZip(var fs: Tmemorystream); var ds: TDecompressionStream; ms: TMemoryStream; num: Integer; begin if not(Assigned(fs) and (fs.Size>0)) then Exit; fs.Position := 0; fs.ReadBuffer(num,sizeof(num)); ms := TMemoryStream.Create; ds := TDecompressionStream.Create(fs); try ms.SetSize(num); ds.Read(ms.Memory^, num); //ms.Position := 0; fs.Clear; fs.CopyFrom(ms, 0); finally ds.Free; ms.Free; end; end; //壓縮測試 procedure TForm1.Button1Click(Sender: TObject); var ms: TMemoryStream; begin ms := TMemoryStream.Create; ms.LoadFromFile('c:/temp/test.txt'); Zip(ms); ms.SaveToFile('c:/temp/test.zipx'); end; //解壓測試 procedure TForm1.Button2Click(Sender: TObject); var ms: TMemoryStream; begin ms := TMemoryStream.Create; ms.LoadFromFile('c:/temp/test.zipx'); UnZip(ms); ms.SaveToFile('c:/temp/test2.txt'); end; end.
分割與合併檔案的函式
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} //分割檔案的函式 {引數 1 是要分割的檔名; 引數 2 是要風格檔案的大小, 單位是 KB} {分割後的檔名副檔名用序號替換} function SplitFile(const FileName: string; Size: Cardinal): Boolean; var fStream: TFileStream; {原始檔案} toStream: TMemoryStream; {分檔案} p,i: Integer; {p 記錄當前指標位置; i 記錄這是第幾個分的檔案} begin Result := False; Size := Size * 1024; {把大小的單位轉換為位元組} fStream := TFileStream.Create(FileName, fmOpenRead); p := 0; i := 0; toStream := TMemoryStream.Create; while p < fStream.Size do begin toStream.Clear; {清空上次資料} fStream.Position := p; {放好指標位置} if fStream.Size-p < Size then Size := fStream.Size-p; {最後一個時, 有多少算多少} toStream.CopyFrom(fStream, Size); {複製} toStream.SaveToFile(FileName + '.' + IntToStr(i)); {儲存} Inc(i); p := p + Size; end; fStream.Free; toStream.Free; Result := True; end; //合併檔案, 引數是其中一個分檔名 function MergeFile(const FileName: string): Boolean; var ms: TMemoryStream; {讀取分檔案} fs: TFileStream; {合併後的檔案} path: string; i: Integer; begin path := ChangeFileExt(FileName,''); {去掉序號副檔名} ShowMessage(path); i := 0; ms := TMemoryStream.Create; fs := TFileStream.Create(path, fmCreate); while FileExists(path + '.' + IntToStr(i)) do begin ms.LoadFromFile(path + '.' + IntToStr(i)); fs.CopyFrom(ms, 0); {TFileStream 不需要 SetSize; 但如果用 TMemoryStream 就需要} Inc(i); end; ms.Free; fs.Free; end; //測試分割 procedure TForm1.Button1Click(Sender: TObject); begin SplitFile('c:/temp/test.txt', 10); end; //測試合併 procedure TForm1.Button2Click(Sender: TObject); begin MergeFile('c:/temp/test.txt.0'); end; end.
壓縮與解壓縮排度
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; ProgressBar1: TProgressBar; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure CsProgress(Sender: TObject); {壓縮的 OnProgress 事件} procedure DsProgress(Sender: TObject); {解壓縮的 OnProgress 事件} end; var Form1: TForm1; implementation {$R *.dfm} uses Zlib; {壓縮的 OnProgress 事件} procedure TForm1.CsProgress(Sender: TObject); begin ProgressBar1.Position := Integer(TCompressionStream(Sender).Position div 1024); Application.ProcessMessages; end; {解壓縮的 OnProgress 事件} procedure TForm1.DsProgress(Sender: TObject); begin ProgressBar1.Position := Integer(TDecompressionStream(Sender).Position div 1024); Application.ProcessMessages; end; {壓縮} procedure TForm1.Button1Click(Sender: TObject); var cs: TCompressionStream; fs,ms: TMemoryStream; num: Integer; begin fs := TMemoryStream.Create; fs.LoadFromFile('c:/temp/test.txt'); {我是用一個 15M 的文字檔案測試的} num := fs相關推薦
Delphi中流的使用(比較全面)
Delphi 中流的使用(1) 用 TMemoryStream(記憶體流) 入門 前言:所謂"流", 就是一段資料或是一塊記憶體;在進行流操作時, 我們不必關心流中的資料到底是什麼; 只需要知道流的大小和當前的指標位置. 所以流只有兩個屬性: Size、Position.
ACM 演算法 階段性練習 (比較全面)
初期: 一.基本演算法: (1)列舉. (poj1753,poj2965) (2)貪心(poj1328,poj2109,poj2586) (3)遞迴和分治法. (4)遞推. (5)構造法.(poj3295) (6)模擬法.(poj1068,poj2632,poj1573,poj2993,poj2
程序與執行緒總結(比較全面)
1.程序和執行緒 1.1 概述: 程序是具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程序是系統進行資源分配和排程的一個獨立單位. 執行緒是程序的一個實體,是CPU排程和分派的基本單位,它是比程序更小的能獨立執行的基本單位.執行緒自己基本上不擁有系統資源,只擁有一點在執行中必不
SIP協議簡介(比較全面)
介紹 通訊提供商及其合作伙伴和使用者越來越渴求新一代基於 IP 的服務。現在有了 SIP協議(會話啟動協議),一解燃眉之急。SIP協議 是不到十年前在電腦科學實驗室誕生的一個想法。它是第一個適合各種媒體內容而實現多使用者會話的協議,現在已成了 Internet 工程任
delphi文件操作(比較全)
寫入 con sender 類型 close 文本 版本信息 讀取 關於 Delphi中默認有input和output兩個文件變量,使用可以不用定義,直接使用. 但: input:只讀、output:只寫。用時註意以免引起異常. 文件是由文件名標識的一組數據的集合,文件
java的網路程式設計(概括比較全面)
對java網路程式設計Socket(套接字)介面的使用做詳細的介紹和使用。 原文連結 一.網路程式設計中兩個主要的問題 一個是如何準確的定位網路上一臺或多臺主機,另一個就是找到主機後如何可靠高效的進行資料傳輸。 在TCP/IP協議中IP層主要負責網路主機的定位,資料
maven專案構建(比較全面的操作流程)
在構建一個maven專案的時候首先你需要你需要檢查以下幾個方面的資訊是否配置好首先你需要有一個eclipse或者是myeclipse,然後將一個svn配置到你的環境中(配置的步驟很簡單一般就是直接把下載的svn的檔案直接放到環境當中,也就是eclipse中的目錄下,網上有好多
LoadRunner學習---腳本編寫(4)(比較重要)
用戶 變量 php roots 正則 ase src bar 分析 LoadRunner學習---腳本編寫(4)(比較重要) 今天接著來翻譯http://www.wilsonmar.com/中關於LoadRunner腳本編寫部分,下面該翻譯腳本編寫中一些比較重要
require的路徑問題(比較重要)
比較 收錄 設置 例如 term 方法 gis base 加載文件 dojo.baseUrl baseUrl用來存儲dojo.js存放 的跟目錄,例如dojo.js的路徑是“/web/scripts/dojo-1.3/dojo/dojo.js”則baseUrl為“/web
zookeeper的選舉機制(比較清晰)
一、前言 前面學習了Zookeeper服務端的相關細節,其中對於叢集啟動而言,很重要的一部分就是Leader選舉,接著就開始深入學習Leader選舉。 二、Leader選舉 2.1 Leader選舉概述 Leader選舉是保證分散式資料一致性的關鍵所在。當Zookeepe
Java 多執行緒面試題及答案(非常全面)
這篇文章主要是對多執行緒的問題進行總結的,因此羅列了40個多執行緒的問題。 這些多執行緒的問題,有些來源於各大網站、有些來源於自己的思考。可能有些問題網上有、可能有些問題對應的答案也有、也可能有些各位網友也都看過,但是本文寫作的重心就是所有的問題都會按照自己的理解回答一遍,不會去看網上的
Linux下nf_conntrack(最全面)
總結如下: dmesg |grep nf_conntrack 連線跟蹤表nf_conntrack:如果輸出值中有“nf_conntrack: table full, dropping packet”,說明伺服器nf_conntrack表已經被打滿 如果伺服器
少說話多寫程式碼之Python學習026——條件語句03(比較運算子)
條件語句中基本的運算子就是比較運算子。常用的運算子如下: ==, <, >, <=, >=, !=, is , is not, in, not in。 具體用法如下, x=1 y=1 if x==y : print('x等於y'
百度面試總結:spark比MapReduce快的原因是什麼?(比較完整)
1、spark是基於記憶體進行資料處理的,MapReduce是基於磁碟進行資料處理的 MapReduce的設設計:中間結果儲存在檔案中,提高了可靠性,減少了記憶體佔用。但是犧牲了效能。 Spark的設計:資料在記憶體中進行交換,要快一些,但是記憶體這個東西,可靠性不如磁碟。所以效能方面比MapR
Spring事務傳播機制(比較詳細)
文章一: 我們都知道事務的概念,那麼事務的傳播特性是什麼呢?(此處著重介紹傳播特性的概念,關於傳播特性的相關配置就不介紹了,可以檢視spring的官方文件) 在我們用SSH開發專案的時候,我們一般都是將事務設定在Service層 那麼當我們呼叫Service層的一個方法的時候它能夠保
資料整理——Oracle版本歷史(很全面)(Releases and versions of Oracle Database)
資料來源: https://en.wikipedia.org/wiki/Oracle_Database Oracle Database Version Initial Release Version Initial Release Date
gitlab-ci實現前端自動化部署(步驟全面)
近些年前端發展迅速,前後分離已經是一個大趨勢。隨著前端專案的愈加龐大,其自動化也極其重要的一環。不僅僅是通過webpack實現的自動化構建,當專案提交的時候,同時也要實現其自動化的部署、釋出工作。 接下來我就講一講通過gitlab-ci實現前端自動化部署的各個
JS中不同型別作比較的規律 (比較運算子)
JS 不同資料型別的比較 是個頭疼事情,那有沒有規律可循,讓記憶和理解起來更加容易呢, console.log(1 == "1") //true 好的,我先把規則告訴大家,然後大家理解後再開始練習。看看效果是不是很顯著; 不同資料型別間的比較,規
spark比MapReduce快的原因是什麼?(比較完整)
1、spark是基於記憶體進行資料處理的,MapReduce是基於磁碟進行資料處理的 MapReduce的設設計:中間結果儲存在檔案中,提高了可靠性,減少了記憶體佔用。但是犧牲了效能。 Spark的設計:資料在記憶體中進行交換,要快一些,但是記憶體這個東西,可靠性不如磁碟。所以效能方面比Ma
TreeSet ------自然排序與定製排序(比較器)
前言:TreeSet集合是Set集合的一個子實現類,它是基於TreeMap中的NavigableSet介面實現的,TreeSet集合是預設通過自然排序將集合中的元素進行排序 TreeSet有兩種排序方式: 1)自然排序 2)比較器排序 1. 自然排序: 在TreeSe