主頁 > 軟體工程 > 處理檔案

處理檔案

2021-10-15 07:28:57 軟體工程

在考慮了解決方案并分析了所有答案后,我洗掉了我的帖子

uj5u.com熱心網友回復:

a 的重點BackgroundWorker是將東西從 UI 執行緒中推出。這樣做了,但隨后Bw_DoWork你立即將東西推UI 執行緒,使用this.Dispatcher.Invoke,它會阻塞作業執行緒,直到現在在 UI 執行緒上運行的作業完成。

基本上:洗掉該this.Dispatcher.Invoke呼叫,然后在 worker 上運行代碼如果您需要觸摸 UI,那么您需要在 UI 執行緒上處理這些位,但僅限于那些按鈕。

同樣,我懷疑mutliocr應該使用 dispatch invoke,它當然不應該將 UI 執行緒更改為后臺執行緒 ( Thread.CurrentThread.IsBackground = true;)。

uj5u.com熱心網友回復:

您的代碼非常非常臭和丑陋。您似乎完全沒有遵循任何命名約定。本地和班級成員是駝峰式和 PascalCase,有些根本不使用大小寫,有些則使用下劃線。你真的應該仔細檢查你的代碼,考慮很多方面并清理它。也有一些冗余。

你的一個非常糟糕的習慣是過度使用Dispatcher. 例如,您創建一個后臺執行緒并發布完整的!此執行緒的作業回傳到Dispatcher/UI 執行緒。資源的巨大浪費并消除了任何多執行緒優勢。
您不想將所有作業都放在Dispatcher. 您想將 CPU 密集型 eork 卸載到后臺執行緒。您希望盡可能使用異步 API。因為你想讓 UI 保持回應。Dispatcher表示 UI 執行緒。

一些非常重要的興趣點

  • GrantAccess實施是對用戶權利的嚴重安全侵犯。不要修改訪問規則。而是過濾并忽略當前用戶無權訪問的資源。特別重要的是,您永遠不要將訪問權限恢復到原始狀態。
  • 作為一般規則:不要在后臺執行緒上執行 IO 相關代碼(例如,資料庫、HTTP 流、檔案 IO)。請改用異步 API。僅將執行緒用于 CPU 密集型作業(例如計算、轉換)。
  • File有一個你應該經常使用的異步 API。例如File.OpenRead回傳一個FileStream暴露FileStream.ReadAsnyc成員的。如果您在處理檔案時需要更多便利,例如逐行讀取,則將其包裝FileStreamStreamReader/StreamWriter并使用類似的成員StreamReader.ReadLineAsync
  • 為避免Dispatcher呼叫,請將所需的 UI 值作為引數傳遞給并發方法。更好地使用資料系結(這不會消除跨執行緒寫入問題,但會使您的代碼更具可讀性并消除Dispatcher讀取值的呼叫)。看看下面的重構File_process方法。它展示了如何將 UI 值作為引數傳遞給converttiffpdfreducer然后在后臺執行緒上執行方法。
  • 考慮為長期運行添加取消支持 converttiffpdfreducer()
  • 避免呼叫ToArrayToListIEnumerable這些方法是立即執行最初延遲的 LINQ 查詢的終結器。
  • 不要打電話ToArrayToList對結果之類的EnumerateFiles這些方法用于提高性能,因為它們逐項回傳檔案系統物件。如果您遞回迭代整個檔案系統結構,這一點尤其重要。如果檔案系統樹很深很寬,呼叫ToArray將強制迭代完成,然后立即回傳所有結果。ToArrayonEnumerateFiles就像使用GetFiles. 您應該檢查完整的代碼并正確重構它。你總是用Enumerate XYZ 錯!

