使用gitee自动备份文件

需求

舍友磁盘前两天gg了,里面的论文没有本地备份,最后费劲巴拉的在坚果云上找到了很早前的版本。我说可以上传到github,建一个私人仓库就行了,安全性应该有保证,毕竟不是啥学术大亨,不会有人偷你论文。但是他嫌每次写完还得手动操作,能不能写一个自动检测修改的软件,然后修改后就自动上传到github上。

第一反应是,需要word提供的接口,使用观察者模式,从而检测修改,然后通过github的API,开发一个上传文件的软件。但是通过word开发实在是太难了。

然后今天想了想,完全不需要,直接写个定时任务,10分钟检查下是否有文件进行修改就行了。本来就不要求较高的实时性,所以根本用不到观察者模式。

这样的话就有两种选择了,第一通过Java调用git然后进行文件的提交和上传,第二就是自己开发一个类似于git的工具,针对文件的创建,修改和删除进行对应的github仓库修改。

今天的话,是想着使用第二种方式的,确实有点难,用了一下午时间,才完成了文件的上传功能。

使用第二种方式,需要分析:

  • git add .和git commit实现的功能
  • git pull和push实现的功能

使用第一种方式,就简单许多

  • 监听时间
  • 使用jgit进行上传文件

简单设计

  • 监听类 Listenner :负责监听目录/文件等的变化。
  • 上传类 UpLoader : 负责将文件上传到github或者gitee或者其他云盘上
    • GiteeUpLoader
    • GithubUpLoader
    • GitUploader
  • 主类 Main
  • utils类
  • 常量(使用接口),异常,还有配置文件,工具文件等

差不多类似于这样吧,忽略chapter1,这个是之前的项目。

image-20240317212206535

事件监听

Gitee文件上传类

package autoSendFiles.uploaders;

import autoSendFiles.constants.UploadConstants;
import autoSendFiles.exception.NullPropertiesException;

import java.io.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import autoSendFiles.interfaces.Uploader;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

/**
 * @author: Zekun Fu
 * @date: 2024/3/17 12:12
 * @Description: 通过调用git的方式,将文件上传到Gited中
 */
public class GiteeUploader implements Uploader {

    private String accessToken;
    private String username;
    private String repository;
    private String branch;


    public GiteeUploader() throws NullPropertiesException {
        // 读取参数,如果没有配置,抛出异常
        try (InputStream input = new FileInputStream(UploadConstants.APP_PROPERTIES_PATH)) {
            Properties properties = new Properties();

            // 加载 properties 文件
            properties.load(input);

            // 获取属性值
            this.accessToken = properties.getProperty("gitee.accessToken");
            this.username = properties.getProperty("gitee.username");
            this.repository = properties.getProperty("gitee.repository");
            this.branch = properties.getProperty("gitee.branch");
            if (StringUtils.isAnyEmpty(accessToken, username, repository, branch))
                throw new NullPropertiesException("未配置Gitee属性,请先配置!");
        } catch (IOException e) {
            System.out.println("系统异常!请联系管理员");
            e.printStackTrace();
        }
    }

    public List<File> upload(List<File> files) {
        return uploadHelper(files);
    }

