【Hadoop】HDFS API 操作大全

news2025/1/11 21:52:41

🍁 博主 "开着拖拉机回家"带您 Go to New World.✨🍁

🦄 个人主页——🎐开着拖拉机回家_Linux,大数据运维-CSDN博客 🎐✨🍁

🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批评指正!🍁🐥

🪁🍁🪁🍁🪁🍁🪁🍁 🪁🍁🪁🍁🪁🍁🪁 🪁🍁🪁🍁🪁🍁🪁🍁🪁🍁🪁🍁

🍁🪁🍁 🪁🍁🪁🍁感谢点赞和关注 ,每天进步一点点!加油!🍁🪁🍁 🪁🍁🪁🍁

目录

🍁 博主 "开着拖拉机回家"带您 Go to New World.✨🍁

一、FileSystem文件抽象类

1.1文件读取API

1.2文件操作API

1.3抽象FileSystem类的具体实现子类

1.4FileSystem IO输入系统相关类

1.5FileSystem IO输出系统相关类

二、HDFS的API操作

2.1测试集群版本信息

2.2文件上传下载和移动

2.3文件读写操作

2.4文件状态信息获取

2.5实战案例


一、FileSystem文件抽象类


为了提供对不同数据访问的一致接口,Hadoop借鉴了Linux虚拟文件系统的概念,为此Hadopo提供了一个抽象的文件系统模型FileSystem,HDFS 是其中的一个实现。

FileSystem是Hadoop中所有文件系统的抽象父类,它定义了文件系统所具有的基本特征和基本操作。

1.1文件读取API


HadoopFileSystem操作

Java操作

Linux操作

描述

URL.openStream

FileSystem.open

FileSystem.create

FileSystem.append

URL.openStream

open

打开一个文件

FSDataInputStream.read

InputStream.read

read

读取文件中的数据

FSDataInputStream.write

OutputStream.write

write

向文件中写入数据

FSDataInputStream.close

FSDataOutputStream.close

InputStream.close

OutputStream.close

close

关闭一个文件

FSDataInputStream.seek

RandomAccessFile.seek

lseek

改变文件读写位置

FileSystem.getContentSummary

du/wc

获取文件存储信息

1.2文件操作API


HadoopFileSystem操作

Java操作

Linux操作

描述

FileSystem.getFileStatus

FileSystem.get*

File.get*

stat

获取文件/目录的属性

FileSystem.set*

File.set*

chomd

修改文件属性

FileSystem.createNewFile

File.createNewFile

create

创建一个文件

FileSystem.delete

File.delete

remove

删除一个文件

FileSystem.rename

File.renameTo

rename

移动或先修改文件/目录名

FileSystem.mkdirs

File.mkdir

mkdir

创建目录

FileSystem.delete

File.delete

rmdir

从一个目录下删除一个子目录

FileSystem.listStatus

File.list

readdir

读取一个目录下的项目

FileSystem.setWorkingDirectory

getcwd/getwd

返回当前工作目录

FileSystem.setWorkingDirectory

chdir

更改当前的工作目录

1.3抽象FileSystem类的具体实现子类


1.4FileSystem IO输入系统相关类


1.5FileSystem IO输出系统相关类



二、HDFS的API操作


2.1测试集群版本信息

2.2文件上传下载和移动

/**
   * 本地文件上传到 HDFS
   *
   * @param srcPath  本地路径 + 文件名
   * @param dstPath  Hadoop路径
   * @param fileName 文件名
   */
def copyToHDFS(srcPath: String, dstPath: String, fileName: String): Boolean = {
  var path = new Path(dstPath)
  val fileSystem: FileSystem = path.getFileSystem(conf)
  val isFile = new File(srcPath).isFile
  // 判断路径是否存在
  val existDstPath: Boolean = fileSystem.exists(path)
  if (!existDstPath) {
    fileSystem.mkdirs(path)
  }
  // 本地文件存在
  if (isFile) {
    // HDFS 采用 路径+ 文件名
    path = new Path(dstPath + File.separator + fileName)
    // false: 是否删除 目标文件,false: 不覆盖
    fileSystem.copyFromLocalFile(false, false, new Path(srcPath), path)
    return true
  }
  false
}


