文件遷移到FileTable中

来源:https://www.cnblogs.com/adsoft/archive/2019/12/17/12055976.html
-Advertisement-
Play Games

看此文檔前,先參考一下文檔 https://blog.csdn.net/downmoon/article/details/24374609 環境:阿裡雲ECS SQL Server 2017 + Delphi7 測試用xcopy,robocopy等命令遷移文件好像不太會用。有感興趣的朋友,告知一下。 ...


看此文檔前,先參考一下文檔 https://blog.csdn.net/downmoon/article/details/24374609

環境:阿裡雲ECS SQL Server 2017 + Delphi7

測試用xcopy,robocopy等命令遷移文件好像不太會用。

倒是可以通過T-SQL的方法,但是需要文件在伺服器上面,這就有點難受了。如下:

--我們使用該函數插入一個圖片文件到該目錄下:這裡的路徑需要是伺服器上的路徑。
declare @image1 varbinary(max), @path_locator hierarchyid;
select @image1=cast(bulkcolumn as varbinary(max)) from openrowset(bulk N'C:\1.png', single_blob) as x;
select @path_locator=path_locator from DocumentStores where [name]='MyDir1';
insert into DocumentStores(name, file_stream, path_locator) 
       values('1.png', @image1, dbo.fnGetNewPathLocator(newid(), @path_locator));

--如果你想使用SQL Server本身提供的hierarchyid層次結構,下麵這個函數也許可以幫你:
create FUNCTION fnGetNewPathLocator
        (@child uniqueidentifier, 
         @parent hierarchyid)
returns hierarchyid
as 
begin
  declare @ret hierarchyid, @binid Binary(16) = convert(binary(16), @child);
  select @ret=hierarchyid::Parse(
            COALESCE(@parent.ToString(), N'/') +
            CONVERT(nvarchar, CONVERT(bigint, SUBSTRING(@binId, 1, 6))) + N'.' +
            CONVERT(nvarchar, CONVERT(bigint, SUBSTRING(@binId, 7, 6))) + N'.' +
            CONVERT(nvarchar, CONVERT(bigint, SUBSTRING(@binId, 13, 4))) + N'/');
  return @ret;
end;

通過程式也能實現,只是如果層級太深,生成的path_locator太長,總感覺不太靠譜。

下麵是用Delphi實現的,Insert操作(本地E:\Doc目錄下所有文件遷移到FileTable)。

procedure TForm1.BitBtn9Click(Sender: TObject);
var
  lst, lstContent: TStrings;
  I: Integer;
  strSQL: string;
begin
  lst := TStringList.Create;
  lstContent := TStringList.Create;
  try
    GetFileStructureList('E:\Doc', lst);
    strSQL := EmptyStr;
    rzprogressbar1.TotalParts := lst.Count;
    for I:=0 to lst.Count-1 do
    begin
      SplitString(lst.Strings[I], '|', lstContent);
      if SameText(lstContent.Strings[0], '0') then      //目錄
        strSQL := strSQL + Format('Insert into DocumentStores(name, path_locator, is_directory, is_archive) values(%S, %S, %D, %D);',
                                   [QuotedStr(ExtractFileName(lstContent.Strings[1])), QuotedStr(lstContent.Strings[2]), 1, 0]) + #13#10
      else if SameText(lstContent.Strings[0], '1') then //文件
        strSQL := strSQL + Format('Insert into DocumentStores(name, path_locator, file_stream) values(%S, %S, %S);',
                                   [QuotedStr(ExtractFileName(lstContent.Strings[1])), QuotedStr(lstContent.Strings[2]),
                                    StrToHex(BaseEncodeFile(lstContent.Strings[1]))]) + #13#10;
      rzprogressbar1.PartsComplete := rzprogressbar1.PartsComplete + 1;
      Application.ProcessMessages;
    end;
    try
      ADOConnection1.Connected := True;
      ADOConnection1.BeginTrans;
      ADOQuery1.SQL.Text := strSQL;
      ADOQuery1.ExecSQL;
      ADOConnection1.CommitTrans;
    except
      ADOConnection1.RollbackTrans;
    end;
  finally
    lst.Free;
    lstContent.Free;
  end;