    private List<File> uploadHelper(List<File>files) {
        List<File>failUploadFiles = new ArrayList<>();
        for (File file : files) {
            // 如果没有上传成功,需要放入到传输失败列表中
            try {
                if (!upload(file))
                    failUploadFiles.add(file);
            } catch (IOException e) {
                failUploadFiles.addAll(files);
                e.printStackTrace();
            }
        }
        return failUploadFiles;
    }
    private boolean upload(File file) throws IOException {
        // 生成路径,提交信息,以及提交文件的base64编码
        String savePath = getSavePath(file);
        String message = generatorSendMessage();
        String content = this.fileBase64(file);

        // 创建 http 客户端
        String apiUrl = String.format(UploadConstants.UPLOAT_URL, this.username, this.repository, savePath);
        OkHttpClient client = new OkHttpClient();

        // 创建请求体
        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart(UploadConstants.ACCESS_TOKEN, this.accessToken)
                .addFormDataPart(UploadConstants.CONTENT, content)
                .addFormDataPart(UploadConstants.MESSAGE, message)
                .addFormDataPart(UploadConstants.BRANCH, this.branch)
                .build();

        // 创建 http 请求
        Request request = new Request.Builder()
                .url(apiUrl)
                .post(requestBody)
                .build();

        // 接收响应
        Response response = client.newCall(request).execute();

        // 上传
        if (response.isSuccessful()) {
            System.out.println("文件上传成功!");
            return true;
        } else {
            System.out.println("文件上传失败:" + response.code() + " " + response.message());
            return false;
        }
    }

    private String generatorSendMessage() {
        LocalDateTime currentDateTime = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
        String formattedDateTime = currentDateTime.format(formatter);
        String msg = formattedDateTime + "提交";
        return msg;
    }

    private String fileBase64(File file) throws IOException {
        return Base64.getEncoder().encodeToString(fileToByteArray(file));
    }
    private byte[] fileToByteArray(File file) throws IOException {
        byte[] data = new byte[(int) file.length()];
        try (FileInputStream fis = new FileInputStream(file)) {
            fis.read(data);
        }
        return data;
    }
    /**
     * @return 生成路径, 如果为空,说明生成错了,没有.git文件夹
     * */
    private String getSavePath(File file) {
        StringBuffer savePath = new StringBuffer();
        return UploadConstants.DIR_SPLIT + findGitDirectory(file, savePath);
    }
    /**
     * @return 递归获取路径,直到碰到.git为止
     * */
    private String findGitDirectory(File directory, StringBuffer savePath) {
        StringBuffer curPath = new StringBuffer(directory.getName());
        if (!StringUtils.isEmpty(savePath)) curPath.append(UploadConstants.DIR_SPLIT).append(savePath);
        File gitDirectory = new File(directory, UploadConstants.ROOT_DIR);
        if (gitDirectory.exists() && gitDirectory.isDirectory()) {
            return savePath.toString();
        } else {
            File parentDirectory = directory.getParentFile();
            if (parentDirectory != null) {
                return findGitDirectory(parentDirectory, curPath);
            } else {
                return null;
            }
        }
    }

    public static void testGenerateSendMesage(GiteeUploader uploader) {
        System.out.println("提交msg为:" + uploader.generatorSendMessage());
    }

    public static void testGetPath(GiteeUploader uploader, File file) {
        // 1. 如果不包含.git文件
        // 2. Linux的和windows的分隔符不一样
        // 3. 其他特殊情况
        String filePath = uploader.getSavePath(file);
        if (!StringUtils.isEmpty(filePath)) {
            System.out.println("当前的保存路径为:" + filePath);
        }
        else System.out.println("测试失败,无法获取当前文件的路径");
    }

    public static GiteeUploader testCreateUploader() throws IOException, NullPropertiesException{
        GiteeUploader uploader = new GiteeUploader();
        return uploader;
    }

    public static void testBase64(GiteeUploader uploader, File file) throws IOException {
        String content = uploader.fileBase64(file);
        if (StringUtils.isEmpty(content)) {
            System.out.println("base64编码后的内容为空!");
            return ;
        }
        System.out.println("base64编码后的内容为:" + content);
    }

    public static void testUpLoad() throws IOException, NullPropertiesException {
        String FilePath = "D:\\learning\\论文\\毕业论文\\毕业论文备份\\test.txt";
        GiteeUploader uploader = new GiteeUploader();
        File file = new File(FilePath);
        uploader.upload(new File(FilePath));
    }