/**
   * Hadoop文件下载到本地
   *
   * @param srcPath hadoop 源文件
   * @param dstPath 目标文件
   * @param fs      文件访问对象
   */
def downLoadFromHDFS(srcPath: String, dstPath: String, fs: FileSystem): Unit = {
  val srcPathHDFS = new Path(srcPath)
  val dstPathLocal = new Path(dstPath)
  // false: 不删除源文件
  fs.copyToLocalFile(false, srcPathHDFS, dstPathLocal)
}

/**
   * 检查Hadoop文件是否存在并删除
   *
   * @param path  HDFS文件
   */
def checkFileAndDelete(path: String, fs: FileSystem) = {
  val dstPath: Path = new Path(path)
  if (fs.exists(dstPath)) {
    // false: 是否递归删除,否
    fs.delete(dstPath, false)
  }
}

  /**
   * 获取指定目录下,正则匹配后的文件列表
   *
   * @param dirPath   hdfs路径
   * @param regexRule 正则表达式 ,如:"^(?!.*[.]tmp$).*$" ,匹配非 .tmp结尾的文件
   */
  def listStatusHDFS(dirPath: String, regexRule: String, fs: FileSystem): util.ArrayList[Path] = {
    val path = new Path(dirPath)
    val pattern: Pattern = Pattern.compile(regexRule)
    // 匹配的文件
    val fileList = new util.ArrayList[Path]()
    val fileStatusArray: Array[FileStatus] = fs.listStatus(path)
    for (fileStatus <- fileStatusArray) {
      // 文件 全路径
      val filePath: Path = fileStatus.getPath()
      val fileName: String = filePath.getName.toLowerCase
      if (regexRule.equals("")) {
        // 如果匹配规则为空 则获取目录下的全部文件
        fileList.add(filePath)
        log.info("match file : " + fileName)
      } else {
        // 正则匹配文件
        if (pattern.matcher(fileName).matches()) {
          fileList.add(filePath)
          log.info("match file : " + fileName)
        }
      }
    }
    fileList
}


/**
 * 文件移动或重命名到指定目录, 如:文件00000 重命名为00001
 *
 * @param srcPath 源文件路径
 * @param dstPath 源文件路径
 * @param fs      文件操作对象
 */
def renameToHDFS(srcPath: String, dstPath: String, fs: FileSystem): Boolean = {
    var renameFlag = false
    val targetPath = new Path(dstPath)
    // 目标文件存在先删除
    if (fs.exists(targetPath)) {
      fs.delete(targetPath, false)
    }
    renameFlag = fs.rename(new Path(srcPath), targetPath)
    if (renameFlag) {
      log.info("renamed file " + srcPath + " to " + targetPath + " success!")
    } else {
      log.info("renamed file " + srcPath + " to " + targetPath + " failed!")
    }
    renameFlag
}

2.3文件读写操作


Hadoop抽象文件系统也是使用流机制进行文件的读写。Hadoop抽象文件系统中,用于读文件数据的流是FSDataInputStream,对应地,写文件通过抽象类FSDataOutputStream实现。


/**
   * 读取HDFS文件
   *
   * @param inPutFilePath 源文件路径
   * @param fs            文件操作对象
   */