end;

//下麵是公用單元
unit U_Commfunc;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, EncdDecd, Contnrs;

  //生成filetable用的path_locator
  function GetPathLocator(root: Boolean=True): string;
  function GetGUID: string;
  function StrToHex(AStr: string): string;
  //文件轉字元串流
  function BaseEncodeFile(fn: TFileName): string;
  procedure SplitString(Source,Deli:string; var lst :TStrings);
  //獲取目錄+文件的列表 返回值是文件的個數,頂層為選擇的目錄 為filetalbe插入用
  function GetFileStructureList(Path: PChar; var lst: TStrings): LongInt;

implementation


function GetGUID: string;
var
  LTep: TGUID;
  sGUID: string;
begin
  CreateGUID(LTep);
  sGUID := GUIDToString(LTep);
  sGUID := StringReplace(sGUID, '-', '', [rfReplaceAll]);
  sGUID := Copy(sGUID, 2, Length(sGUID) - 2);
  Result := sGUID;
end;

function GetPathLocator(root: Boolean): string;
var
  //LocatorPath的三個組成部分 S1,S2,S3;
  sGuid, S1, S2, S3: string;
begin
  Result := '';
  if root then
    Result := '/';
  sGuid := GetGUID;
  S1 := IntToStr(StrToInt64(StrToHex(Copy(sGuid, 1, 6))));
  S2 := IntToStr(StrToInt64(StrToHex(Copy(sGuid, 7, 6))));
  S3 := IntToStr(StrToInt64(StrToHex(Copy(sGuid, 13, 4))));
  Result := Result + S1 + '.' + S2 + '.' + S3 + '/';
end;

function StrToHex(AStr: string): string;
var
  i : Integer;
  ch:char;
begin
  Result:='0x';
  for i:=1 to length(AStr)  do
  begin
    ch:=AStr[i];
    Result:=Result+IntToHex(Ord(ch),2);
  end;
end;

function BaseEncodeFile(fn: TFileName): string;
var
  ms: TMemoryStream;
  ss: TStringStream;
  str: string;