》 EnumerateFiles 和 GetFiles 方法的區別如下: 使用 EnumerateFiles 時,可以在回傳整個集合之前開始列舉名稱集合。使用 GetFiles 時,必須等待整個名稱陣列回傳后才能進行訪問陣列。因此,當您處理許多檔案和目錄時,EnumerateFiles 可以更高效。”

  • 使用資料系結而不是直接訪問 UI 元素。這允許您在不使用Dispatcher.
  • 永遠不要從建構式執行長時間運行的操作
  • 永遠不要從建構式呼叫異步代碼
  • 始終保持物件實體化便宜且快速,并且沒有隱藏的性能/資源成本
  • 永遠抓不到Exception始終捕獲專門的例外型別。
  • 不要使用空的 catch 塊。如果可以,要么處理例外,要么讓它使您的應用程式崩潰,讓您有機會修復錯誤。當您吞下例外時,錯誤將悄悄地潛入您的應用程式。你將很難發現它們。記錄例外不被視為處理 - 在這種情況下重新拋出。
  • 如果使用using陳述句宣告資源,則不必顯式關閉資源Dispose一旦指令指標離開using作用域,隱式呼叫將自動關閉資源。

實施所有建議將顯著加快您的應用程式。

I have refactored only some of your code to show how to properly use async APIs and Task.Run instead of the BackgroundWorker. I have removed every Dispatcher invocation. Instead of direct access to UI elements in order to read their values from the background thread, I have extracted those values before invoking the concurent method and passed those prefetched values as method arguments. If you would use data binding you could read the property values directly and therefore ommit the method parameters.

The MainWindow should be shown manually from App.xaml.cs to allow asynchronous and longrunning initialization of the instance. For this pattern let the class that requires such initialization implement a public InitializeAsync method that can be awaited from the caller's context. Alternatively use Lazy<T> to defer initialization when required e.g., when initialization is depending on explicit access to members.

Although the refactored code will significantly improve the applicatoin's performance, you will have do to do some important refactoring yourself (following the pattern of the already refactored code sections).
Take a look at

  • InitializeAsync and WriteLnAsync to learn how to use the async file IO API.
  • converttiffpdfreducer to learn how to use the EnumerateFiles and EnumerateDirectories methods properly in order to significantly improve the performance.
  • mutliocr, merge and converttiffpdfreducer to learn how pass UI element values as argument in order to avoid Dispatcher invocations.
  • start_btn_Click and converttiffpdfreducer to learn how to implemnent cancellation and to guard your API against calls during an uninitialized state

App.xaml

<Application Startup="Application_Startup">

</Application>

App.xaml.cs

class App : Application
{
  private async void Application_Startup(object sender, StartupEventArgs e)
  {
    var mainWindow = new MainWindow();

    // Because InitializeAsync depends on UI elements,
    // we have to wait until the Ui is loaded.
    mainWindow.Loaded  = OnMainWindowLoaded;

    // Either call Show() before initialization or after.
    // If before, ensure access to uninitialized members and resources is denied
    // e.g. by querying the MainWindow.IsInitialized property in public members and event handlers.
    mainWindow.Show();        
  }

  private async void OnMainWindowLoaded(object sender, EventArgs args) 
    => await mainWindow.InitializeAsync();
}

MainWindow.xaml.cs

public partial class MainWindow : Window
{
  public bool IsInitialized { get; private set; }
  private bool IsBusy { get; set; }
  private CancellationTokenSource CancellationTokenSource { get; set; }

  public MainWindow()
  {
    InitializeComponent();
    CancellationTokenSource = new CancellationTokenSource();
  }

  // Execute blocking initialization routines asynchronously
  public async Task InitializeAsync()
  {
    if (IsInitialized)
    {
      return;
    }

    // Will execute the intesive CPU bound work on a background thread.
    await File_process(Cancellationtoken.None);

    string configpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"path.txt");
    // Use async API to read/write from/to files and other IO resources
    using (FileStream configfile = File.OpenRead(configpath))
    {
      using (var fileReader = new StreamReader(configfile))
      {
        var configFileContent = new List<string>();
        while (!fileReader.EndOfStream)
        {
          string lineOfFile = await fileReader.ReadLineAsync();
          configFileContent.Add(lineOfFile);
        }

        if (configFileContent.Any())
        {
          ip.Text = configFileContent[0];
          GrantAccess(configFileContent[0]);

          op.Text = configFileContent[1];
          GrantAccess(configFileContent[1]);

          ex_tb.Text = configFileContent[2];
          GrantAccess(configFileContent[2]);

          Protb.Text = configFileContent[3];
          GrantAccess(configFileContent[3]);
        }
      }
    }