def readFromHDFS(inPutFilePath: String, OutputFilePath: String, fs: FileSystem) = {
  var fSDataInputStream: FSDataInputStream = null
  var bufferedReader: BufferedReader = null
  val srcPath = new Path(inPutFilePath)
  if (fs.exists(srcPath)) {
    val fileStatuses: Array[FileStatus] = fs.listStatus(srcPath)
    for (fileStatus <- fileStatuses) {
      val filePath: Path = fileStatus.getPath
      // 判断文件大小
      if (fs.getContentSummary(filePath).getLength > 0) {
        fSDataInputStream = fs.open(filePath)
        bufferedReader = new BufferedReader(new InputStreamReader(fSDataInputStream))

        var line = bufferedReader.readLine()
        while (line != null) {
          print(line + "\n") // 打印
          line = bufferedReader.readLine()
        }
      }
    }
  }
  fSDataInputStream.close()
  bufferedReader.close()
}

/**
   * 读取HDFS文件, 处理完成 重新写入
   *
   * @param inPutFilePath 源文件路径
   * @param OutputFilePath 输出文件到新路径
   * @param fs            文件操作对象
   */
def writeToHDFS(inPutFilePath: String, OutputFilePath: String, fs: FileSystem) = {
  var fSDataInputStream: FSDataInputStream = null
  var fSDataOutputStream: FSDataOutputStream = null
  var bufferedReader: BufferedReader = null
  var bufferedWriter: BufferedWriter = null
  val srcPath = new Path(inPutFilePath)
  var count = 0
  if (fs.exists(srcPath)) {
    val fileStatuses: Array[FileStatus] = fs.listStatus(srcPath)
    for (fileStatus <- fileStatuses) {
      val filePath: Path = fileStatus.getPath
      // 判断文件大小
      if (fs.getContentSummary(filePath).getLength > 0) {
        fSDataInputStream = fs.open(filePath)
        bufferedReader = new BufferedReader(new InputStreamReader(fSDataInputStream))
        val outputFilePath = new Path(OutputFilePath + count)

        fSDataOutputStream = fs.create(outputFilePath)
        bufferedWriter = new BufferedWriter(new OutputStreamWriter(fSDataOutputStream, "UTF-8"))
        var line = bufferedReader.readLine()
        while (line != null) {
          val bytes: Array[Byte] = line.getBytes("UTF-8")
          bufferedWriter.write(new String(bytes) + "\n")
          line = bufferedReader.readLine()
        }
        bufferedWriter.flush()
        count += 1
      }
    }
  }
  fSDataInputStream.close()
  bufferedReader.close()
  bufferedWriter.close()
}

测试结果如下:

2.4文件状态信息获取


FileSystem. getContentSummary()提供了类似Linux命令du、df提供的功能。du表示"disk usage",它会报告特定的文件和每个子目录所使用的磁盘空间大小;命令df则是"diskfree"的缩写,用于显示文件系统上已用的和可用的磁盘空间的大小。du、df是Linux中查看磁盘和文件系统状态的重要工具。

getContentSummary()方法的输入是一个文件或目录的路径,输出是该文件或目录的一些存储空间信息,这些信息定义在ContentSummary,包括文件大小、文件数、目录数、文件配额,已使用空间和已使用文件配额等。

 /**
   * HDFS路径下文件信息统计
   *
   * @param dirPath hdfs路径
   **/
  def listHDFSStatus(dirPath: String, fs: FileSystem) = {
    val path = new Path(dirPath)
    // 匹配的文件
    val contentSummary: ContentSummary = fs.getContentSummary(path)
    println("/tmp/kangll 目录下子目录个数: ", contentSummary.getDirectoryCount)
    println("/tmp/kangll 目录下文件个数: ", contentSummary.getFileCount)
    println("/tmp/kangll 目录下文件大小: ", contentSummary.getLength)
    println("/tmp/kangll 目录下文件和子目录个数: ", contentSummary.getFileAndDirectoryCount)

  }

/tmp/kangll目录信息获取结果:

2.5实战案例


案例说明: HDFS 文件清理, 根据文件大小、个数、程序休眠时间控制 匀速 批量删除 HDFS 文件,当文件越大 ,需要配置 删除个数更少,休眠时间更长,防止 NameNode 负载过大,减轻DataNode磁盘读写压力,从而不影响线上业务情况下清理过期数据。

package com.kangll.common.utils