begin
  ms := TMemoryStream.Create;
  ss := TStringStream.Create('');
  try
    ms.LoadFromFile(fn);
    EncdDecd.EncodeStream(ms, ss);                       // 將ms的內容Base64到ss中
    str := ss.DataString;
    str := StringReplace(str, #13, '', [rfReplaceAll]);  // 這裡ss中數據會自動添加回車換行,所以需要將回車換行替換成空字元
    str := StringReplace(str, #10, '', [rfReplaceAll]);
    result := str;                                       // 返回值為Base64的Stream
  finally
    FreeAndNil(ms);
    FreeAndNil(ss);
  end;
end;

procedure SplitString(Source,Deli:string; var lst :TStrings);
var
  EndOfCurrentString: Integer;
begin
  if  lst = nil then exit;
  lst.Clear;
  while Pos(Deli, Source)>0 do
  begin
    EndOfCurrentString := Pos(Deli, Source);
    lst.add(Copy(Source, 1, EndOfCurrentString - 1));
    Source := Copy(Source, EndOfCurrentString + length(Deli), length(Source) - EndOfCurrentString);
  end;
  lst.Add(source);
end;

function GetFileStructureList(Path: PChar; var lst: TStrings): LongInt;
var
  SearchRec: TSearchRec;
  Found: Integer;
  TmpStr, TmpLocator: string;
  CurDir, DirLocator: PChar;
  DirQue: TQueue;
  C: Cardinal;
begin
  Result := 0;
  if lst = nil then exit;
  dirQue := TQueue.Create;
  try
    CurDir := Path;
    DirLocator := PChar(GetPathLocator());
    lst.Add('0|'+CurDir+'|'+DirLocator);
    while CurDir <> nil do
    begin
      //搜索尾碼,如:c:\*.*;
      TmpStr := IncludeTrailingPathDelimiter(curDir)+'*.*';
      Found := FindFirst(TmpStr, faAnyFile, SearchRec);
      while Found = 0 do
      begin
        C := GetFileAttributes(PChar(IncludeTrailingPathDelimiter(curDir) + SearchRec.Name));
        //if (searchRec.Attr and faDirectory)<>0 then  //這個貌似有問題/
        if (C and FILE_ATTRIBUTE_DIRECTORY)<> 0 then
        begin
          if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
          begin
            TmpStr := IncludeTrailingPathDelimiter(curDir)+SearchRec.Name;
            TmpLocator := GetPathLocator(False);
            TmpLocator := DirLocator + TmpLocator;
            lst.Add('0|'+TmpStr+'|'+TmpLocator);
            DirQue.Push(StrNew(PChar(TmpStr)));
            DirQue.Push(StrNew(PChar(TmpLocator)));
          end;
        end else begin
          Result:=Result+1;
          TmpLocator := GetPathLocator(False);
          TmpLocator := DirLocator + TmpLocator;
          lst.Add('1|'+IncludeTrailingPathDelimiter(curDir)+SearchRec.Name+'|'+TmpLocator);
        end;
        found:=FindNext(SearchRec);
      end;
      {當前目錄找到後,如果隊列中沒有數據,則表示全部找到了;
      否則就是還有子目錄未查找,取一個出來繼續查找。}
      if DirQue.Count > 0 then
      begin
        CurDir := DirQue.Pop;
        DirLocator := DirQue.Pop;
      end else begin
        CurDir := nil;
        DirLocator := nil;
      end;
    end;
  finally
    dirQue.Free;
  end;
end;

end.

效果圖如下,目錄加文件共計20個。

本地文件夾E:\Doc:

 

 

 FileTable虛擬目錄文件Doc:

資料庫表中存放數據:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、初識socket socket(套接字)起源於20世紀70年代加利福尼亞大學伯克利分校版本的Unix,即人們所說的BSDUnix。因此,有時人們也把套接字稱為“伯克利套接字”或“BSD套接字”。一開始,套接字被設計用在同一臺主機上多個應用程式之間的通訊。這也被稱進程間通訊,或IPC。socket ...
  • 狀態模式可以看做是在運行時改變對象行為的一種方式。狀態模式允許對象在其內部狀態變化時改變其行為,此時感覺就像對象本身已經改變了一樣。 參與者: State介面:State基類,定義不同狀態共同需要執行的介面。 ConcreteSate對象:State基類的子類,不同狀態的可以在子類介面中實現不同的操 ...
  • 一、概述 本篇介紹自適應擴展,方法getAdaptiveExtension()的實現。ExtensionLoader類本身很多功能也使用到了自適應擴展。包括ExtensionFactory擴展。 通俗的講,自適應擴展要實現的邏輯是:調用擴展點的方法時,自動判斷要調用那個擴展點實現類的方法。我們知道, ...
  • softmax函數的作用 對於分類方面,softmax函數的作用是從樣本值計算得到該樣本屬於各個類別的概率大小。例如手寫數字識別,softmax模型從給定的手寫體圖片像素值得出這張圖片為數字0~9的概率值,這些概率值之和為1。預測的結果取最大的概率表示的數字作為這張圖片的分類。 可以從下麵這張圖理解 ...
  • ...
  • 本文主要講解Spring載入xml配置文件的方式,跟蹤載入BeanDefinition的全過程。 源碼分析 源碼的入口 ClassPathXmlApplicationContext構造函數 new ClassPathXmlApplicationContext(“spring.xml”)用於載入CLA ...
  • 如圖,即實現點擊一個城市,出現對應的學校名稱。開始一直以為是建立數據表的時候實現的,原來是通過ajax實現的。 思路:當get請求顯示原始狀態(即下拉框呈現全部內容)。當點擊一個城市後,通過ajax的post方式提交,然後後端返回篩選的數據到前端,然後js先將所有的學校標簽刪除,創建後端傳過來的學校 ...
  • Python 列表 list (以下內容為比較初級適合小白查看的筆記) 一、介紹: 列表是Python中內置有序、可變序列,列表的所有元素放在一對中括弧“[]”中,並使用逗號分隔開; 列表可以進行增刪改查,每一次操作,都會補全列表中的位置,保證在列表中沒有縫隙 list中,可以存整數、小數、字元串等 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...