    cbPDFConform.Items.Clear();
    for (int i = 0; i < Enum.GetNames(typeof(PdfConformance)).Length - 1; i  )
    {
      ComboBoxItem cbi = new ComboBoxItem();
      cbi.Content = Enum.GetName(typeof(PdfConformance), (PdfConformance)i);
      PdfConformance test = (PdfConformance)i;
      cbi.Tag = (PdfConformance)i;
      cbPDFConform.Items.Add(cbi);
    }

    cbPDFConform.SelectedIndex = 0;
    cbProcessorCount.Items.Clear();
    for (int i = 1; i <= Environment.ProcessorCount; i  )
    {
      cbProcessorCount.Items.Add(i.ToString());
      if (Environment.ProcessorCount / 2 == i) { cbProcessorCount.SelectedIndex = i - 1; }
    }

    LicenseManager oLicenseManager = new LicenseManager();
    oLicenseManager.RegisterKEY("");

    threadSyn = SynchronizationContext.Current;

    IsInitialiezd = true;
  }

  public async Task File_process(CancellationToken cancellationToken)
  {
    // Read UI values to avoid Dispatcher calls from the background thread
    string ipText = ip.Text;
    string protbText = Protb.Text;
    string opText = op.Text;

    // Execute the intesive CPU bound work on a background thread.
    await Task.Run(() => converttiffpdfreducer(ipText, protbText, opText, cancellationToken), cancellationToken);
  }