import java.text.SimpleDateFormat
import java.util.concurrent.TimeUnit
import java.util.{Calendar, Date, Properties}
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.{ContentSummary, FileStatus, FileSystem, Path}
import org.apache.log4j.Logger

import scala.collection.mutable.ListBuffer

/** ***************************************************************************************
 *
 * @auther kangll                               
 * @date 2023/09/12 12:10                                  
 * @desc HDFS 文件清理, 根据文件大小、个数、程序休眠时间控制 匀速 批量删除
 *       HDFS 文件,当文件越大 ,需要配置 删除个数更少,休眠时间更长,防止
 *       NameNode 负载过大,减轻DataNode磁盘读写压力,从而不影响线上业务下删除
 *
 *
 *       1.遍历文件夹下的文件个数据, 当遍历的文件夹下的文件个数到达阈值时 将
 *        文件所述的 父路径直接删除
 *
 * ****************************************************************************************/
object CleanHDFSFileUtil {

  // 删除文件总数统计
  var HDFS_FILE_SUM = 0
  // 批次删除文件个数显示
  var HDFS_FILE_BATCH_DEL_NUM = 0
  val start = System.currentTimeMillis()

  /**
   *
   * @param fs             文件操作对象
   * @param pathName       文件根路径
   * @param fileList       批次清理的 buffer
   * @param saveDay        根据文件属性 获取文件创建时间  选择文件保留最近的天数
   * @param sleepTime      休眠时间,防止一次性删除太多文件  导致 datanode 文件负载太大
   * @param fileBatchCount 批次删除文件的个数, 相当于是 上报到 namenode 文件清理队列的大小,参数越大 队列越大,datanode 磁盘负载相对来说就高
   * @return
   */
  def listPath(fs: FileSystem, pathName: String, fileList: ListBuffer[String], saveDay: Int, sleepTime: Long, fileBatchCount: Int): ListBuffer[String] = {
    val fm = new SimpleDateFormat("yyyy-MM-dd")
    // 获取当前时间
    val currentDay = fm.format(new Date())
    val dnow = fm.parse(currentDay)
    val call = Calendar.getInstance()
    call.setTime(dnow)
    call.add(Calendar.DATE, -saveDay)
    // 获取保留天前的时期
    val saveDayDate = call.getTime
    // 遍历文件
    val fileStatuses = fs.listStatus(new Path(pathName))

    for (status <- fileStatuses) {
      // 获取到文件名
      val filePath = status.getPath
      if (status.isFile) {
        // 获取到文件修改时间
        val time: Long = status.getModificationTime
        val hdfsFileDate = fm.parse(fm.format(new Date(time)))
        if (saveDayDate.after(hdfsFileDate)) {
          fileList += filePath.toString
          // 获取文件个数
          val cs: ContentSummary = fs.getContentSummary(filePath)
          HDFS_FILE_SUM += cs.getFileCount.toInt
          HDFS_FILE_BATCH_DEL_NUM += cs.getFileCount.toInt
          if (HDFS_FILE_BATCH_DEL_NUM >= fileBatchCount) {
            val end = System.currentTimeMillis()
            println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
            println("++++++++++++++++ 遍历文件数量达到 " + HDFS_FILE_BATCH_DEL_NUM + " 个,删除HDFS文件 ++++++++++++++++")
            println("++++++++++++++++++++++++++++ 休眠 " + sleepTime + " S ++++++++++++++++++++++++++++")
            println("++++++++++++++++++++++++ 删除文件总数:" + HDFS_FILE_SUM + " ++++++++++++++++++++++++++")
            println("++++++++++++++++++++++++ 程序运行时间:" + (end - start) / 1000 + " s ++++++++++++++++++++++++")
            println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
            HDFS_FILE_BATCH_DEL_NUM = 0
            TimeUnit.MILLISECONDS.sleep(sleepTime)

          }

          // 文件删除根据绝对路径删除
          println("+++++ 删除文件: " + filePath + "+++++")
          // 递归删除
          fs.delete(filePath, true)
        }

      } else {
        // 递归文件夹
        listPath(fs, filePath.toString, fileList, saveDay, sleepTime, fileBatchCount)
      }
    }
    println("+++++++++++++++++++++++++   删除文件总数:" + HDFS_FILE_SUM + " +++++++++++++++++++++++++")
    fileList
  }

