Step 3: Implement Document Scanning in JavaScript

With the environment ready, the next step is to implement the relevant functions in JavaScript.

Get Devices

Enumerate the available scanners.

const ScannerType = {    // TWAIN scanner type, represented by the value 0x10    TWAINSCANNER: 0x10,    // WIA scanner type, represented by the value 0x20    WIASCANNER: 0x20,    // 64-bit TWAIN scanner type, represented by the value 0x40    TWAINX64SCANNER: 0x40,    // ICA scanner type, represented by the value 0x80    ICASCANNER: 0x80,    // SANE scanner type, represented by the value 0x100    SANESCANNER: 0x100,    // eSCL scanner type, represented by the value 0x200    ESCLSCANNER: 0x200,    // WiFi Direct scanner type, represented by the value 0x400    WIFIDIRECTSCANNER: 0x400,    // WIA-TWAIN scanner type, represented by the value 0x800    WIATWAINSCANNER: 0x800};let queryDevicesButton = document.getElementById(\\\"query-devices-button\\\");queryDevicesButton.onclick = async () => {    let scannerType = ScannerType.TWAINSCANNER | ScannerType.TWAINX64SCANNER;    let devices = await getDevices(host, scannerType);    let select = document.getElementById(\\\"sources\\\");    select.innerHTML = \\'\\';    for (let i = 0; i < devices.length; i  ) {        let device = devices[i];        let option = document.createElement(\\\"option\\\");        option.text = device[\\'name\\'];        option.value = JSON.stringify(device);        select.add(option);    };}async function getDevices(host, scannerType) {    devices = [];    let url = host   \\'/DWTAPI/Scanners\\'    if (scannerType != null) {        url  = \\'?type=\\'   scannerType;    }    try {        let response = await fetch(url);        if (response.ok) {            let devices = await response.json();            return devices;        }    } catch (error) {        console.log(error);    }    return [];}

Explanation

Acquire Image

Scan documents from the selected scanner by specifying the pixel type, resolution, and other settings.

let scanButton = document.getElementById(\\\"scan-button\\\");scanButton.onclick = async () => {    let select = document.getElementById(\\\"sources\\\");    let device = select.value;    if (device == null || device.length == 0) {        alert(\\'Please select a scanner.\\');        return;    }    let inputText = document.getElementById(\\\"inputText\\\").value;    let license = inputText.trim();    if (license == null || license.length == 0) {        alert(\\'Please input a valid license key.\\');    }    let parameters = {        license: license,        device: JSON.parse(device)[\\'device\\'],    };    let showUICheck = document.getElementById(\\\"showUICheckId\\\");    let pixelTypeSelect = document.getElementById(\\\"pixelTypeSelectId\\\");    let resolutionSelect = document.getElementById(\\\"resolutionSelectId\\\");    let adfCheck = document.getElementById(\\\"adfCheckId\\\");    let duplexCheck = document.getElementById(\\\"duplexCheckId\\\");    parameters.config = {        IfShowUI: showUICheck.checked,        PixelType: pixelTypeSelect.selectedIndex,        Resolution: parseInt(resolutionSelect.value),        IfFeederEnabled: adfCheck.checked,        IfDuplexEnabled: duplexCheck.checked,    };    let jobId = await scanDocument(host, parameters);    let images = await getImages(host, jobId);    for (let i = 0; i < images.length; i  ) {        let url = images[i];        let img = document.getElementById(\\'document-image\\');        img.src = url;        data.unshift(url);        let option = document.createElement(\\\"option\\\");        option.selected = true;        option.text = url;        option.value = url;        let thumbnails = document.getElementById(\\\"thumb-box\\\");        let newImage = document.createElement(\\'img\\');        newImage.setAttribute(\\'src\\', url);        if (thumbnails != null) {            thumbnails.insertBefore(newImage, thumbnails.firstChild);            newImage.addEventListener(\\'click\\', e => {                if (e != null && e.target != null) {                    let target = e.target;                    img.src = target.src;                    selectedThumbnail = target;                }            });        }        selectedThumbnail = newImage;    }}async function scanDocument(host, parameters, timeout = 30) {    let url = host   \\'/DWTAPI/ScanJobs?timeout=\\'   timeout;    try {        let response = await fetch(url, {            method: \\'POST\\',            headers: {                \\'Content-Type\\': \\'application/json\\'            },            body: JSON.stringify(parameters)        });        if (response.ok) {            let jobId = await response.text();            return jobId;        }        else {            return \\'\\';        }    } catch (error) {        alert(error);        return \\'\\';    }}async function getImages(host, jobId) {    let images = [];    let url = host   \\'/DWTAPI/ScanJobs/\\'   jobId   \\'/NextDocument\\';    while (true) {        try {            let response = await fetch(url);            if (response.status == 200) {                const arrayBuffer = await response.arrayBuffer();                const blob = new Blob([arrayBuffer], { type: response.type });                const imageUrl = URL.createObjectURL(blob);                images.push(imageUrl);            }            else {                break;            }        } catch (error) {            console.error(\\'No more images.\\');            break;        }    }    return images;}

Explanation

Rotate Image

Rotate the scanned image by -90 or 90 degrees.

let rotateLeftButton = document.getElementById(\\\"rotate-left-button\\\");rotateLeftButton.onclick = () => {    let img = document.getElementById(\\'document-image\\');    img.src = rotateImage(\\'document-image\\', -90);    selectedThumbnail.src = img.src;}let rotateRightButton = document.getElementById(\\\"rotate-right-button\\\");rotateRightButton.onclick = () => {    let img = document.getElementById(\\'document-image\\');    img.src = rotateImage(\\'document-image\\', 90);    selectedThumbnail.src = img.src;}    function rotateImage (imageId, angle) {    const image = document.getElementById(imageId);    const canvas = document.createElement(\\'canvas\\');    const context = canvas.getContext(\\'2d\\');    const imageWidth = image.naturalWidth;    const imageHeight = image.naturalHeight;    // Calculate the new rotation    let rotation = 0;    rotation = (rotation   angle) % 360;    // Adjust canvas size for rotation    if (rotation === 90 || rotation === -270 || rotation === 270) {        canvas.width = imageHeight;        canvas.height = imageWidth;    } else if (rotation === 180 || rotation === -180) {        canvas.width = imageWidth;        canvas.height = imageHeight;    } else if (rotation === 270 || rotation === -90) {        canvas.width = imageHeight;        canvas.height = imageWidth;    } else {        canvas.width = imageWidth;        canvas.height = imageHeight;    }    // Clear the canvas    context.clearRect(0, 0, canvas.width, canvas.height);    // Draw the rotated image on the canvas    context.save();    if (rotation === 90 || rotation === -270) {        context.translate(canvas.width, 0);        context.rotate(90 * Math.PI / 180);    } else if (rotation === 180 || rotation === -180) {        context.translate(canvas.width, canvas.height);        context.rotate(180 * Math.PI / 180);    } else if (rotation === 270 || rotation === -90) {        context.translate(0, canvas.height);        context.rotate(270 * Math.PI / 180);    }    context.drawImage(image, 0, 0);    context.restore();    return canvas.toDataURL();}

Delete Image

Delete all scanned images, including the main image and thumbnails, and reset the data array.

let deleteButton = document.getElementById(\\\"delete-button\\\");deleteButton.onclick = async () => {    let img = document.getElementById(\\'document-image\\');    img.src = \\'images/default.png\\';    data = [];    let thumbnails = document.getElementById(\\\"thumb-box\\\");    thumbnails.innerHTML = \\'\\';}

Step 4: Interop Between C# and JavaScript for Saving Images

Saving images directly in JavaScript is restricted due to security concerns. Therefore, we need to interoperate between C# and JavaScript to accomplish this task.

  1. Create a JavaScript function to convert the scanned image to a base64 string.

    function getBase64Image() {    var img = document.getElementById(\\'document-image\\');    var canvas = document.createElement(\\'canvas\\');    canvas.width = img.naturalWidth;    canvas.height = img.naturalHeight;    var ctx = canvas.getContext(\\'2d\\');    ctx.drawImage(img, 0, 0);    var dataURL = canvas.toDataURL(\\'image/png\\');     var base64 = dataURL.split(\\',\\')[1];     return base64;}
  2. When clicking the save button, set window.location.href to trigger the OnWebViewNavigated event handler of the WebView control.

    let saveButton = document.getElementById(\\\"save-button\\\");saveButton.onclick = async () => {    window.location.href = \\'invoke://CallCSharpFunction\\';    }
  3. In the OnWebViewNavigated event handler, call EvaluateJavaScriptAsync to retrieve the base64 image data from JavaScript and save it to a file.

    private async void OnWebViewNavigated(object sender, WebNavigatingEventArgs e){    if (e.Url.StartsWith(\\\"invoke://callcsharpfunction\\\"))    {        var base64String = await WebView.EvaluateJavaScriptAsync(\\\"getBase64Image()\\\");        CallCSharpFunction(base64String);    }}private void CallCSharpFunction(string base64String){    if (!string.IsNullOrEmpty(base64String))    {        try        {            byte[] imageBytes = Convert.FromBase64String(base64String);            var filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), GenerateFilename());            File.WriteAllBytes(filePath, imageBytes);            DisplayAlert(\\\"Success\\\", \\\"Image saved to: \\\"   filePath, \\\"OK\\\");        }        catch (Exception ex)        {            DisplayAlert(\\\"Error\\\", ex.Message, \\\"OK\\\");        }    }    else    {        DisplayAlert(\\\"Failure\\\", \\\"No image data found\\\", \\\"OK\\\");    }}private string GenerateFilename(){    DateTime now = DateTime.Now;    string timestamp = now.ToString(\\\"yyyyMMdd_HHmmss\\\");    return $\\\"image_{timestamp}.png\\\";}

Note: Do not pass the base64 string directly to the C# function via window.location.href, as the string may be too long and cause an error. Instead, return the base64 string when calling EvaluateJavaScriptAsync from the C# function.

Step 5: Run the .NET MAUI Document Scanner Application

Press F5 in Visual Studio or Visual Studio Code to run the .NET document scanner application on Windows or macOS.

\\\"Switching

Source Code

https://github.com/yushulx/dotnet-twain-wia-sane-scanner/tree/main/examples/MauiWebView

","image":"http://www.luping.net/uploads/20240801/172251253066ab7492458d1.png","datePublished":"2024-08-01T19:42:09+08:00","dateModified":"2024-08-01T19:42:09+08:00","author":{"@type":"Person","name":"luping.net","url":"https://www.luping.net/articlelist/0_1.html"}}
”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 从 .NET MAUI Blazor 切换到 WebView 控件进行文档扫描

从 .NET MAUI Blazor 切换到 WebView 控件进行文档扫描

发布于2024-08-01
浏览:770

In .NET MAUI development, both BlazorWebView and WebView are used to display web content, but they serve different purposes and are designed for different scenarios. The BlazorWebView is specifically designed to host Blazor components in a .NET MAUI application, allowing you to reuse Blazor components and share code between web and native applications. The WebView is a general-purpose control for displaying web content, including web pages, HTML strings, and local HTML files. In this article, we will explore how to transition a .NET MAUI Blazor document scanner application to a .NET MAUI application using the WebView control, implementing the document scanning logic in JavaScript and HTML, and enabling interoperation between C# and JavaScript to scan documents and save images.

Prerequisites

  1. Install Dynamsoft Service: This service is necessary for communicating with TWAIN, SANE, ICA, ESCL, and WIA scanners on Windows and macOS.
    • Windows: Dynamsoft-Service-Setup.msi
    • macOS: Dynamsoft-Service-Setup.pkg
  2. Request a Free Trial License: Obtain a 30-day free trial license for Dynamic Web TWAIN to get started.

Step 1: Create a New .NET MAUI Project with WebView Control

  1. In Visual Studio or Visual Studio Code, create a new .NET MAUI project.
  2. Open the MainPage.xaml file and replace the existing code with the following XAML to add a WebView control:

  3. Open the MainPage.xaml.cs file and add the following code to set the source of the WebView and handle the Navigating event:

    namespace MauiWebView
    {
        public partial class MainPage : ContentPage
        {
            public MainPage()
            {
                InitializeComponent();
                LoadHtmlFile();
            }
    
            private void LoadHtmlFile()
            {
                WebView.Source = "index.html";
    
            }
    
            private async void OnWebViewNavigated(object sender, WebNavigatingEventArgs e)
            {
                if (e.Url.StartsWith("invoke://callcsharpfunction"))
                {
                    // TODO: Implement interop between C# and JavaScript
                }
            }
        }
    
    }
    
    

    Exaplanation:

    • The LoadHtmlFile method sets the Source property of the WebView control to load the index.html file.
    • The OnWebViewNavigated method is triggered when the WebView navigates to a new URL. It checks if the URL starts with invoke://callcsharpfunction and, if so, allows for C# and JavaScript interop.

Step 2: Load Static HTML, JavaScript, and CSS Files into the WebView Control

In a .NET MAUI project, you can load static HTML, JavaScript, and CSS files located in the Resources/Raw folder into the WebView. Ensure that the MauiAsset build action is included in the .csproj file:

Switching from .NET MAUI Blazor to WebView Control for Document Scanning

We create a similar UI layout as the previous Blazor document scanner application in the index.html file.




    Dynamsoft RESTful API Example

Document Scanner


Acquire Image

Image Tools

从 .NET MAUI Blazor 切换到 WebView 控件进行文档扫描

Step 3: Implement Document Scanning in JavaScript

With the environment ready, the next step is to implement the relevant functions in JavaScript.

Get Devices

Enumerate the available scanners.

const ScannerType = {
    // TWAIN scanner type, represented by the value 0x10
    TWAINSCANNER: 0x10,

    // WIA scanner type, represented by the value 0x20
    WIASCANNER: 0x20,

    // 64-bit TWAIN scanner type, represented by the value 0x40
    TWAINX64SCANNER: 0x40,

    // ICA scanner type, represented by the value 0x80
    ICASCANNER: 0x80,

    // SANE scanner type, represented by the value 0x100
    SANESCANNER: 0x100,

    // eSCL scanner type, represented by the value 0x200
    ESCLSCANNER: 0x200,

    // WiFi Direct scanner type, represented by the value 0x400
    WIFIDIRECTSCANNER: 0x400,

    // WIA-TWAIN scanner type, represented by the value 0x800
    WIATWAINSCANNER: 0x800
};

let queryDevicesButton = document.getElementById("query-devices-button");
queryDevicesButton.onclick = async () => {
    let scannerType = ScannerType.TWAINSCANNER | ScannerType.TWAINX64SCANNER;
    let devices = await getDevices(host, scannerType);
    let select = document.getElementById("sources");
    select.innerHTML = '';
    for (let i = 0; i 



Explanation

  • The getDevices function sends a GET request to the RESTful API endpoint /DWTAPI/Scanners to fetch the available scanners. The scanner type is specified by the scannerType parameter.

Acquire Image

Scan documents from the selected scanner by specifying the pixel type, resolution, and other settings.

let scanButton = document.getElementById("scan-button");
scanButton.onclick = async () => {
    let select = document.getElementById("sources");
    let device = select.value;

    if (device == null || device.length == 0) {
        alert('Please select a scanner.');
        return;
    }

    let inputText = document.getElementById("inputText").value;
    let license = inputText.trim();

    if (license == null || license.length == 0) {
        alert('Please input a valid license key.');
    }

    let parameters = {
        license: license,
        device: JSON.parse(device)['device'],
    };

    let showUICheck = document.getElementById("showUICheckId");

    let pixelTypeSelect = document.getElementById("pixelTypeSelectId");

    let resolutionSelect = document.getElementById("resolutionSelectId");

    let adfCheck = document.getElementById("adfCheckId");

    let duplexCheck = document.getElementById("duplexCheckId");

    parameters.config = {
        IfShowUI: showUICheck.checked,
        PixelType: pixelTypeSelect.selectedIndex,
        Resolution: parseInt(resolutionSelect.value),
        IfFeederEnabled: adfCheck.checked,
        IfDuplexEnabled: duplexCheck.checked,
    };


    let jobId = await scanDocument(host, parameters);
    let images = await getImages(host, jobId);

    for (let i = 0; i  {
                if (e != null && e.target != null) {
                    let target = e.target;
                    img.src = target.src;
                    selectedThumbnail = target;
                }
            });
        }

        selectedThumbnail = newImage;
    }

}

async function scanDocument(host, parameters, timeout = 30) {
    let url = host   '/DWTAPI/ScanJobs?timeout='   timeout;

    try {
        let response = await fetch(url, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(parameters)
        });

        if (response.ok) {
            let jobId = await response.text();
            return jobId;
        }
        else {
            return '';
        }
    } catch (error) {
        alert(error);
        return '';
    }
}

async function getImages(host, jobId) {
    let images = [];
    let url = host   '/DWTAPI/ScanJobs/'   jobId   '/NextDocument';

    while (true) {
        try {

            let response = await fetch(url);

            if (response.status == 200) {
                const arrayBuffer = await response.arrayBuffer();
                const blob = new Blob([arrayBuffer], { type: response.type });
                const imageUrl = URL.createObjectURL(blob);

                images.push(imageUrl);
            }
            else {
                break;
            }

        } catch (error) {
            console.error('No more images.');
            break;
        }
    }

    return images;
}

Explanation

  • The scanDocument function sends a POST request to the RESTful API endpoint /DWTAPI/ScanJobs to start a scanning job. The parameters include the license key, device name, and scanning settings.
  • The getImages function sends a GET request to the RESTful API endpoint /DWTAPI/ScanJobs/{jobId}/NextDocument to fetch scanned images. The images are stored in a blob object and displayed in the image display area.

Rotate Image

Rotate the scanned image by -90 or 90 degrees.

let rotateLeftButton = document.getElementById("rotate-left-button");
rotateLeftButton.onclick = () => {
    let img = document.getElementById('document-image');
    img.src = rotateImage('document-image', -90);
    selectedThumbnail.src = img.src;
}

let rotateRightButton = document.getElementById("rotate-right-button");
rotateRightButton.onclick = () => {
    let img = document.getElementById('document-image');
    img.src = rotateImage('document-image', 90);
    selectedThumbnail.src = img.src;
}

    function rotateImage (imageId, angle) {
    const image = document.getElementById(imageId);
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    const imageWidth = image.naturalWidth;
    const imageHeight = image.naturalHeight;

    // Calculate the new rotation
    let rotation = 0;
    rotation = (rotation   angle) % 360;

    // Adjust canvas size for rotation
    if (rotation === 90 || rotation === -270 || rotation === 270) {
        canvas.width = imageHeight;
        canvas.height = imageWidth;
    } else if (rotation === 180 || rotation === -180) {
        canvas.width = imageWidth;
        canvas.height = imageHeight;
    } else if (rotation === 270 || rotation === -90) {
        canvas.width = imageHeight;
        canvas.height = imageWidth;
    } else {
        canvas.width = imageWidth;
        canvas.height = imageHeight;
    }

    // Clear the canvas
    context.clearRect(0, 0, canvas.width, canvas.height);

    // Draw the rotated image on the canvas
    context.save();
    if (rotation === 90 || rotation === -270) {
        context.translate(canvas.width, 0);
        context.rotate(90 * Math.PI / 180);
    } else if (rotation === 180 || rotation === -180) {
        context.translate(canvas.width, canvas.height);
        context.rotate(180 * Math.PI / 180);
    } else if (rotation === 270 || rotation === -90) {
        context.translate(0, canvas.height);
        context.rotate(270 * Math.PI / 180);
    }
    context.drawImage(image, 0, 0);
    context.restore();

    return canvas.toDataURL();
}

Delete Image

Delete all scanned images, including the main image and thumbnails, and reset the data array.

let deleteButton = document.getElementById("delete-button");
deleteButton.onclick = async () => {
    let img = document.getElementById('document-image');
    img.src = 'images/default.png';
    data = [];
    let thumbnails = document.getElementById("thumb-box");
    thumbnails.innerHTML = '';
}

Step 4: Interop Between C# and JavaScript for Saving Images

Saving images directly in JavaScript is restricted due to security concerns. Therefore, we need to interoperate between C# and JavaScript to accomplish this task.

  1. Create a JavaScript function to convert the scanned image to a base64 string.

    function getBase64Image() {
        var img = document.getElementById('document-image');
        var canvas = document.createElement('canvas');
        canvas.width = img.naturalWidth;
        canvas.height = img.naturalHeight;
        var ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0);
    
        var dataURL = canvas.toDataURL('image/png'); 
        var base64 = dataURL.split(',')[1]; 
        return base64;
    }
    
  2. When clicking the save button, set window.location.href to trigger the OnWebViewNavigated event handler of the WebView control.

    let saveButton = document.getElementById("save-button");
    saveButton.onclick = async () => {
        window.location.href = 'invoke://CallCSharpFunction';    
    }
    
  3. In the OnWebViewNavigated event handler, call EvaluateJavaScriptAsync to retrieve the base64 image data from JavaScript and save it to a file.

    private async void OnWebViewNavigated(object sender, WebNavigatingEventArgs e)
    {
        if (e.Url.StartsWith("invoke://callcsharpfunction"))
        {
            var base64String = await WebView.EvaluateJavaScriptAsync("getBase64Image()");
            CallCSharpFunction(base64String);
        }
    }
    
    private void CallCSharpFunction(string base64String)
    {
        if (!string.IsNullOrEmpty(base64String))
        {
    
            try
            {
                byte[] imageBytes = Convert.FromBase64String(base64String);
    
                var filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), GenerateFilename());
                File.WriteAllBytes(filePath, imageBytes);
                DisplayAlert("Success", "Image saved to: "   filePath, "OK");
    
            }
            catch (Exception ex)
            {
                DisplayAlert("Error", ex.Message, "OK");
            }
        }
        else
        {
            DisplayAlert("Failure", "No image data found", "OK");
        }
    }
    
    private string GenerateFilename()
    {
        DateTime now = DateTime.Now;
        string timestamp = now.ToString("yyyyMMdd_HHmmss");
        return $"image_{timestamp}.png";
    }
    

Note: Do not pass the base64 string directly to the C# function via window.location.href, as the string may be too long and cause an error. Instead, return the base64 string when calling EvaluateJavaScriptAsync from the C# function.

Step 5: Run the .NET MAUI Document Scanner Application

Press F5 in Visual Studio or Visual Studio Code to run the .NET document scanner application on Windows or macOS.

Switching from .NET MAUI Blazor to WebView Control for Document Scanning

Source Code

https://github.com/yushulx/dotnet-twain-wia-sane-scanner/tree/main/examples/MauiWebView

版本声明 本文转载于:https://dev.to/yushulx/switching-from-net-maui-blazor-to-webview-control-for-document-scanning-31lp?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 跨域场景下CORS何时使用预检请求?
    跨域场景下CORS何时使用预检请求?
    CORS:了解跨域请求的“预检”请求跨域资源共享 (CORS) 在制作 HTTP 时提出了挑战跨域请求。为了解决这些限制,引入了预检请求作为解决方法。预检请求说明预检请求是先于实际请求(例如 GET 或 POST)的 OPTIONS 请求)并用于与服务器协商请求的权限。这些请求包括两个附加标头:Ac...
    编程 发布于2024-11-05
  • 如何使用 PHP 的 glob() 函数按扩展名过滤文件?
    如何使用 PHP 的 glob() 函数按扩展名过滤文件?
    在 PHP 中按扩展名过滤文件使用目录时,通常需要根据扩展名检索特定文件。 PHP 提供了一种使用 glob() 函数来完成此任务的有效方法。要按扩展名过滤文件,请使用语法:$files = glob('/path/to/directory/*.extension');例如,要检索目录 /path/...
    编程 发布于2024-11-05
  • 理解 JavaScript 中的 Promise 和 Promise Chaining
    理解 JavaScript 中的 Promise 和 Promise Chaining
    什么是承诺? JavaScript 中的 Promise 就像你对未来做某事的“承诺”。它是一个对象,表示异步任务的最终完成(或失败)及其结果值。简而言之,Promise 充当尚不可用但将来可用的值的占位符。 承诺国家 Promise 可以存在于以下三种状态之一: ...
    编程 发布于2024-11-05
  • 安全分配
    安全分配
    今天,关于 JavaScript 中安全赋值运算符 (?=) 的新提案引起了热烈讨论。我喜欢 JavaScript 随着时间的推移而不断改进,但这也是我最近在一些情况下遇到的问题。我应该将快速示例实现作为函数,对吧? 如果您还没有阅读该提案,以下是其建议: const [error, value] ...
    编程 发布于2024-11-05
  • 创建队列接口
    创建队列接口
    创建字符队列的接口。 需要开发的三个实现: 固定大小的线性队列。 循环队列(复用数组空间)。 动态队列(根据需要增长)。 1 创建一个名为 ICharQ.java 的文件 // 字符队列接口。 公共接口 ICharQ { // 向队列中插入一个字符。 void put(char ch); ...
    编程 发布于2024-11-05
  • Pip 的可编辑模式何时对本地 Python 包开发有用?
    Pip 的可编辑模式何时对本地 Python 包开发有用?
    使用 Pip 在 Python 中利用可编辑模式进行本地包开发在 Python 的包管理生态系统中,Pip 拥有“-e”(或'--editable') 特定场景的选项。什么时候使用这个选项比较有利?答案在于可编辑模式的实现,官方文档中有详细说明:“从本地以可编辑模式安装项目(即 se...
    编程 发布于2024-11-05
  • 当您在浏览器中输入 URL 时会发生什么?
    当您在浏览器中输入 URL 时会发生什么?
    您是否想知道当您在浏览器中输入 URL 并按 Enter 键时幕后会发生什么?该过程比您想象的更加复杂,涉及多个步骤,这些步骤无缝地协同工作以提供您请求的网页。在本文中,我们将探讨从输入 URL 到查看完全加载的网页的整个过程,阐明使这一切成为可能的技术和协议。 第 1 步:输入 U...
    编程 发布于2024-11-05
  • 如何有效管理大量小HashMap对象的“OutOfMemoryError:超出GC开销限制”?
    如何有效管理大量小HashMap对象的“OutOfMemoryError:超出GC开销限制”?
    OutOfMemoryError: Handling Garbage Collection Overhead在Java中,当过多时会出现“java.lang.OutOfMemoryError: GC Overhead limit allowed”错误根据 Sun 的文档,时间花费在垃圾收集上。要解决...
    编程 发布于2024-11-05
  • 为什么在 Python 列表初始化中使用 [[]] * n 时列表会链接在一起?
    为什么在 Python 列表初始化中使用 [[]] * n 时列表会链接在一起?
    使用 [[]] * n 进行列表初始化时的列表链接问题使用 [[]] 初始化列表列表时 n,程序员经常会遇到一个意想不到的问题,即列表似乎链接在一起。出现这种情况是因为 [x]n 语法创建对同一基础列表对象的多个引用,而不是创建不同的列表实例。为了说明该问题,请考虑以下代码:x = [[]] * ...
    编程 发布于2024-11-05
  • Python 变得简单:从初学者到高级 |博客
    Python 变得简单:从初学者到高级 |博客
    Python Course Code Examples This is a Documentation of the python code i used and created , for learning python. Its easy to understand and L...
    编程 发布于2024-11-05
  • 简化 TypeScript 中的类型缩小和防护
    简化 TypeScript 中的类型缩小和防护
    Introduction to Narrowing Concept Typescript documentation explains this topic really well. I am not going to copy and paste the same descrip...
    编程 发布于2024-11-05
  • 何时应该使用 session_unset() 而不是 session_destroy() ,反之亦然?
    何时应该使用 session_unset() 而不是 session_destroy() ,反之亦然?
    理解 PHP 中 session_unset() 和 session_destroy() 的区别PHP 函数 session_unset() 和 session_destroy() 有不同的用途管理会话数据。尽管它们在清除会话变量方面有明显相似之处,但它们具有不同的效果。session_unset(...
    编程 发布于2024-11-05
  • 如何选择在 C++ 中解析 INI 文件的最佳方法?
    如何选择在 C++ 中解析 INI 文件的最佳方法?
    在 C 中解析 INI 文件:各种方法指南在 C 中处理初始化 (INI) 文件时,开发人员经常遇到有效解析这些文件以提取所需信息的挑战。本文探讨了用 C 解析 INI 文件的不同方法,讨论了它们的优点和注意事项。本机 Windows API 函数一种方法是利用 Windows API 函数INI ...
    编程 发布于2024-11-05
  • 代码日:重新聚焦
    代码日:重新聚焦
    2024 年 8 月 19 日星期一 今天是我 100 天编程之旅的一半! ?除了记录我的进步之外,我还喜欢分享学习技巧。我最喜欢的新方法之一是番茄工作法,它需要专注于一项任务 25 分钟,然后休息 5 分钟。四个周期后,您会休息更长的时间。这有助于保持注意力并防止倦怠。 我尝试过 App Stor...
    编程 发布于2024-11-05
  • 为什么我在 Visual Studio 2015 中收到编译器错误 C2280“尝试引用已删除的函数”?
    为什么我在 Visual Studio 2015 中收到编译器错误 C2280“尝试引用已删除的函数”?
    Visual Studio 2015 中编译器错误 C2280“尝试引用已删除的函数”Visual Studio 2015 编译器与其 2013 的前身不同,自动为定义移动构造函数或移动赋值运算符的类生成删除的复制构造函数。 C 标准强制执行此行为,以防止在首选移动的情况下发生意外复制。在您的代码片...
    编程 发布于2024-11-05

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3