    public static void test() throws NullPropertiesException, IOException {
        System.out.println("测试开始...");
        String FilePath = "D:\\learning\\论文\\毕业论文\\毕业论文备份\\test.txt";
        GiteeUploader uploader = testCreateUploader();
        testGenerateSendMesage(uploader);
        File file = new File(FilePath);
        testGetPath(uploader, file);
        testBase64(uploader, file);
        testUpLoad();
        System.out.println("测试完成...");
    }


    public static void main(String[] args) throws NullPropertiesException, IOException{
        test();
    }
}

定时监听

项目架构

image-20240317234653713

运行效果

image-20240317234741826

运行结果:固定时间进行扫描提交

image-20240317235255019

时间监听器

package autoSendFiles.Listener;

import autoSendFiles.constants.ApplicationConstants;
import autoSendFiles.constants.PropertyConstants;
import autoSendFiles.interfaces.Listenner;
import autoSendFiles.interfaces.Uploader;
import autoSendFiles.utils.AppPropertiesUtils;

/**
 * @author: Zekun Fu
 * @date: 2024/3/17 23:02
 * @Description:
 */
public class TimeListenner implements Listenner, Runnable{
    private Thread thread;
    private Uploader uploader;
    private int listenTime;
    public TimeListenner(Uploader uploader) {
        this.uploader = uploader;
        this.listenTime = Integer.parseInt(AppPropertiesUtils.getProperty(PropertyConstants.LISTEN_TIME));
    }

    @Override
    public void run() {
        System.out.println("线程监听开始...");
        while (true) {
            if (this.thread.isInterrupted()) {
                // 实际结束线程的地方
                break;
            }
            try {

                // 上传修改的文件
                System.out.println("同步中...");
                this.uploader.uploadAllChanges();
                System.out.println("同步完成...");

                // 睡眠
                Thread.sleep(ApplicationConstants.TO_SECONDS * this.listenTime);

            } catch (InterruptedException e) {
                // 这里处理善后工作

                // 重新进行标记,从而可以结束线程
                this.thread.interrupt();
            }
        }
    }

    @Override
    public void listen() {
        // 开启线程进行监听
        System.out.println("开启新线程,启动监听...");
        this.thread = new Thread(this);
        thread.start();
    }

    public void stop() {
        this.thread.interrupt();
    }
}

主线程

package autoSendFiles;

import autoSendFiles.Listener.TimeListenner;
import autoSendFiles.constants.ApplicationConstants;
import autoSendFiles.constants.PropertyConstants;
import autoSendFiles.exception.NullPropertiesException;
import autoSendFiles.interfaces.Uploader;
import autoSendFiles.uploaders.GitUploader;
import autoSendFiles.utils.AppPropertiesUtils;

import javax.imageio.IIOException;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: Zekun Fu
 * @date: 2024/3/17 12:12
 * @Description:
 */
public class Main {