   /**
   * 删除空文件夹
   *
   * @param fs              文件操作对象
   * @param pathName        路径
   * @param pathSplitLength 文件按照"/"拆分后的长度
   */
  def delEmptyDirectory(fs: FileSystem, pathName: String, pathSplitLength: Int) = {

    // 遍历文件
    val fileStatuses = fs.listStatus(new Path(pathName))
    for (status <- fileStatuses) {
      if (status.isDirectory) {
        val path: Path = status.getPath
        // /kangll/winhadoop/temp/wmall_batch_inout/day/1660878372 = 7
        val delPathSplitLength = path.toString.substring(6, path.toString.length).split("/").length
        //  filePath  /kangll/winhadoop/temp/wmall_batch_inout/day  子时间戳文件夹两个
        //        val hdfsPathListCount = fileStatuses.length
        val hdfsPathListCount = fs.listStatus(path).length
        if (delPathSplitLength == pathSplitLength && hdfsPathListCount == 0) {
          println("+++++++++++++++++ 删除空文件夹 : " + path + " +++++++++++++++++++")
          fs.delete(path, true)
        }
      }
    }
  }

  def main(args: Array[String]): Unit = {
    val logger = Logger.getLogger("CleanHDFSFileUtil")
    val conf = new Configuration()
    conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem")
    conf.set("fs.file.impl", "org.apache.hadoop.fs.LocalFileSystem")
    val fs = FileSystem.get(conf)

    val fileList = new ListBuffer[String]
    
    val hdfsDir = if (args.size > 0) args(0).toString else System.exit(0).toString
    val saveDay = if (args.size > 1) args(1).toInt else 2
    val sleepTime = if (args.size > 2) args(2).toLong else 10
    val fileBatchCount = if (args.size > 3) args(3).toInt else 5
    /*
     默认不启用文件夹删除,参数为 文件夹绝对路径Split后的数组长度
     如 路径  /winhadoop/temp/wmall_batch_inout/thirty"  配置为 7
     */
    val pathSplitLength = if (args.size > 4) args(4).toInt else 20
    // 删除文件
    listPath(fs, hdfsDir, fileList, saveDay, sleepTime, fileBatchCount)
    // 删除空文件夹
    delEmptyDirectory(fs, hdfsDir, pathSplitLength)
    fs.close()
  }
}

调用脚本

#                                                                                                         
# 脚本功能: 过期文件清理                                                                                              
# 作    者: kangll                                                                                             
# 创建时间: 2023-09-14                                                                                           
# 修改内容: 控制删除文件的批次个数,程序休眠时间传入                                                              
# 当前版本: 1.0v                                                                                                 
# 调度周期: 一天一次                                                                                                 
# 脚本参数: 删除文件夹、文件保留天数、程序休眠时间、批次删除个数                                                  
#  1.文件根路径,子文件夹递归遍历                                                                                                   
#  2.文件保留天数                                                                                                 
#  3.程序休眠时间 防止 DataNode 删除文件负载过大,单位  秒                                                        
#  4.批次删除文件个数 ,如配置 100,当满足文件个数100时, 整批执行 delete,紧接着程序休眠                           
#  5.默认不启用文件夹删除,也就是不传参,参数为 文件夹绝对路径Split后的数组长度                                   
#        /winhadoop/temp/wmall_batch_inout/thirty/时间戳/ Split后 长度为7,默认删除时间戳文件夹                                                                         
#

###  对应的新删除程序
jarPath=/hadoop/project/del_spark2-1.0-SNAPSHOT.jar

