esp32搭建文件服务器,ESP32入门示例 - SD卡Web服务器

这个是来自ESP32官方示例的改版,官方的示例由于存在一些问题所以我进行了修改

原本的示例有点逻辑上的问题,所以进行了一些修改

主要修改有:

1.新增SD卡测试部分 复制自官方SD卡示例

2.新增一个根目录页,访问根目录就可以看到

3.修改了目录展示页,可以通过"ip地址/list"看到,原本这个页面只会返回"BAD ARGS"

4.新增Wifi设置页,可以通过Wifi设置页更改链接的Wifi(但是建议不要随便更改,除非连着串口,不然你看不到新的IP地址)

5.新增文件上传页,可以通过网页进行上传(调用原本的"/edit"的链接)

下面是页面展示:

主页

70d8077d25d7c32fb2a7a7cb2bbf0996.gif

Index.PNG (29.16 KB, 下载次数: 16)

2018-8-27 15:10 上传

Wifi设置页

70d8077d25d7c32fb2a7a7cb2bbf0996.gif

WifiSetting.PNG (20.95 KB, 下载次数: 14)

2018-8-27 15:10 上传

WIFI信息页

70d8077d25d7c32fb2a7a7cb2bbf0996.gif

WIFIINFO.PNG (7.28 KB, 下载次数: 19)

2018-8-27 15:10 上传

文件目录页

70d8077d25d7c32fb2a7a7cb2bbf0996.gif

File List.PNG (43.39 KB, 下载次数: 16)

2018-8-27 15:10 上传

文件上传页

70d8077d25d7c32fb2a7a7cb2bbf0996.gif

UPLOAD.PNG (3.88 KB, 下载次数: 17)

2018-8-27 15:10 上传

主要代码:

[mw_shl_code=cpp,true]/*

SDWebServer - Example WebServer with SD Card backend for esp8266

Copyright (c) 2015 Hristo Gochkov. All rights reserved.

This file is part of the WebServer library for Arduino environment.

This library is free software; you can redistribute it and/or

modify it under the terms of the GNU Lesser General Public

License as published by the Free Software Foundation; either

version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public

License along with this library; if not, write to the Free Software

Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

Have a FAT Formatted SD Card connected to the SPI port of the ESP8266

The web root is the SD Card root folder

File extensions with more than 3 charecters are not supported by the SD Library

File Names longer than 8 charecters will be truncated by the SD library, so keep filenames shorter

index.htm is the default index (works on subfolders as well)

upload the contents of SdRoot to the root of the SDcard and access the editor by going to http://esp8266sd.local/edit

Modified by Maoweicao 2018.8.27

*/

#include

#include

#include

#include

#include

#include

#include "FS.h"

#define DBG_OUTPUT_PORT Serial

const char* ssid = "................."; //Replace youself wifi ssid

const char* password = "......................"; //Replace youself wifi password

const char* host = "esp32sd";

String wifissid = "";

String wifipwd = "";

WebServer server(80);

static bool hasSD = false;

File uploadFile;

//format bytes

String formatBytes(size_t bytes) {

if (bytes < 1024) {

return String(bytes) + "B";

} else if (bytes < (1024 * 1024)) {

return String(bytes / 1024.0) + "KB";

} else if (bytes < (1024 * 1024 * 1024)) {

return String(bytes / 1024.0 / 1024.0) + "MB";

} else {

return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB";

}

}

void listDir(fs::FS &fs, const char * dirname, uint8_t levels){

Serial.printf("Listing directory: %s\n", dirname);

File root = fs.open(dirname);

if(!root){

Serial.println("Failed to open directory");

return;

}

if(!root.isDirectory()){

Serial.println("Not a directory");

return;

}

File file = root.openNextFile();

while(file){

if(file.isDirectory()){

Serial.print("  DIR : ");

Serial.println(file.name());

if(levels){

listDir(fs, file.name(), levels -1);

}

} else {

Serial.print("  FILE: ");

Serial.print(file.name());

Serial.print("  SIZE: ");

Serial.println(file.size());

}

file = root.openNextFile();

}

}