    public static void main(String[] args) throws NullPropertiesException, IIOException {
        Uploader uploader = new GitUploader();
        TimeListenner listenner = new TimeListenner(uploader);
        listenner.listen();
        try {
            int times = Integer.parseInt(AppPropertiesUtils.getProperty(PropertyConstants.RUN_TIME));
            Thread.sleep(times * ApplicationConstants.TEN_MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 100min后结束
        listenner.stop();
    }
}

Git上传器

package autoSendFiles.uploaders;

import autoSendFiles.constants.ApplicationConstants;
import autoSendFiles.constants.PropertyConstants;
import autoSendFiles.constants.UploadConstants;
import autoSendFiles.exception.NullPropertiesException;
import autoSendFiles.interfaces.Uploader;
import autoSendFiles.utils.AppPropertiesUtils;
import autoSendFiles.utils.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jgit.api.AddCommand;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.jgit.util.IO;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: Zekun Fu
 * @date: 2024/3/17 22:20
 * @Description: 静态常量设计的不行! gitee和github的不分了。
 * 重新开启一个文件叫做参数常量文件就行了。
 */
public class GitUploader implements Uploader {
    private String workDir;
    private String remoteName;
    private String branch;
    private String password;
    private String username;
    public GitUploader() throws NullPropertiesException {
        workDir = AppPropertiesUtils.getProperty(PropertyConstants.WORK_DIR);
        remoteName = AppPropertiesUtils.getProperty(PropertyConstants.GITEE_REMOTE_NAME);
        branch = AppPropertiesUtils.getProperty(PropertyConstants.GITEE_BRANCH);
        password = AppPropertiesUtils.getProperty(PropertyConstants.GITEE_PASSWORD);
        username =AppPropertiesUtils.getProperty(PropertyConstants.GITEE_USERNAME);
        if (StringUtils.isAnyEmpty(workDir, remoteName, branch, password)) {
            throw new NullPropertiesException("没有配置工作文件夹,检查配置文件!");
        }
    }

    @Override
    public List<File> upload(List<File> files) {
        List<File>failList = this.uploadHelper(files);
        this.commit();
        this.push();
        return failList;
    }

    @Override
    public void uploadAllChanges() {
        this.pushAllChanges();
    }

    /**
     * 完成所有修改文件的同步
     * */
    private void pushAllChanges() {
        this.addAll();
        this.commit();
        this.push();
    }

    public boolean add(String filePath) {
        try (Git git = Git.open(new File(this.workDir))) {
            AddCommand addCommand = git.add();
            addCommand.addFilepattern(filePath);
            addCommand.call();
            System.out.println(filePath + " 添加完成。");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public void addAll() {
        try (Git git = Git.open(new File(this.workDir))) {
            AddCommand addCommand = git.add();
            addCommand.addFilepattern(".");
            addCommand.call();

            System.out.println("Git add . 操作完成。");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void commit() {
        try (Git git = Git.open(new File(this.workDir))) {
            CommitCommand commitCommand = git.commit();
            commitCommand.setMessage(this.getCommitMessage());
            commitCommand.call();
            System.out.println("Git commit 操作完成。");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void commit(String msg) {
        try (Git git = Git.open(new File(this.workDir))) {
            CommitCommand commitCommand = git.commit();
            commitCommand.setMessage(msg);
            commitCommand.call();
            System.out.println("Git commit 操作完成。");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void push() {
        try (Git git = Git.open(new File(this.workDir))) {
            PushCommand pushCommand = git.push();
            pushCommand.setRemote(remoteName);
            pushCommand.setRefSpecs(new RefSpec(this.branch));
            // 用户密码验证
            CredentialsProvider credentialsProvider = new UsernamePasswordCredentialsProvider(this.username, this.password);
            pushCommand.setCredentialsProvider(credentialsProvider);
            pushCommand.call();

            System.out.println("Git push 操作完成。");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private List<File>uploadHelper(List<File> files) {
        List<File>failedFile = new ArrayList<>();
        for (File f : files) {
            if (!this.add(f.getName()))
                failedFile.add(f);
        }
        return failedFile;
    }
    private String getCommitMessage() {
        return DateUtils.getCurTime(ApplicationConstants.MIN_PATTERN) + "提交";
    }

    public static void testGitUploader() throws IOException, NullPropertiesException {
        Uploader uploader = new GitUploader();
        List<File> fileList = new ArrayList<>();
        String[] filePathList = {"D:\\projects\\java\\projects\\autoCommit\\test3.txt", "D:\\projects\\java\\projects\\autoCommit\\test4.txt"};
        for (String filePath : filePathList) {
            fileList.add(new File(filePath));
        }
        List<File>failedFiles = uploader.upload(fileList);
        if (failedFiles.size() != 0) {
            System.out.println("上传失败的文件有:");
            for (File file : failedFiles) {
                System.out.println(file.getName());
            }
        }
    }

    public static void main(String[] args) throws NullPropertiesException , IOException{
//        new GitUploader().push();
        GitUploader uploader = new GitUploader();
        uploader.add("test3.txt");
    }
}

工具文件

package autoSendFiles.utils;

import autoSendFiles.constants.UploadConstants;
import autoSendFiles.exception.NullPropertiesException;
import org.apache.commons.lang3.StringUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * @author: Zekun Fu
 * @date: 2024/3/17 21:50
 * @Description:
 */
public class AppPropertiesUtils {
    private static Properties properties = new Properties();
    static {
        // 读取参数,如果没有配置,抛出异常
        try (InputStream input = new FileInputStream(UploadConstants.APP_PROPERTIES_PATH)) {
            // 加载 properties 文件
            properties.load(input);
        } catch (IOException e) {
            System.out.println("系统异常!请联系管理员");
            e.printStackTrace();
        }
    }
    public static String getProperty(String key) {
        return properties.getProperty(key);
    }
}

package autoSendFiles.utils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author: Zekun Fu
 * @date: 2024/3/17 21:43
 * @Description:
 */
public class DateUtils {
    public static String getCurTime(String pattern) {
        LocalDateTime currentDateTime = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return currentDateTime.format(formatter);
    }
}

配置文件

# gitee配置
gitee.accessToken=你的口令
gitee.branch=本地分支
gitee.username=用户名
gitee.password=密码
gitee.repository=仓库
gitee.remoteName=远程分成

# 监听的git路径
work.dir=D:/projects/java/projects/autoCommit

# 监听的时间间隔10min
listen.time=10

# 程序运行时间100min
run.time=100

常量文件

package autoSendFiles.constants;

/**
 * @author: Zekun Fu
 * @date: 2024/3/17 21:45
 * @Description:
 */
public interface ApplicationConstants {
    String MIN_PATTERN = "yyyy/MM/dd HH:mm";
    int TEN_MINUTES = 1000 * 60 * 10;
    int TWENTY_MINUTES = 1000 * 60 * 20;
    int TO_SECONDS = 1000;
    int TO_MIMUTES = 1000 * 60;
}

package autoSendFiles.constants;

/**
 * @author: Zekun Fu
 * @date: 2024/3/17 22:39
 * @Description: 配置Key的常量
 */
public interface PropertyConstants {
    String GITEE_BRANCH = "gitee.branch";
    String GITEE_REMOTE_NAME="gitee.remoteName";
    String WORK_DIR = "work.dir";
    String GITEE_PASSWORD = "gitee.password";
    String GITEE_USERNAME = "gitee.username";
    String LISTEN_TIME = "listen.time";
    String RUN_TIME = "run.time";
}

package autoSendFiles.constants;

/**
 * @author: Zekun Fu
 * @date: 2024/3/17 20:01
 * @Description:
 */
public interface UploadConstants {
    String UPLOAT_URL = "https://gitee.com/api/v5/repos/%s/%s/contents/%s";
    String ACCESS_TOKEN = "access_token";
    String CONTENT = "content";
    String MESSAGE = "message";
    String BRANCH = "branch";
    String ROOT_DIR = ".git";
    String DIR_SPLIT = "/";
    String APP_PROPERTIES_PATH = "src/main/resources/application.properties";
}

异常类

package autoSendFiles.exception;

/**
 * @author: Zekun Fu
 * @date: 2024/3/17 18:18
 * @Description:
 */
public class NullPropertiesException extends Exception{
    public NullPropertiesException(String msg) {
        super(msg);
    }
}

maven依赖

  <dependencies>
        <!-- Apache HttpClient Core -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.13</version>
        </dependency>

        <!-- Apache HttpClient Mime -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.5.13</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.9.3</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jgit</groupId>
            <artifactId>org.eclipse.jgit</artifactId>
            <version>5.13.0.202109080827-r</version>
        </dependency>
    </dependencies>

总结

  • 没有实现事件监听器,可以通过listenner进行扩展
  • 文件上传器,接口设计的不好,应该单一职责,这里两个职责了。一个是上传文件,一个是上传所有变化的文件
  • 没有实现图像化结面

下一步

  • 实现git pull的功能,进行文件的覆盖
  • 实现事件监听功能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/465026.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从JVM的退出机制分析Java程序的优雅关闭退出

前言 Java程序启动从main函数开始启动&#xff0c;是程序入口和主线程&#xff0c;但程序会在什么时候结束&#xff1f;为什么有的Java程序在启动后很快就结束了&#xff0c;比如HelloWorld程序&#xff0c;有的程序却能一直在运行&#xff0c;比如Tomcat启动后就一直保持进程…

AI:149-法律电子邮件图像中的欺诈检测与敲诈勒索追踪—深度学习技术

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带关键代码,详细讲解供大家学习,希望…

JSONP漏洞详解

目录 同源策略 JSONP简介 JSONP劫持漏洞 漏洞原理 漏洞利用过程 利用工具 JSONP漏洞挖掘思路 JSONP防御 首先&#xff0c;要了解一下什么是同源策略&#xff1f; 同源策略 同源策略&#xff08;SOP&#xff09;是浏览器的一个安全基石&#xff0c;浏览器为了保证数据…

AI系统性学习01- Prompt Engineering

文章目录 面向开发者的Prompt Engineering一、简介二、Prompt设计原则1 环境配置2.两个基本原则2.1 原则1&#xff1a;编写清晰、具体的指令2.1.1 策略一&#xff1a;分割2.1.2 策略2&#xff1a;结构化输出2.1.3 策略3&#xff1a;模型检测2.1.4 策略4&#xff1a;提供示例 2.…

[数据集][目标检测]焊接件表面缺陷检测数据集VOC+YOLO格式2292张10类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2292 标注数量(xml文件个数)&#xff1a;2292 标注数量(txt文件个数)&#xff1a;2292 标注…

【GPT-SOVITS-03】SOVITS 模块-生成模型解析

说明&#xff1a;该系列文章从本人知乎账号迁入&#xff0c;主要原因是知乎图片附件过于模糊。 知乎专栏地址&#xff1a; 语音生成专栏 系列文章地址&#xff1a; 【GPT-SOVITS-01】源码梳理 【GPT-SOVITS-02】GPT模块解析 【GPT-SOVITS-03】SOVITS 模块-生成模型解析 【G…

【PyTorch】进阶学习:一文详细介绍 torch.load() 的应用场景、实战代码示例

【PyTorch】进阶学习&#xff1a;一文详细介绍 torch.load() 的应用场景、实战代码示例 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程…

栈和队列(Java实现)

栈和队列&#xff08;Java实现&#xff09; 栈 栈(Stack)&#xff1a;栈是先进后出&#xff08;FILO, First In Last Out&#xff09;的数据结构。Java中实现栈有以下两种方式&#xff1a; stack类LinkedList实现&#xff08;继承了Deque接口&#xff09; &#xff08;1&am…

Python基础算法解析:支持向量机(SVM)

支持向量机&#xff08;Support Vector Machine&#xff0c;SVM&#xff09;是一种用于分类和回归分析的机器学习算法&#xff0c;它通过在特征空间中找到一个最优的超平面来进行分类。本文将详细介绍支持向量机的原理、实现步骤以及如何使用Python进行编程实践。 什么是支持向…

【Java刷题篇】串联所有单词的子串

这里写目录标题 &#x1f4c3;1.题目&#x1f4dc;2.分析题目&#x1f4dc;3.算法原理&#x1f9e0;4.思路叙述✍1.进窗口✍2.判断有效个数✍3.维护窗口✍4.出窗口 &#x1f4a5;5.完整代码 &#x1f4c3;1.题目 力扣链接: 串联所有单词的子串 &#x1f4dc;2.分析题目 阅…

2.vscode 配置python开发环境

vscode用着习惯了,也不想再装别的ide 1.安装vscode 这一步默认已完成 2.安装插件 搜索插件安装 3.选择调试器 Ctrl Shift P&#xff08;或F1&#xff09;&#xff0c;在打开的输入框中输入 Python: Select Interpreter 搜索&#xff0c;选择 Python 解析器 选择自己安…

vulhub中GitLab 远程命令执行漏洞复现(CVE-2021-22205)

GitLab是一款Ruby开发的Git项目管理平台。在11.9以后的GitLab中&#xff0c;因为使用了图片处理工具ExifTool而受到漏洞CVE-2021-22204的影响&#xff0c;攻击者可以通过一个未授权的接口上传一张恶意构造的图片&#xff0c;进而在GitLab服务器上执行任意命令。 环境启动后&am…

深度学习1650ti在win10安装pytorch复盘

深度学习1650ti在win10安装pytorch复盘 前言1. 安装anaconda2. 检查更新显卡驱动3. 根据pytorch选择CUDA版本4. 安装CUDA5. 安装cuDNN6. conda安装pytorch结语 前言 建议有条件的&#xff0c;可以在安装过程中&#xff0c;开启梯子。例如cuDNN安装时登录 or 注册&#xff0c;会…

安卓国产百度网盘与国外云盘软件onedrive对比

我更愿意使用国外软件公司的产品&#xff0c;而不是使用国内百度等制作的流氓软件。使用这些国产软件让我不放心&#xff0c;他们占用我的设备大量空间&#xff0c;在我的设备上推送运行各种无用的垃圾功能。瞒着我&#xff0c;做一些我不知道的事情。 百度网盘安装包大小&…

鸿蒙Next 支持数据双向绑定的组件:Checkbox--Search--TextInput

Checkbox $$语法&#xff0c;$$绑定的变量发生变化时&#xff0c;会触发UI的刷新 Entry Component struct MvvmCase { State isMarry:boolean falseStatesearchText:string build() {Grid(){GridItem(){Column(){Text("checkbox 的双向绑定")Checkbox().select($$…

【PyTorch】基础学习:一文详细介绍 torch.save() 的用法和应用

【PyTorch】基础学习&#xff1a;一文详细介绍 torch.save() 的用法和应用 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f44…

ioDraw:与 GitHub、gitee、gitlab、OneDrive 无缝对接,绘图文件永不丢失!

&#x1f31f; 绘图神器 ioDraw 重磅更新&#xff0c;文件保存再无忧&#xff01;&#x1f389; 无需注册&#xff0c;即刻畅绘&#xff01;✨ ioDraw 让你告别繁琐注册&#xff0c;尽情挥洒灵感&#xff01; 新增文件在线实时保存功能&#xff0c;支持将绘图文件保存到 GitHu…

【HarmonyOS】ArkUI - 向左/向右滑动删除

核心知识点&#xff1a;List容器 -> ListItem -> swipeAction 先看效果图&#xff1a; 代码实现&#xff1a; // 任务类 class Task {static id: number 1// 任务名称name: string 任务${Task.id}// 任务状态finished: boolean false }// 统一的卡片样式 Styles func…

机电公司管理小程序|基于微信小程序的机电公司管理小程序设计与实现(源码+数据库+文档)

机电公司管理小程序目录 目录 基于微信小程序的机电公司管理小程序设计与实现 一、前言 二、系统设计 三、系统功能设计 1、机电设备管理 2、机电零件管理 3、公告管理 4、公告类型管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八…

【LabVIEW FPGA入门】定时

在本节学习使用循环计时器来设置FPGA循环速率&#xff0c;等待来添加事件之间的延迟&#xff0c;以及Tick Count来对FPGA代码进行基准测试。 1.定时快捷VI函数 在FPGA VI中放置的每个VI或函数都需要一定的时间来执行。您可以允许操作以数据流确定的速率发生&#xff0c;而无需额…