### 集群日志
java -classpath $jarPath com.kangll.common.utils.CleanHDFSFileUtil /spark2-history 3 10 100

参考 :

hadoop抽象文件系统filesystem框架介绍_org.apache.hadoop.fs.filesystem_souy_c的博客-CSDN博客

Hadoop FileSystem文件系统的概要学习 - 回眸,境界 - 博客园

hadoop抽象文件系统filesystem框架介绍_org.apache.hadoop.fs.filesystem_souy_c的博客-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3 Ajax(axios)异步

文章目录 Vue3 Ajax(axios)异步1. 基础1.1 安装Ajax1.2 使用方法1.3 浏览器支持情况 2. GET方法2.1 参数传递2.2 实例 3. POST方法4. 执行多个并发请求5. axios API5.1 传递配置创建请求5.2 请求方法的别名5.3 并发5.4 创建实例5.5 实例方法5.6 请求配置项5.7 响应结构5.8 配置…

【配代码演示】Cookie和Session的区别

一、共同之处&#xff1a; cookie和session都是用来跟踪浏览器用户身份的会话方式。 二、工作原理&#xff1a; 1.Cookie的工作原理 &#xff08;1&#xff09;浏览器端第一次发送请求到服务器端 &#xff08;2&#xff09;服务器端创建Cookie&#xff0c;该Cookie中包含用户的…

控制台日志打印console的封装,加入美化与打印开关

控制台日志打印console的封装&#xff0c;加入美化与打印开关 为什么要写这个&#xff1f; 封装这个控制台日志打印工具&#xff0c;主要是在项目中自己做的SDK需要提供给其他开发人员使用&#xff0c;加入了日志美化和打印打开&#xff0c;方便了开发人员查找SDK中的日志&am…

以神龙出行小程序为例,说一些网站技术

注册和登录功能&#xff1a; 用户注册和登录可以使用手机号验证、第三方登录等方式来实现。这需要与后台服务器进行数据交互&#xff0c;并进行身份验证。 数据存储和管理&#xff1a; 用户的个人信息和常用地址需要进行存储和管理。这可以通过数据库来实现&#xff0c;如关系…

【八大经典排序算法】冒泡排序

【八大经典排序算法】冒泡排序 一、概述二、思路解读三、代码实现四、优化 一、概述 冒泡排序由于其简单和易于理解&#xff0c;使其成为初学者学习排序算法的首选&#xff0c;也是初学者接触到的第一个排序算法。其原理是通过重复交换相邻的元素来将最大的元素逐步“冒泡”到…

Python数据库编程:连接、操作和管理数据库

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 Python作为一门多用途的…

前端screenfull实现界面全屏展示功能

还是先引入依赖 我们要先执行 npm config set registry https://registry.npmjs.org/将本地npm registry地址设置为官方的npm registry地址 不然这个东西安装会有点问题 然后我们执行命令安装 npm install screenfull安装完之后 我们终端执行一下 npm config delete registr…

华为云HECS云服务器docker环境下安装redis

当前有个华为云HECS云服务器&#xff0c;已经安装了docker环境&#xff0c;准备下docker环境下安装redis。 一、HECS云服务器安装docker 登录华为HECS云服务器&#xff0c;安装docker环境。 安装docker参考如下文章&#xff1a; 华为云HECS安装docker并安装mysql-CSDN博客 …

构建个人图床云盘—EasyImage的简单部署及远程访问配置

文章目录 1.前言2. EasyImage网站搭建2.1. EasyImage下载和安装2.2. EasyImage网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar云端设置3.2 Cpolar内网穿透本地设置 4. 公网访问测试5. 结语 1.前言 一个好的图床&#xff0c;是网站或者文章图片能稳定显示的关键&…

ros---服务端和客户端

服务模型&#xff1a; 想对于发布订阅模型的区别&#xff1a;请求一次才会接收一次&#xff0c;而不是不断的发布。 自定义服务数据 1.定义srv文件 2.在package.xml中添加功能包依赖 <build_depend>message_generation</build_depend> <exec_depend>mess…