void createDir(fs::FS &fs, const char * path){

Serial.printf("Creating Dir: %s\n", path);

if(fs.mkdir(path)){

Serial.println("Dir created");

} else {

Serial.println("mkdir failed");

}

}

void removeDir(fs::FS &fs, const char * path){

Serial.printf("Removing Dir: %s\n", path);

if(fs.rmdir(path)){

Serial.println("Dir removed");

} else {

Serial.println("rmdir failed");

}

}

void readFile(fs::FS &fs, const char * path){

Serial.printf("Reading file: %s\n", path);

File file = fs.open(path);

if(!file){

Serial.println("Failed to open file for reading");

return;

}

Serial.print("Read from file: ");

while(file.available()){

Serial.write(file.read());

}

file.close();

}

void writeFile(fs::FS &fs, const char * path, const char * message){

Serial.printf("Writing file: %s\n", path);

File file = fs.open(path, FILE_WRITE);

if(!file){

Serial.println("Failed to open file for writing");

return;

}

if(file.print(message)){

Serial.println("File written");

} else {

Serial.println("Write failed");

}

file.close();

}

void appendFile(fs::FS &fs, const char * path, const char * message){

Serial.printf("Appending to file: %s\n", path);

File file = fs.open(path, FILE_APPEND);

if(!file){

Serial.println("Failed to open file for appending");

return;

}

if(file.print(message)){

Serial.println("Message appended");

} else {

Serial.println("Append failed");

}

file.close();

}

void renameFile(fs::FS &fs, const char * path1, const char * path2){

Serial.printf("Renaming file %s to %s\n", path1, path2);

if (fs.rename(path1, path2)) {

Serial.println("File renamed");

} else {

Serial.println("Rename failed");

}

}

void deleteFile(fs::FS &fs, const char * path){

Serial.printf("Deleting file: %s\n", path);

if(fs.remove(path)){

Serial.println("File deleted");

} else {

Serial.println("Delete failed");

}

}

void testFileIO(fs::FS &fs, const char * path){

File file = fs.open(path);

static uint8_t buf[512];

size_t len = 0;

uint32_t start = millis();

uint32_t end = start;

if(file){

len = file.size();

size_t flen = len;

start = millis();

while(len){

size_t toRead = len;

if(toRead > 512){

toRead = 512;

}

file.read(buf, toRead);

len -= toRead;

}

end = millis() - start;

Serial.printf("%u bytes read for %u ms\n", flen, end);

file.close();

} else {

Serial.println("Failed to open file for reading");

}

file = fs.open(path, FILE_WRITE);

if(!file){

Serial.println("Failed to open file for writing");

return;

}

size_t i;

start = millis();

for(i=0; i<2048; i++){

file.write(buf, 512);

}

end = millis() - start;

Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end);

file.close();

}

void returnOK() {

server.send(200, "text/plain", "");

}

void returnOK(String msg) {

server.send(200, "text/plain", msg+"\r\n");

}

void returnFail(String msg) {

server.send(500, "text/plain", msg + "\r\n");

}

bool loadFromSdCard(String path) {

String dataType = "text/plain";

if (path.endsWith("/")) {

path += "index.htm";

}

if (path.endsWith(".src")) {

path = path.substring(0, path.lastIndexOf("."));

} else if (path.endsWith(".htm")) {

dataType = "text/html";

} else if (path.endsWith(".css")) {

dataType = "text/css";

} else if (path.endsWith(".js")) {

dataType = "application/javascript";

} else if (path.endsWith(".png")) {

dataType = "image/png";

} else if (path.endsWith(".gif")) {

dataType = "image/gif";

} else if (path.endsWith(".jpg")) {

dataType = "image/jpeg";

} else if (path.endsWith(".ico")) {

dataType = "image/x-icon";

} else if (path.endsWith(".xml")) {

dataType = "text/xml";

} else if (path.endsWith(".pdf")) {

dataType = "application/pdf";

} else if (path.endsWith(".zip")) {

dataType = "application/zip";

}

File dataFile = SD.open(path.c_str());

if (dataFile.isDirectory()) {

path += "/index.htm";

dataType = "text/html";

dataFile = SD.open(path.c_str());

}

if (!dataFile) {

return false;

}

if (server.hasArg("download")) {

dataType = "application/octet-stream";

}

if (server.streamFile(dataFile, dataType) != dataFile.size()) {

DBG_OUTPUT_PORT.println("Sent less data than expected!");

}

dataFile.close();

return true;

}