private async Task DoWorkAsync(CancellationToken cancellationToken)
{
  IsBusy = true;

  using (var sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"path.txt"), false))
  {
    await sw.WriteLineAsync(ip.Text);
    await sw.WriteLineAsync(op.Text);
    await sw.WriteLineAsync(ex_tb.Text);
    await sw.WriteLineAsync(Protb.Text);
  }

  try
  {
    cancellationToken.ThrowIfCancellationRequested();

    var watch1 = new System.Diagnostics.Stopwatch();
    watch1.Start();

    // Consider to add cancellation support to File_process 
    await File_process(cancellationToken);

    watch1.Stop();

    TimeSpan ts1 = watch1.Elapsed;
    ts1.ToString("mm\\:ss");

    if (MergeChk.IsChecked == false)
    {
      value = "OCRed";
    }

    await WriteLnAsync("All documents have been successfully "   value   " "   ts1   " "   DateTime.Now   " "   Environment.UserName, cancellationToken);

    IsBusy = false;
  }
  catch (OperationCanceledException)
  {
    IsBusy = false;
    throw;
  }
}

  private async Task WriteLnAsync(string text, CancellationToken cancellationToken)
  {
    logtb.Text  = text   Environment.NewLine;

    log_list.Add(text);
    log_cap = text   Environment.NewLine   log_cap;
    using (var sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"FileProcessing_log.txt"), false))
    {
      foreach (string l in log_list)
      {
        cancellationToken.ThrowIfCancellationRequested();
        await sw.WriteLineAsync(l);
      }
    }
  }

  private async void start_btn_Click(object sender, RoutedEventArgs e)
  {
    if (!IsInitialized)
    {
      return;
    }

    if (IsBusy)
    {
      // Cancel the longrunning operation.
      this.CancellationTokenSource.Cancel();
    }
    start_btn.Content = "Start";

    try
    {
      await DoWorkAsync(CancellationTokenSource.Token);
    }
    catch (OperationCanceledException)
    {
      CancellationTokenSource?.Dispose();
      CancellationTokenSource = new CancellationTokenSource();
    }
  }

  private void converttiffpdfreducer(
    string ipText, 
    string protbText, 
    string opText, 
    CancellationToken cancellationToken)
  {
    string[] dir = null;
    string box = string.Empty;
    string box1 = string.Empty;
    string[] gg = null;


    PdfConformance optPDFConform = PdfConformance.Unknown;

    foreach (var directoryPath in Directory.EnumerateDirectories(ipText, "*.*", SearchOption.AllDirectories).Where(l => l.Length != 0))
    {
      cancellationToken.ThrowIfCancellationRequested();

      foreach (var filePath in Directory.EnumerateFiles(directoryPath, "*.*", SearchOption.AllDirectories))
      {
        cancellationToken.ThrowIfCancellationRequested();

        string getext = Path.GetExtension(filePath);
        string fd = Path.GetDirectoryName(filePath);
        string op_path = fd.Replace(ipText, protbText);
        string getextension = Path.GetExtension(filePath);
        string dict = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Redist", "OCR");
        string outputPath = fd.Replace(ipText, protbText);
        string FNAME = Path.GetFileNameWithoutExtension(filePath);
        string fn = Path.GetDirectoryName(filePath).Replace(ipText, protbText);
        string filen = Path.Combine(outputPath, fn, FNAME   ".pdf");
        string savefile = Path.Combine(op_path, filen);

        box = Path.GetDirectoryName(filePath);
        box1 = Path.GetDirectoryName(box);
        using (GdPictureDocumentConverter oConverter = new GdPictureDocumentConverter())
        {
          GdPictureStatus status = new GdPictureStatus();
          if (Path.GetExtension(filePath).ToUpper() == ".PDF")
          {
            status = oConverter.LoadFromFile(filePath, GdPicture14.DocumentFormat.DocumentFormatPDF);
          }

          else if (Path.GetExtension(filePath).ToUpper() == ".TIF" || Path.GetExtension(filePath).ToUpper() == ".TIFF")

          {
            status = oConverter.LoadFromFile(filePath, GdPicture14.DocumentFormat.DocumentFormatTIFF);
          }
          else if (Path.GetExtension(filePath).ToUpper() == ".JPG")
          {
            status = oConverter.LoadFromFile(filePath, GdPicture14.DocumentFormat.DocumentFormatJPEG);
          }

          if (status == GdPictureStatus.OK)
          {
            if (!Directory.Exists(op_path))
            {
              Directory.CreateDirectory(op_path);
            }
            GrantAccess(op_path);
            optPDFConform = (PdfConformance)((ComboBoxItem)cbPDFConform.SelectedItem).Tag;
            status = oConverter.SaveAsPDF(savefile, optPDFConform);
            if (status == GdPictureStatus.OK)
            { }
            else
            { }
          }
          else
          { }
        }
      }
    }

    string BOXX = box.Replace(ipText, protbText);

    // TODO::Refactor 'merge' and replace 'ToArray' with 'foreach'
    string[] Arr = Directory.EnumerateFiles(BOXX, "*.pdf", SearchOption.AllDirectories).ToArray();
    if (MergeChk.IsChecked == true)
    { merge(Arr, protbText); }
    else if (MergeChk.IsChecked == false)
    {
      mutliocr(Arr);
    }
  }

  private string[] merge(string[] arr, string protbText, string opText)
  {
    string box = string.Empty;
    string box1 = string.Empty; string[] gg = null;
    System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
    {
      box = Path.GetDirectoryName(arr[0]);
      box1 = Path.GetDirectoryName(box);
      string dirName = Directory.GetParent(arr[0]).FullName;
      string BOXFILES = Path.GetDirectoryName(dirName);
      string folder = Directory.GetParent(arr[0]).FullName.Replace(protbText, opText);

      string ocrfolder = (new FileInfo(arr[0]).Directory.FullName).Replace(protbText, opText);
      string fn = Directory.GetParent(arr[0]).Name;
      string filen = Path.Combine(ocrfolder, folder, fn   ".pdf");
      if (!Directory.Exists(ocrfolder))
      {
        Directory.CreateDirectory(ocrfolder);
      }
      GrantAccess(ocrfolder);
      using (GdPicturePDF oGdPicturePDF = new GdPicturePDF())
      {
        GdPictureStatus status = oGdPicturePDF.MergeDocuments(ref arr, filen);

        if (status == GdPictureStatus.OK)
        { }
        else
        { }
        oGdPicturePDF.Dispose();
      }
      Directory.Delete(box, true);
      string BOXX = box.Replace(protbText, opText);//op            
      string[] files = Directory.EnumerateFiles(BOXX, "*.pdf", SearchOption.AllDirectories).ToArray();
      if (MergeChk.IsChecked == true)
      { mutliocr(files, protbText, opText); }
    }));
    return gg;
  }

  private string[] mutliocr(string[] arr, string protbText, string opText)
  {
    string box = string.Empty;
    string box1 = string.Empty;
    try
    {
      string filepath = string.Empty;
      if (MergeChk.IsChecked == true)
      { filepath = opText; }
      else if (MergeChk.IsChecked == false)
      { filepath = protbText; }
      System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
      {
        Thread.CurrentThread.IsBackground = true;
        var watch2 = new System.Diagnostics.Stopwatch();
        watch2.Start();
        string[] getfilearray = arr;
        for (int f = 0; f < getfilearray.Length; f  )
        {
          string dirName = Directory.GetParent(getfilearray[f]).FullName;
          string folder = Directory.GetParent(getfilearray[f]).FullName;

          box = Path.GetDirectoryName(getfilearray[f]);
          box1 = Path.GetDirectoryName(box);
          string getextension = Path.GetExtension(getfilearray[f]);
          string[] newF = Directory.EnumerateFiles(dirName, "*.*", SearchOption.AllDirectories).ToArray();
          string FN = Directory.GetParent(getfilearray[f]).Name;
          string ocrfolder = (new FileInfo(getfilearray[f]).Directory.FullName);
          string filen = Path.Combine(ocrfolder, folder, FN   "-ocr"   getextension);
          string dict = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Redist", "OCR");
          if (!Directory.Exists(ocrfolder))
          {
            Directory.CreateDirectory(ocrfolder);
          }
          GrantAccess(ocrfolder);
          GdPicturePDF oGdPicturePDF = new GdPicturePDF();
          oGdPicturePDF.OcrPagesDone  = OcrPagesDone;
          void OcrPagesDone(GdPictureStatus status1)
          {
            if (oGdPicturePDF.SaveToFile(filen) == GdPictureStatus.OK)
            { }
            else
              MessageBox.Show("PDF: The OCR-ed file has failed to save. Status: "   oGdPicturePDF.GetStat().ToString());
          }
          GdPictureStatus status = GdPictureStatus.OK;
          if (oGdPicturePDF.LoadFromFile(getfilearray[f], false) == GdPictureStatus.OK)
            if (status == GdPictureStatus.OK)
            {
              if (oGdPicturePDF.OcrPages_4("*", 0, "eng", dict, "", 300, OCRMode.FavorSpeed, 1, true) == GdPictureStatus.OK)
                if (status == GdPictureStatus.OK)
                { }
                else
                { MessageBox.Show("PDF: The OCR process has failed. Status: "   status.ToString()); }
            }
            else
            { MessageBox.Show("PDF: The PDF file has failed to load. Status: "   status.ToString()); }

          oGdPicturePDF.Dispose();
          GrantAccess(getfilearray[f]);
          File.Delete(getfilearray[f]);
          watch2.Stop();
          TimeSpan ts2 = watch2.Elapsed;
          ts2.ToString("mm\\:ss");
          WriteLn(" OCR pages "   filen.Replace(opText, "")   " "   ts2   " "   DateTime.Now);
        }
        if (MergeChk.IsChecked == true)
        {
          foreach (string str in Directory.EnumerateFiles(opText, "*.pdf", SearchOption.AllDirectories).ToArray())
          {
            if (Path.GetFileNameWithoutExtension(str).EndsWith("-ocr"))
              File.Move(str, Path.Combine(Path.GetDirectoryName(str), Path.GetFileNameWithoutExtension(str).Substring(0, Path.GetFileNameWithoutExtension(str).Length - 4)   ".pdf"));
          }
        }
        if (MergeChk.IsChecked == false)
        {
          FileSystem.MoveDirectory(protbText, opText, UIOption.AllDialogs);
          Directory.CreateDirectory(protbText);
          string FF = string.Empty;
          foreach (string str in Directory.EnumerateFiles(opText, "*.pdf", SearchOption.AllDirectories))
          {

            if (Path.GetFileNameWithoutExtension(str).EndsWith("-ocr"))
              File.Move(str, Path.Combine(Path.GetDirectoryName(str), Path.GetFileNameWithoutExtension(str).Substring(0, Path.GetFileNameWithoutExtension(str).Length - 4)   ".pdf"));
          }
        }

      }));
    }
    catch (Exception mul)
    {
    }
    return arr;
  }
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/314844.html

標籤:C# 小白 图像处理 写字楼 文件传输

上一篇:如何確定3-D射線穿過的第一個三角形(一組三角形中)?

下一篇:比較和匹配不同資料框架的逗號分隔字串Pythonpandas

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more