商业大厦为什么要烟感监控?一篇看懂

烟感监控在现代商业大厦的安全体系中扮演着至关重要的角色。随着城市化的不断发展和商业大厦的不断增多&#xff0c;建筑物内的火灾风险也相应增加。 因此&#xff0c;采取有效的烟感监控措施&#xff0c;以及建立快速响应火警的机制&#xff0c;对于保护人员生命安全和财产安全…

Java之String类

作者简介&#xff1a; zoro-1&#xff0c;目前大二&#xff0c;正在学习Java&#xff0c;数据结构等 作者主页&#xff1a; zoro-1的主页 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f496; Java之String类 String的构造String底层String之间…

【计算机毕业设计】基于SpringBoot+Vue的流浪猫狗救助救援网站的设计与实现

博主主页&#xff1a;一季春秋博主简介&#xff1a;专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发&#xff0c;远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容&#xff1a;毕业设计(Java项目、小程序等)、简历模板、学习资料、面试题…

讨论问题--数据类型、数组、传值/址API函数等

前言 数据类型是编程语言中用于表示数据的分类。常见的数据类型包括整数、浮点数、字符串、布尔值等。数据类型决定了变量能存储的值的种类和范围。 数组是一种存储多个相同类型数据的数据结构。它通过索引来访问并操作其中的元素。数组在内存中是连续存储的&#xff0c;可以…

前后端分离vue简介

vue简介 vue是一个渐进式js框架&#xff0c;用于构建用户界面&#xff0c;其主要特点是易学易用、轻量、灵活和高效。Vue.js由前Google工程师尤雨溪&#xff08; Evan You&#xff09;在2014年创建&#xff0c;它的核心库只关注视图层&#xff0c;是一款非常优秀的MVVM框架&…

大数据驱动业务增长:数据分析和洞察力的新纪元

文章目录 大数据的崛起大数据的特点大数据技术 大数据驱动业务增长1. 洞察力和决策支持2. 个性化营销3. 风险管理4. 产品创新 大数据分析的新纪元1. 云计算和大数据示例代码&#xff1a;使用AWS的Elastic MapReduce&#xff08;EMR&#xff09;进行大数据分析。 2. 人工智能和机…

通过内网穿透实现远程连接群晖Drive,轻松实现异地访问群晖NAS

文章目录 前言1.群晖Synology Drive套件的安装1.1 安装Synology Drive套件1.2 设置Synology Drive套件1.3 局域网内电脑测试和使用 2.使用cpolar远程访问内网Synology Drive2.1 Cpolar云端设置2.2 Cpolar本地设置2.3 测试和使用 3. 结语 前言 群晖作为专业的数据存储中心&…

一些文档上传网站实现原理的分析

背景说明 很多网站都有文档上传功能&#xff0c;如百度文库&#xff0c;原创力&#xff0c;当然也有宇宙闻名的CSDN小猴子网站。如果我们要批量大规模上传文档&#xff0c;手工方式比较低效。自动上传的话&#xff0c;又缺乏网站的API&#xff0c;那只能自己分析上传流程&…

vue中slot,slot-scope,v-slot的用法和区别

slot用于设置标签的属性值(slot“title”)slot-scopev-slot slot <el-menu-item v-if"!navMenu.children" :key"navMenu.id" :index"navMenu.id " click"itemClick(navMenu)" ><span slot"title">{{ navMenu.…

2023-09-18 monetdb-GDK和BAT-分析与思考

摘要: GDK作为moentdb的最核心的内核, 可以看作是物理计划的执行, 以及与磁盘IO直接进行交互. 而物理列的数据结构, 就是BAT. 所以GDK也可以看作是对BAT的操作的模块, BAT是GDK操作的对象, 是GDK的一部分. GDK和BAT的名字其实无关紧要, 重要的是这些模块所承载的功能. GDK: …