void handleWifiPage()

{

String content = "

Congratulations! You Now Connect to The Wifi!
";

content += "You Connect Wifi Name is:"+String(ssid)+"
";

content += "Wifi Password is:"+String(password)+"
";

content += "You input ssid is:" + wifissid + "
";

content += "You input password is:"+wifipwd+"
";

content += "";

server.send(200, "text/html", content);

}

void handleSetWifi()

{

String msg;

if (server.hasArg("DISCONNECT")){

Serial.println("Disconnection");

String header = "HTTP/1.1 301 OK\r\nSet-Cookie: ESPSESSIONID=0\r\nLocation: /wifiinfo\r\nCache-Control: no-cache\r\n\r\n";

server.sendContent(header);

return;

}

if (server.hasArg("WIFINAME") && server.hasArg("WIFIPWD")){

wifissid=server.arg("WIFINAME");

wifipwd=server.arg("WIFIPWD");

String header = "HTTP/1.1 301 OK\r\nSet-Cookie: ESPSESSIONID=1\r\nLocation: /wifiinfo\r\nCache-Control: no-cache\r\n\r\n";

server.sendContent(header);

Serial.println("WIFI INFO:");

Serial.println("Wifi Name:"+wifissid);

Serial.println("Wifi Password:"+wifipwd);

if(WiFi.isConnected())

{

WiFi.disconnect();

}

WiFi.begin(wifissid.c_str(),wifipwd.c_str());

int i=0;

while (WiFi.status() != WL_CONNECTED && i++ < 50) {//wait 25 seconds

Serial.print(".");

delay(500);

}

if (i == 51) {

DBG_OUTPUT_PORT.print("Could not connect to");

DBG_OUTPUT_PORT.println(wifissid);

while (1) {

delay(500);

}

}

DBG_OUTPUT_PORT.print("Connected! IP address: ");

DBG_OUTPUT_PORT.println(WiFi.localIP());

return;

}

String content = "

This is a Wifi Setting Page
";

content += "Wifi SSID:
";

content += "Wifi Password:
";

content += "

" + msg + "
";

content += "We Can Scan The Wifi List is:
";

int n = WiFi.scanNetworks();

if(n==0)

content += "There is no wifi can use!
";

else

{

content += "

  1. ";

for(int i=0; i

content += (String("

")+String(" Wifi SSID:")+String(WiFi.SSID(i))+String(" Wifi RSSI:")+String(WiFi.RSSI(i))+String((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?String(" "):String("*"))+String(""));

}

content += "

";

}

content += "";

server.send(200, "text/html", content);

}

void handleRoot(){

Serial.println("Enter handleRoot");

String header;

String content = "

Hello, you successfully connected to ESP32-F!


";

if (server.hasHeader("User-Agent")){

content += "the user agent used is : " + server.header("User-Agent") + "
";

}

content += "You can choose this page to visit:
";

content +="Wifi Setup
";

content +="Wifi Infomation
";

content +="File List
";

content +="Upload File
";

content +="Good Luck Everyone!";

content += "";

server.send(200, "text/html", content);

}

void handleUploadWeb()

{

File html=SD.open("/upload/upload.html");

String dataType = "text/html";

server.streamFile(html,dataType);

Serial.println("Open Upload File");

}

void handleFileUpload() {

bool updone=false;

if (server.uri() != "/edit") {

return;

}

String fileName = "";

HTTPUpload& upload = server.upload();

if (upload.status == UPLOAD_FILE_START) {

if (SD.exists((char *)upload.filename.c_str())) {

SD.remove((char *)upload.filename.c_str());

}

fileName = "/upload/"+upload.filename.substring(upload.filename.lastIndexOf('\\')+1);

Serial.println(fileName);

uploadFile = SD.open(fileName, FILE_WRITE);

if(uploadFile!=NULL)

Serial.println("File exsist!");

DBG_OUTPUT_PORT.print("Upload: START, filename: "); DBG_OUTPUT_PORT.println(upload.filename);

} else if (upload.status == UPLOAD_FILE_WRITE) {

if (uploadFile) {

if(uploadFile.write(upload.buf, upload.currentSize))

Serial.println("write Done");

}

DBG_OUTPUT_PORT.print("Upload: WRITE, Bytes: "); DBG_OUTPUT_PORT.println(upload.currentSize);

} else if (upload.status == UPLOAD_FILE_END) {

uploadFile.close();

DBG_OUTPUT_PORT.print("Upload: END, Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);

String message = "Upload Done!\n\n";

message += "URI: ";

message += server.uri();

message += "\nMethod: ";

message += (server.method() == HTTP_GET) ? "GET" : "POST";

message += "\nArguments: ";

message += server.args();

message += "\n";

for (uint8_t i = 0; i < server.args(); i++) {

message += " NAME:" + server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";

}

server.send(200, "text/plain", message);

updone=true;

}

if(updone)

if(fileName!="")

readFile(SD,fileName.c_str());

}

void deleteRecursive(String path) {

File file = SD.open((char *)path.c_str());

if (!file.isDirectory()) {

file.close();

SD.remove((char *)path.c_str());

return;

}

file.rewindDirectory();

while (true) {

File entry = file.openNextFile();

if (!entry) {

break;

}

String entryPath = path + "/" + entry.name();

if (entry.isDirectory()) {

entry.close();

deleteRecursive(entryPath);

} else {

entry.close();

SD.remove((char *)entryPath.c_str());

}

yield();

}

SD.rmdir((char *)path.c_str());

file.close();

}

void handleDelete() {

if (server.args() == 0) {

return returnFail("BAD ARGS");

}

String path = server.arg(0);

if (path == "/" || !SD.exists((char *)path.c_str())) {

returnFail("BAD PATH");

return;

}

deleteRecursive(path);

returnOK();

}

void handleCreate() {

if (server.args() == 0) {

return returnFail("BAD ARGS");

}

String path = server.arg(0);

if (path == "/" || SD.exists((char *)path.c_str())) {

returnFail("BAD PATH");

return;

}

if (path.indexOf('.') > 0) {

File file = SD.open((char *)path.c_str(), FILE_WRITE);

if (file) {

file.write(0);

file.close();

}

} else {

SD.mkdir((char *)path.c_str());

}

returnOK();

}

String listDir2Web(fs::FS &fs, const char * dirname, uint8_t levels)

{

String message="";

File root = fs.open(dirname);

if(!root){

message += "Failed to open directory
";

return message;

}

if(!root.isDirectory()){

message += "Not a directory
";

return message;

}

File file = root.openNextFile();

while(file){

if(file.isDirectory()){

message +="  DIR : ";

message += String(file.name())+String("
");

if(levels){

message += listDir2Web(fs, file.name(), levels -1);

}

} else {

message += String("  FILE: ");

message += String(file.name())+String("
");

message += String("  SIZE: ");

message += formatBytes(file.size())+String("
");

}

file = root.openNextFile();

}

return message;

}

void printDirectory() {

String header = "

";

String message= header + "

List the file in the SD Card:

";

message += listDir2Web(SD,"/",5);

server.send(200,"text/html",message);

}

void handleNotFound() {

if (hasSD && loadFromSdCard(server.uri())) {

return;

}

String message = "SDCARD Not Detected\n\n";

message += "URI: ";

message += server.uri();

message += "\nMethod: ";

message += (server.method() == HTTP_GET) ? "GET" : "POST";

message += "\nArguments: ";

message += server.args();

message += "\n";

for (uint8_t i = 0; i < server.args(); i++) {

message += " NAME:" + server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";

}

server.send(404, "text/plain", message);

DBG_OUTPUT_PORT.print(message);

}

void setup(void) {

DBG_OUTPUT_PORT.begin(115200);

DBG_OUTPUT_PORT.setDebugOutput(true);

DBG_OUTPUT_PORT.print("\n");

WiFi.mode(WIFI_STA);

//Soft AP Setting

/*IPAddress softLocal(192,168,25,1);

IPAddress softGateway(192,168,25,1);

IPAddress softSubnet(255,255,255,0);

WiFi.softAPConfig(softLocal,softGateway,softSubnet);

WiFi.softAP("ESP32_5672C","adminadmin");

Serial.println("SoftAP IPAdress:"+WiFi.softAPIP());*/

//Station Setting

WiFi.begin(ssid, password);

DBG_OUTPUT_PORT.print("Connecting to ");

DBG_OUTPUT_PORT.println(ssid);

// Wait for connection

uint8_t i = 0;

while (WiFi.status() != WL_CONNECTED && i++ < 50) {//wait 25 seconds

Serial.print(".");

delay(500);

}

if (i == 51) {

DBG_OUTPUT_PORT.print("Could not connect to");

DBG_OUTPUT_PORT.println(ssid);

while (1) {

delay(500);

}

}

DBG_OUTPUT_PORT.print("Connected! IP address: ");

DBG_OUTPUT_PORT.println(WiFi.localIP());

//Setting sub network

if (MDNS.begin(host)) {

MDNS.addService("http", "tcp", 80);

DBG_OUTPUT_PORT.println("MDNS responder started");

DBG_OUTPUT_PORT.print("You can now connect to http://");

DBG_OUTPUT_PORT.print(host);

DBG_OUTPUT_PORT.println(".local");

}

server.on("/",handleRoot);

server.on("/list", HTTP_GET, printDirectory);

server.on("/edit", HTTP_DELETE, handleDelete);

server.on("/edit", HTTP_PUT, handleCreate);

server.on("/upload",HTTP_GET,handleUploadWeb);

server.on("/wifiinfo",HTTP_GET,handleWifiPage);

server.on("/wifiset",HTTP_GET,handleSetWifi);

server.on("/wifiset",HTTP_POST,handleSetWifi);

server.on("/edit", HTTP_POST, []() {

returnOK();

}, handleFileUpload);

server.onNotFound(handleNotFound);

server.begin();

DBG_OUTPUT_PORT.println("HTTP server started");

/*if (SD.begin(SS)) {

DBG_OUTPUT_PORT.println("SD Card initialized.");

hasSD = true;

}**/

if(!SD.begin()){

Serial.println("Card Mount Failed");

return;

}

else

{

Serial.println("SD Card Ready!");

hasSD=true;

}

uint8_t cardType = SD.cardType();

if(cardType == CARD_NONE){

Serial.println("No SD card attached");

return;

}

Serial.print("SD Card Type: ");

if(cardType == CARD_MMC){

Serial.println("MMC");

} else if(cardType == CARD_SD){

Serial.println("SDSC");

} else if(cardType == CARD_SDHC){

Serial.println("SDHC");

} else {

Serial.println("UNKNOWN");

}

uint64_t cardSize = SD.cardSize() / (1024 * 1024);

Serial.printf("SD Card Size: %lluMB\n", cardSize);

listDir(SD, "/", 0);

createDir(SD, "/mydir");

createDir(SD, "/upload");

listDir(SD, "/", 0);

removeDir(SD, "/mydir");

listDir(SD, "/", 2);

writeFile(SD, "/hello.txt", "Hello ");

appendFile(SD, "/hello.txt", "World!\n");

readFile(SD, "/hello.txt");

deleteFile(SD, "/foo.txt");

renameFile(SD, "/hello.txt", "/foo.txt");

readFile(SD, "/foo.txt");

testFileIO(SD, "/test.txt");

Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));

Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));

}

void loop(void) {

server.handleClient();

}[/mw_shl_code]

当然文件上传页是在SD卡目录下面的,所以你需要在SD卡新建一个upload目录并且上传一个upload网页

这样就可以上传了。

下面是那个比较简单的上传页面

记得要替换掉那个IP Address变成你自己的目录或者直接去掉

[mw_shl_code=html,true]

Choose You Will Upload File:

[/mw_shl_code]:

另外一个版本:

[mw_shl_code=html,true]

Choose You Will Upload File:

[/mw_shl_code]

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

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

相关文章

mysql 配置文件在哪_MySQL+MyCat分库分表 读写分离配置

一、 MySQLMyCat分库分表1 MyCat简介java编写的数据库中间件Mycat运行环境需要JDK。Mycat是中间件&#xff0c;运行在代码应用和MySQL数据库之间的应用。前身&#xff1a; corba&#xff0c;是阿里开发的数据库中间件&#xff0c;实现MySQL数据库分库分表集群管理的中间件&…

字符串String截取字符char

字符串类的charAt() 方法可返回指定位置的字符。 stringObject.charAt(index)从键盘输入获取了一个字符串&#xff0c;将其数据类型转换为字符型。 Scanner scan new Scanner(System.in); String str scan.next(); char ca str.charAt(0);示例&#xff1a; import java.u…

Java基本语法(14)--for循环结构

循环结构&#xff1a;在某些条件满足的情况下&#xff0c;反复执行特定代码的功能。 基本格式&#xff1a; for (①初始化部分; ②循环条件部分; ④迭代部分)&#xff5b; ③循环体部分; &#xff5d;如果①&#xff0c;④部分多条语句&#xff0c;语句之间用“&#xff0c;”…

Java 8中的功能接口是什么? @功能注释和示例

函数接口是Java 8最重要的概念之一&#xff0c;实际上为lambda表达式提供了动力&#xff0c;但是许多开发人员没有首先了解函数接口在Java 8中的作用就花了很多精力来理解它&#xff0c;并花时间学习lambda表达式和Stream API。除非您知道什么是功能接口以及lambda与它之间的关…

win10存储池_3个光威480G SSD组WIN10存储池,深度测试到底值不值得搞

上次由于我SSD不够&#xff0c;所以我用虚拟硬盘的方式&#xff0c;虚拟了3个VHDX硬盘&#xff0c;组了个奇偶校验的存储池&#xff0c;并且简单的做了测试。测试结果是&#xff0c;组存储池确实提高了我们的数据安全性。WIN10存储池&#xff0c;可以让我们玩家省去组RAID&…

截止角频率和截止频率的关系_开关电源的控制环截止频率和开关频率有什么关系?...

【新朋友】点击上方蓝字“电源之家”关注【老朋友】点击右上角按钮&#xff0c;分享到朋友圈电源之家官方技术③群&#xff1a;522815202(3000人群)(电源行业第一大技术交流QQ群)这个问题很专业&#xff0c;因此答案注定也专业而非科普&#xff0c;非电力电子专业小伙伴看不懂很…

restlet_Restlet框架– Hello World示例

restletRestlet是用于Java平台的轻量级&#xff0c;全面的开源REST框架。 Restlet适用于服务器和客户端Web应用程序。 它支持主要的Internet传输&#xff0c;数据格式和服务描述标准&#xff0c;例如HTTP和HTTPS&#xff0c;SMTP&#xff0c;XML&#xff0c;JSON&#xff0c;At…

在运行时在Spring Cloud Config中刷新属性配置

在本系列Spring Cloud Config的教程系列中&#xff0c;我们将讨论在运行时刷新属性配置的过程&#xff0c;我们将使用Spring Boot致动器/refresh端点进行/refresh 。 此外&#xff0c;我们还将研究使用RefreshScope注释刷新Value属性。 在我的Spring Cloud Config的上一教程中…

pythonnumpy教程_Python学习教程:通俗易懂的Numpy入门教程

Numpy是python语言中最基础和最强大的科学计算和数据处理的工具包&#xff0c;如数据分析工具pandas也是基于numpy构建的&#xff0c;机器学习包scikit-learn也大量使用了numpy方法。本文介绍了Numpy的n维数组在数据处理和分析的所有核心应用。目录如何构建numpy数组如何观察数…

css hack技巧_5种减少Hack的编码技巧

css hack技巧在本文中&#xff0c;我们将探讨五种方法&#xff0c;这些方法可以使用有效的编码来帮助垃圾回收器花费更少的CPU时间分配和释放内存&#xff0c;并减少GC开销。 较长的GC通常会导致我们的代码在回收内存时停止&#xff08;也称为“停止世界”&#xff09;。 一些…

mysql数据库全备_MySQL innobackupex全备是指什么

MySQL innobackupex全备是指什么发布时间&#xff1a;2020-06-03 10:10:31来源&#xff1a;51CTO阅读&#xff1a;133作者&#xff1a;三月下文主要给大家带来MySQL innobackupex全备是指什么&#xff0c;希望这些内容能够带给大家实际用处&#xff0c;这也是我编辑MySQL innob…

数组初始化使用(写)new与不使用(不写)new

首先&#xff0c;数组初始化时&#xff0c;写不写new没有区别的。int arr[] new int[]{ 3, 9, 8};或者int[] arr {3,9,8};编译器遇到 int a[] {3, 8, 9}; 会编译成和 int a[] new int[] {3, 8, 9}; 完全一样的中间代码。 ①不同于String类。String由于实现了常量池&#xf…

Java数组(2)--一维数组

一、一维数组的&#xff08;声明赋值&#xff09;初始化 声明&#xff1a;type var[]; 或 type[] var;&#xff08;示例&#xff1a;int[] age;&#xff09; 初始化&#xff1a; ①动态初始化&#xff1a;声明且为数组元素分配空间&#xff0c;与赋值的操作分开进行 int[] ar…

Java数组(3)--二维(多维)数组

二维数组相当于一维数组的元素是一维数组 一、二维数组声明赋值初始化 动态初始化① int[][] arr new int[3][2];定义了名称为arr的二维数组 二维数组中有3个一维数组 每一个一维数组中有2个元素 一维数组的名称分别为arr[0], arr[1], arr[2] 给第一个一维数组1脚标位赋值为…

workflow java_workflow java实现的activity工作流实例 Develop 238万源代码下载- www.pudn.com...

文件名称: workflow下载收藏√ [5 4 3 2 1 ]开发工具: Java文件大小: 134 KB上传时间: 2014-09-18下载次数: 3提 供 者: 张华详细说明&#xff1a;java实现的activity工作流实例 -java activity文件列表(点击判断是否您需要的文件&#xff0c;如果是垃圾请在下面评价投诉)…

使用OAuth 2 / OpenID Connect的SSO的Spring Boot 2本机方法

这篇文章是3篇系列文章的最后一部分&#xff0c;该系列文章探讨了如何为基于Spring Boot 2的应用程序启用OAuth2提供程序SSO。 3个帖子是&#xff1a; 引导兼容OpenID Connect的OAuth2授权服务器/ OpenID提供程序的方法 与OAuth2授权服务器/ OpenID提供程序集成的旧版Spring …

实现任意行数的杨辉三角

public class JavaTest {public static void main(String[] args) {//放置杨辉三角的数组&#xff0c;可通过更改new int[n][]中n的值以获取不同行数的杨辉三角int[][] yangItem new int[10][];//获取杨辉三角数组中每个元素的值for (int i 0;i < yangItem.length;i){//当…

java excel sheet页_Java导出Excel Sheet页

1、问题背景导出Excel表格时&#xff0c;首先要生成Sheet页&#xff0c;下面将介绍如何生成Sheet页2、实现源码/**** Project:* Title:ExcelExport.java* Package:report.utils* Description:* Author:YouHaiDong* Date:2015年11月2日 下午6:29:22* Version:*/package report.u…

鸿蒙与安卓系统简单对比,绝非追求三分天下。

鸿蒙是面向5G物联网、面向全场景的分布式操作系统&#xff0c;其不是安卓系统的分支或修改而来的&#xff0c;与安卓、iOS是不一样的操作系统。鸿蒙将打通手机、电脑、平板、电视、电器设备、工业自动化控制、无人驾驶、车机设备 、智能穿戴统一成一个操作系统&#xff0c;并且…

(0.1)鸿蒙HarmonyOS开发工具DevEco Studio设置

1、打开设置操作框 2.1主题设置&#xff08;可以工具自己的喜好设置主题&#xff09; 2.2设置字体 2.3设置注释 2.4设置提示语句忽略大小写&#xff08;输入小写时&#xff0c;提示语句也会出现大写的关键字等&#xff09; 2.5设置自动导包&#xff08;不用导包&#xff0c;工具…