当前位置: 首页 > 编程日记 > 正文

序列化和反序列化实现

1. 什么是序列化?

程序员在编写应用程序的时候往往需要将程序的某些数据存储在内存中,然后将其写入文件或是将其传输到网络中的另一台计算机上以实现通讯。这个将程序数据转换成能被存储并传输的格式的过程被称为序列化(serialization),而它的逆过程被称为反序列化(deserialization)。

简单来说,序列化就是将对象实例的状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它根据流重构对象。这两个过程结合起来,可以轻松地存储和传输数据。

序列化:将对象变成字节流的形式传出去。
  反序列化:从字节流恢复成原来的对象。

2. 序列化实现

可以通过将对象转换成json、xml和二进制流的方式实现序列化,鉴于json和xml在不同编程语言中其组包、解包的API接口实现方法的不同,我决定采用通用的二进制流的方式实现序列化。

2.1 类图设计

3. 各个组件代码实现

3.1 元组实现

该元组可以接纳我们自定义的任意类型

数据类型定义:

enum class Type {Invalid,Boolean,Character,Int8,Int16,Int32,Int64,Float,Double,String};

联合体InnerValue定义:联合体的优点在于所有的值共享一篇存储空间,因此不会引起额外的空间存储消耗

union InnerValue {bool booleanValue;char characterValue;int8_t int8Value;int16_t int16Value;int32_t int32Value;int64_t int64Value;float floatValue;double doubleValue;};

Values类实现:

#include <vector>
class Values : public std::vector<Value>
{
public:Values() = default;Values(std::initializer_list<Value> list) : std::vector<Value>(list){}Value& operator[](size_t index) {return std::vector<Value>::operator[](index);}const Value& operator[](size_t index) const {return std::vector<Value>::operator[](index);}
};

异常类TypeMismatchException实现:

#ifdef WIN32
#define NOEXCEPT
#else
#define NOEXCEPT noexcept
#endifclass TypeMismatchException : public std::exception
{
public:TypeMismatchException(const std::string& message) :_message(message){}const char* what() const NOEXCEPT override{return _message.c_str();}private:std::string _message;
};

元组类的使用:

Values list = {5, "hello"};for (Value value : list)
{std::cout << value << " ";
}

3.2 ByteArray类实现

该类主要扩展字节的基本操作

class ByteArray : public std::vector<char> {
public:ByteArray() = default;ByteArray(int32_t size) :std::vector<char>(size) {}ByteArray(const char *buffer, int32_t size) :std::vector<char>(buffer, buffer + size) {}ByteArray(const std::string &str) :std::vector<char>(str.size()) {memcpy(data(), str.c_str(), str.size());}std::string ToStdString() const {std::string result(this->cbegin(), this->cend());return result;}ByteArray &Concat(const ByteArray &buffer2) {size_t oldSize = size();size_t newSize = oldSize + buffer2.size();resize(newSize);memcpy(this->data() + oldSize, buffer2.data(), buffer2.size());return *this;}ByteArray operator+(const ByteArray &buffer2) const {ByteArray buffer1(this->size() + buffer2.size());memcpy(buffer1.data(), this->data(), this->size());memcpy(buffer1.data() + this->size(), buffer2.data(), buffer2.size());return buffer1;}
};

3.3 ByteArrayReader和ByteArrayWriter类实现

ByteArrayReader:实现二进制流到指定类型T的转换,即将ByteArrray写入到类型Tbuff中

ByteArrayWriter:将T类型的Buff写到ByteArray中

 具体代码实现如下:

#pragma once#include "ByteArray.h"#include <stdint.h>class IODevice
{
public:enum class SeekMode{Set,Forward,Backward};
};class ByteArrayWriter : public IODevice
{
public:ByteArrayWriter(){}template <class T>int32_t Write(const T* buffer, int32_t size){int32_t nWriteSize = sizeof(T) * size;ByteArray buffer2((const char *)buffer, nWriteSize);_bytes.Concat(buffer2);return nWriteSize;}template <class T>int32_t Write(const T& value){return Write((T *)&value, 1);}int32_t Write(const ByteArray& byteArray){_bytes.Concat(byteArray);return byteArray.size();}ByteArray ToByteArray() const{return _bytes;}int32_t Tell() const{return _bytes.size();}private:ByteArray _bytes;
};class ByteArrayReader : public IODevice
{
public:ByteArrayReader(const ByteArray& byteArray):_bytes(byteArray), _pos(0){}template <class T>int32_t Read(T *buff, int32_t count){int nSizeToRead = sizeof(T) * count;if(_pos >= _bytes.size()){return 0;}else if (_bytes.size() - _pos < nSizeToRead){nSizeToRead = _bytes.size() - _pos;}memcpy(buff, _bytes.data() + _pos, nSizeToRead);_pos += nSizeToRead;return nSizeToRead;}template <class T>T Read(){T t;int32_t nSize = Read(&t, 1);return t;}ByteArray Read(int32_t size){int nSizeToRead = size;if(_pos >= _bytes.size()){return 0;}else if (_bytes.size() - _pos < nSizeToRead){nSizeToRead = _bytes.size() - _pos;}ByteArray byteArray(_bytes.data() + _pos, nSizeToRead);_pos += nSizeToRead;return byteArray;}int32_t Tell() const{return _pos;}void Seek(SeekMode mode, int32_t size){if(mode == SeekMode::Set){_pos = size;}else if(mode == SeekMode::Forward){_pos += size;}else if(mode == SeekMode::Backward){_pos -= size;}}
private:ByteArray _bytes;int32_t _pos;
};
View Code

3.4 各数据类型读写控制类实现

在进行数据序列化和反序列化的过程中都必须根据数据类型进行指定数据类型的读写操作,我们用两个map其类型和Writeable类的映射关系:

std::map<Value::Type, int32_t> CodeToTypeMap;
std::map<int32_t, std::shared_ptr<IWriteble>> WriterMap;CodeToTypeMap.insert({ Value::Type::Int32, 5 });
CodeToTypeMap.insert({ Value::Type::String, 9 });WriterMap.insert({ 5, std::shared_ptr<IWriteble>(new Int32Writeable) });
WriterMap.insert({ 9, std::shared_ptr<IWriteble>(new StringWriteable) });

代码实现:

class IWriteble
{
public:virtual int32_t Write(ByteArrayWriter& Writer, const Value& value) = 0;virtual int32_t Read(ByteArrayReader& Reader, Value& value) = 0;
};class Int32Writeable : public IWriteble
{
public:Int32Writeable(){}int32_t Write(ByteArrayWriter& Writer, const Value& value) override{int32_t nValue = value.GetInt32Value();return Writer.Write<int32_t>(nValue);}int32_t Read(ByteArrayReader& Reader, Value& value) override{int32_t nValue = Reader.Read<int32_t>();value.SetInt32Value(nValue);return sizeof(int32_t);}
};class StringWriteable : public IWriteble
{
public:StringWriteable(){}int32_t Write(ByteArrayWriter& Writer, const Value& value) override{std::string stringValue = value.GetStringValue();Writer.Write(stringValue.size());Writer.Write(stringValue.c_str(), stringValue.size());return sizeof(int32_t) + stringValue.size();}int32_t Read(ByteArrayReader& Reader, Value& value) override{// 对于string类型,前4个字节为字符串的长度,后面为字符串的内容int32_t nSize = Reader.Read<int32_t>();ByteArray byteArray = Reader.Read(nSize);value.SetStringValue(byteArray.ToStdString());return sizeof(int32_t) + byteArray.size(); // 注意这个位置不应该直接写nSize
    }
};
View Code

3.5 序列化和反序列化函数实现

class DataPachage
{
public:DataPachage(){CodeToTypeMap.insert({ Value::Type::Int32, 5 });CodeToTypeMap.insert({ Value::Type::String, 9 });WriterMap.insert({ 5, std::shared_ptr<IWriteble>(new Int32Writeable) });WriterMap.insert({ 9, std::shared_ptr<IWriteble>(new StringWriteable) });}ByteArray Serialize(const Values& values){ByteArrayWriter Writer;for (Value value : values){Value::Type type = value.GetValueType();int32_t code = CodeToTypeMap[type];std::shared_ptr<IWriteble> pInt32Writer = std::shared_ptr<IWriteble>(new Int32Writeable());pInt32Writer->Write(Writer, code);std::shared_ptr<IWriteble> Writeable = WriterMap[code];Writeable->Write(Writer, value);}return Writer.ToByteArray();}Values DeSerialize(const ByteArray& byteArray){Values values;int32_t i = 0;ByteArrayReader Reader(byteArray);int32_t pos = 0;while (( pos = Reader.Tell()) < byteArray.size()){std::shared_ptr<IWriteble> pInt32Writer = std::shared_ptr<IWriteble>(new Int32Writeable());Value value;pInt32Writer->Read(Reader, value);std::shared_ptr<IWriteble> Writeable = WriterMap[value.GetInt32Value()];Writeable->Read(Reader, value);values.push_back(value);}return values;}private:std::map<Value::Type, int32_t> CodeToTypeMap;std::map<int32_t, std::shared_ptr<IWriteble>> WriterMap;
};

3.6 测试

#include "stdio.h"#include "Serialize.h"int main()
{Values list = {5, "hello"};std::cout << "序列化前Values值:" << std::endl;for (Value value : list){std::cout << value << " ";}std::cout << std::endl;DataPachage data;ByteArray bytes = data.Serialize(list);Values list1 = data.DeSerialize(bytes);std::cout << "反序列化得到Values值:" << std::endl;for (Value value : list1){std::cout << value << " ";}std::cout << std::endl;return 0;
}

附:

#pragma once#include <vector>
#include <string>
#include <cstring>
#include <stdint.h>class ByteArray : public std::vector<char> {
public:ByteArray() = default;ByteArray(int32_t size) :std::vector<char>(size) {}ByteArray(const char *buffer, int32_t size) :std::vector<char>(buffer, buffer + size) {}ByteArray(const std::string &str) :std::vector<char>(str.size()) {memcpy(data(), str.c_str(), str.size());}std::string ToStdString() const {std::string result(this->cbegin(), this->cend());return result;}ByteArray &Concat(const ByteArray &buffer2) {size_t oldSize = size();size_t newSize = oldSize + buffer2.size();resize(newSize);memcpy(this->data() + oldSize, buffer2.data(), buffer2.size());return *this;}ByteArray operator+(const ByteArray &buffer2) const {ByteArray buffer1(this->size() + buffer2.size());memcpy(buffer1.data(), this->data(), this->size());memcpy(buffer1.data() + this->size(), buffer2.data(), buffer2.size());return buffer1;}
};
ByteArray.h
#pragma once#include "ByteArray.h"#include <stdint.h>class IODevice
{
public:enum class SeekMode{Set,Forward,Backward};
};class ByteArrayWriter : public IODevice
{
public:ByteArrayWriter(){}template <class T>int32_t Write(const T* buffer, int32_t size){int32_t nWriteSize = sizeof(T) * size;ByteArray buffer2((const char *)buffer, nWriteSize);_bytes.Concat(buffer2);return nWriteSize;}template <class T>int32_t Write(const T& value){return Write((T *)&value, 1);}int32_t Write(const ByteArray& byteArray){_bytes.Concat(byteArray);return byteArray.size();}ByteArray ToByteArray() const{return _bytes;}int32_t Tell() const{return _bytes.size();}private:ByteArray _bytes;
};class ByteArrayReader : public IODevice
{
public:ByteArrayReader(const ByteArray& byteArray):_bytes(byteArray), _pos(0){}template <class T>int32_t Read(T *buff, int32_t count){int nSizeToRead = sizeof(T) * count;if(_pos >= _bytes.size()){return 0;}else if (_bytes.size() - _pos < nSizeToRead){nSizeToRead = _bytes.size() - _pos;}memcpy(buff, _bytes.data() + _pos, nSizeToRead);_pos += nSizeToRead;return nSizeToRead;}template <class T>T Read(){T t;int32_t nSize = Read(&t, 1);return t;}ByteArray Read(int32_t size){int nSizeToRead = size;if(_pos >= _bytes.size()){return 0;}else if (_bytes.size() - _pos < nSizeToRead){nSizeToRead = _bytes.size() - _pos;}ByteArray byteArray(_bytes.data() + _pos, nSizeToRead);_pos += nSizeToRead;return byteArray;}int32_t Tell() const{return _pos;}void Seek(SeekMode mode, int32_t size){if(mode == SeekMode::Set){_pos = size;}else if(mode == SeekMode::Forward){_pos += size;}else if(mode == SeekMode::Backward){_pos -= size;}}
private:ByteArray _bytes;int32_t _pos;
};
IODevice.h
#pragma once#include <stdint.h>
#include <exception>
#include <string>
#include <iostream>#ifdef WIN32
#define NOEXCEPT
#else
#define NOEXCEPT noexcept
#endifclass TypeMismatchException : public std::exception
{
public:TypeMismatchException(const std::string& message) :_message(message){}const char* what() const NOEXCEPT override{return _message.c_str();}private:std::string _message;
};class Value {
public:enum class Type {Invalid,Boolean,Character,Int8,Int16,Int32,Int64,Float,Double,String};union InnerValue {bool booleanValue;char characterValue;int8_t int8Value;int16_t int16Value;int32_t int32Value;int64_t int64Value;float floatValue;double doubleValue;};Value() : _type(Type::Invalid) {}Value(bool value) : _type(Type::Boolean) {_value.booleanValue = value;}Value(char value) : _type(Type::Character) {_value.characterValue = value;}Value(int8_t value) : _type(Type::Int8) {_value.int8Value = value;}Value(int16_t value) : _type(Type::Int16) {_value.int16Value = value;}Value(int32_t value) : _type(Type::Int32) {_value.int32Value = value;}Value(int64_t value) : _type(Type::Int64) {_value.int64Value = value;}Value(float value) : _type(Type::Float) {_value.floatValue = value;}Value(double value) : _type(Type::Double) {_value.doubleValue = value;}Value(const std::string& value) : _type(Type::String) {_stringValue = value;}Value(const char* value) : Value(std::string(value)) {}bool ToBoolean() const {if ( _type != Type::Boolean ) {throw TypeMismatchException("The type of value is not boolean");}}int8_t ToInt8() const {if ( _type != Type::Int8 ) {throw TypeMismatchException("The type of value is not int8");}return _value.int8Value;}int16_t ToInt16() const {if ( _type != Type::Int16 ) {throw TypeMismatchException("The type of value is not int16");}return _value.int16Value;}int32_t ToInt32() const {if ( _type != Type::Int32 ) {throw TypeMismatchException("The type of value is not int32");}return _value.int32Value;}int64_t ToInt64() const {if ( _type != Type::Int64 ) {throw TypeMismatchException("The type of value is not int64");}return _value.int64Value;}char ToCharacter() const {if ( _type != Type::Character ) {throw TypeMismatchException("The type of value is not character");}return _value.characterValue;}const std::string& ToString() const {if ( _type != Type::String ) {throw TypeMismatchException("The type of value is not string");}return _stringValue;}friend std::ostream& operator<<(std::ostream& os, const Value& value){if (value._type == Type::String){os << "value:" << value._stringValue;}else if (value._type == Type::Int32){os << "value:" << value._value.int32Value;}else if (value._type == Type::Double){os << "value:" << value._value.doubleValue;}return os;} // 以下以int32和string为例进行测试void SetInt32Value(int32_t value){_type = Type::Int32;_value.int32Value = value;}void SetStringValue(std::string value){_type = Type::String;_stringValue = value;}int32_t GetInt32Value() const {return _value.int32Value;}std::string GetStringValue() const {return _stringValue;}Type GetValueType() const {return _type;}private:Type _type;InnerValue _value;std::string _stringValue;
};#include <vector>
class Values : public std::vector<Value>
{
public:Values() = default;Values(std::initializer_list<Value> list) : std::vector<Value>(list){}Value& operator[](size_t index) {return std::vector<Value>::operator[](index);}const Value& operator[](size_t index) const {return std::vector<Value>::operator[](index);}
};
Values.h
#pragma once#include "IODevice.h"
#include "Values.h"class IWriteble
{
public:virtual int32_t Write(ByteArrayWriter& Writer, const Value& value) = 0;virtual int32_t Read(ByteArrayReader& Reader, Value& value) = 0;
};class Int32Writeable : public IWriteble
{
public:Int32Writeable(){}int32_t Write(ByteArrayWriter& Writer, const Value& value) override{int32_t nValue = value.GetInt32Value();return Writer.Write<int32_t>(nValue);}int32_t Read(ByteArrayReader& Reader, Value& value) override{int32_t nValue = Reader.Read<int32_t>();value.SetInt32Value(nValue);return sizeof(int32_t);}
};class StringWriteable : public IWriteble
{
public:StringWriteable(){}int32_t Write(ByteArrayWriter& Writer, const Value& value) override{std::string stringValue = value.GetStringValue();Writer.Write(stringValue.size());Writer.Write(stringValue.c_str(), stringValue.size());return sizeof(int32_t) + stringValue.size();}int32_t Read(ByteArrayReader& Reader, Value& value) override{// 对于string类型,前4个字节为字符串的长度,后面为字符串的内容int32_t nSize = Reader.Read<int32_t>();ByteArray byteArray = Reader.Read(nSize);value.SetStringValue(byteArray.ToStdString());return sizeof(int32_t) + byteArray.size(); // 注意这个位置不应该直接写nSize
    }
};#include <map>
#include <memory>
/*std::map<Value::Type, int32_t> CodeToTypeMap =
{{Value::Type::Int32, 5},{Value::Type::String, 9}
};// 根据数据类型得到对应的IWriteble
std::map<int32_t, std::shared_ptr<IWriteble>> WriterMap =
{{5, std::shared_ptr<IWriteble>(new Int32Writeable)},{9, std::shared_ptr<IWriteble>(new StringWriteable)}
};*///static std::map<int32_t, IWriteble*> WriterMap =
//{
//    {5, new Int32Writeable()},
//    {9, new StringWriteable()}
//};class DataPachage
{
public:DataPachage(){CodeToTypeMap.insert({ Value::Type::Int32, 5 });CodeToTypeMap.insert({ Value::Type::String, 9 });WriterMap.insert({ 5, std::shared_ptr<IWriteble>(new Int32Writeable) });WriterMap.insert({ 9, std::shared_ptr<IWriteble>(new StringWriteable) });}ByteArray Serialize(const Values& values){ByteArrayWriter Writer;for (Value value : values){Value::Type type = value.GetValueType();int32_t code = CodeToTypeMap[type];std::shared_ptr<IWriteble> pInt32Writer = std::shared_ptr<IWriteble>(new Int32Writeable());pInt32Writer->Write(Writer, code);std::shared_ptr<IWriteble> Writeable = WriterMap[code];Writeable->Write(Writer, value);}return Writer.ToByteArray();}Values DeSerialize(const ByteArray& byteArray){Values values;int32_t i = 0;ByteArrayReader Reader(byteArray);int32_t pos = 0;while (( pos = Reader.Tell()) < byteArray.size()){std::shared_ptr<IWriteble> pInt32Writer = std::shared_ptr<IWriteble>(new Int32Writeable());Value value;pInt32Writer->Read(Reader, value);std::shared_ptr<IWriteble> Writeable = WriterMap[value.GetInt32Value()];Writeable->Read(Reader, value);values.push_back(value);}return values;}private:std::map<Value::Type, int32_t> CodeToTypeMap;std::map<int32_t, std::shared_ptr<IWriteble>> WriterMap;
};
Serialize.h
#include "stdio.h"#include "Serialize.h"int main()
{Values list = {5, "hello"};std::cout << "序列化前Values值:" << std::endl;for (Value value : list){std::cout << value << " ";}std::cout << std::endl;DataPachage data;ByteArray bytes = data.Serialize(list);Values list1 = data.DeSerialize(bytes);std::cout << "反序列化得到Values值:" << std::endl;for (Value value : list1){std::cout << value << " ";}std::cout << std::endl;return 0;
}
main.cpp

转载于:https://www.cnblogs.com/xiaobingqianrui/p/9405457.html

相关文章:

linux source命令

source filename 与 sh filename 及./filename执行脚本的区别在那里呢&#xff1f;1.当shell脚本具有可执行权限时&#xff0c;用sh filename与./filename执行脚本是没有区别得。./filename是因为当前目录没有在PATH中&#xff0c;所有"."是用来表示当前目录的。2.sh…

centos7 nginx配置php7,centos7安装并配置nginx+php,centos7nginx

centos7安装并配置nginxphp&#xff0c;centos7nginxcentos7安装并配置nginxphp安装nginxyum install nginx设置nginx开启起动systemctl start nginx测试访问http://你的域名或IP/查看nginx安装位置whereis nginxnginx: /usr/sbin/nginx /etc/nginx /usr/share/nginx /usr/shar…

host ntrip 千寻rtk_什么是千寻知寸cors账号?它提供的定位服务精度如何?使用时需要注意哪些问题?...

千寻知寸cors账号FindCM&#xff1a;基于RTK技术的厘米级差分数据播发服务&#xff0c;终端设备收到差分数据后&#xff0c;结合自己的卫星观测数据进行高精度定位解算&#xff0c;在观测环境良好的情况下&#xff0c;统计精度可以达到水平2~5厘米&#xff0c;高程2~8厘米。由于…

python创建图片对应的csv格式_Python:如何从csv文件创建图形节点和边?

你可以用另一个COLATIC和COLATIC来建立一个COLATIC/COLATIC。然后将图“投影”到datetime节点上—如果两个datetime都链接到ColA/ColC节点&#xff0c;则在它们之间创建一个链接。在下面的代码展示了一种创建无向图的方法。我不明白你的例子里的指示是什么意思。在import csvim…

卡尺测量的最小范围_工厂车间里常用的测量仪器使用方法介绍,你都会用吗?...

一、测量器具的分类 测量器具是一种具有固定形态、用以复现或提供一个或多个已知量值的器具。按用途的不同量具可分为以下几类&#xff1a;1. 单值量具只能体现一个单一量值的量具。可用来校对和调整其它测量器具或作为标准量与被测量直接进行比较&#xff0c;如量块、角度量块…

codeblocks使用指南

文章目录目录创建c/c项目调试codeblocks快捷键目录 创建c/c项目 左上角File->new->project&#xff0c;然后在弹出的对话框中找到Console application点击Go,然后不断Next,中间的除了项目名和项目地址其他默认即可。 然后在左侧工程目录中点开main文件即可Coding了。&…

php变量 标签,html标签如何使用php中的变量

html标签中使用php变量&#xff0c;提示&#xff1a;Undefined index: uid in /var/www//list.php&#xff0c;list.php的具体代码如下&#xff1a;require redis.php;for ($i0; $i < ($redis->get("userid")) ; $i){$data[] $redis->hgetall("user:&…

Shell基础命令之echo

echo命令的功能是在显示器上显示一段文字&#xff0c;一般起到一个提示的作用。该命令的一般格式为&#xff1a; echo [ -n ] 字符串其中选项n表示输出文字后不换行&#xff1b;字符串能加引号&#xff0c;也能不加引号。用echo命令输出加引号的字符串时&#xff0c;将字符串原…

mysql中leave和_MySQL数据库之Mysql存储过程使用LEAVE实现MSSQL存储过程中return语法

本文主要向大家介绍了MySQL数据库之Mysql存储过程使用LEAVE实现MSSQL存储过程中return语法 &#xff0c;通过具体的内容向大家展现&#xff0c;希望对大家学习MySQL数据库有所帮助。DELIMITER $$USE qrsoft_dyj_db$$DROP PROCEDURE IF EXISTS proc_withdraw_approve$$CREATE PR…

cron 工具 每分钟_计划任务 cron和crontab

很多时候&#xff0c;我们需要定时执行某个应用或者某段脚本&#xff0c;在linux上&#xff0c;可以使用cron服务&#xff0c;它有点类似于Windows上的任务计划程序。这篇文章将简单介绍cron的使用。1. crond和crontab首先需要分清楚两个概念&#xff1a;crond和crontab。crond…

Bootstrap学习记录-2.container和table

1. Container Bootstrap中容器类提供了2个类标识&#xff1a;container、container-fluid。 两者的区别在于&#xff1a;container&#xff1a;容器不止有15px的padding&#xff0c;还有一个随着浏览器宽度变化而变化的margin。container-fluid&#xff1a;只有固定的15px的pad…

java中super用来定义父类,Java中super的几种用法及与this的区别

综观目前的 Web 应用&#xff0c;多数应用都具备任务调度的功能。本文由浅入深介绍了几种任务调度的 Java 实现方法&#xff0c;包括 Timer&#xff0c;Scheduler, Quartz 以及 JCron Tab&#xff0c;并对其优缺点进行比较&#xff0c;目的在于给需要开发任务调度的程序员提供有…

1001 A+B

代码链接 PDF链接 首先要说的是这道题的难点是如何把数字输出加入逗号&#xff0c;毕竟数据范围并没有超过Long。当然这个难点也不是问题&#xff0c;将数字转为字符串,C中就有这样的函数&#xff0c;然后再用 %30 这样来控制输出 。 但我最近出于想要建立自己的代码库的想法&a…

pma mysql_Table ‘phpmyadmin.pma_table_uiprefs’ doesn’t exist mysql

Error: #1146 – Table ‘phpmyadmin.pma_table_uiprefs’ doesn’t exist mysqlJust upgrade my ubuntu 14 to 15. all looks good then i go to my localhost phpmyadmin and tried to open database then found a strange error like mysql said: #1146 – Table ‘phpmyadm…

Qt字符编码,创建中文文件

1.代码文件本身编码&#xff1b; 2.Qt中用于控制读入和写出文件系统时的字符编码由QTextCodec::setCodecForLocale()所决定。一般不用设置&#xff0c;Qt跟系统交互时会根据系统的Locale来更改传给系统的参数的编码&#xff1b; //utf8格式 QString str1("你好Hello\r\…

Python 查看本机WiFi密码

http://www.lijiejie.com/python-get-all-saved-wifi-passwords/ 很早以前我写过一个&#xff0c;丢了。 今天偶然看到这篇文章 &#xff0c; 也是很久以前写的&#xff0c;他用的方法太烦了。 dos命令不是可以取本机WiFi密码吗。 #coding:utf-8 import os import re impor…

五连阳回调买入法_“4连阳+1阴”这种股票,吃透主升浪!挣得万贯家财

根据以往的个股表现情况来看&#xff0c;那些即将进入主升浪的个股具有以下几个特点&#xff1a;1、个股前期已经有了一定的涨幅&#xff0c;但向上的步伐比较谨慎&#xff0c;走势比较温和;2、股价所处的位置并不低&#xff0c;有的是一段时期以来的最高位置&#xff0c;有的甚…

java有模糊查询吗,到底Java里的模糊查询语句该怎么写

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼现在String sql"select * from car where carName like %?%";可以查询出结果了&#xff0c;但问题又来了&#xff0c;只能查询出一条结果&#xff0c;代码如下carDao.java页面public ArrayList queryAppoint(String car…

stm32的rxne和idle中断_HAL库的STM32F767的DMA通过IDLE中断接收数据但不能访问

仿真能看到接收缓冲区数组中的数据&#xff0c;但不能访问&#xff0c;如果不访问&#xff0c;再开启DMA接收能正常接收&#xff0c;并且在仿真状态下也能查看。只要访问一次这个数组&#xff0c;下一次开启DMA接收后就不能接收数据了。原代码如下&#xff1a;if(rx_end 1){rx…

使用OpenRowSet操作Excel Excel导入数据库

使用 OpenRowSet 和 OpenDataSource 访问 Excel 97-2007 测试文件&#xff1a;D:\97-2003.xls和D:\2007.xlsx&#xff0c;两个文件的内容是一模一样的。 测试环境&#xff1a;SQL Server 2000 / 2005。 ---------------------------------------------------------------------…

在Windows上搭建Git Server

Git在版本控制方面&#xff0c;相比与SVN有更多的灵活性&#xff0c;对于开源的项目&#xff0c;我们可以托管到Github上面&#xff0c;非常方便&#xff0c;但是闭源的项目就会收取昂贵的费用。 那么私有项目&#xff0c;如何用Git进行代码版本控制呢&#xff1f;我们可以自己…

pci串口驱动安装失败_TSC TTP-243E Pluse装LTP并口驱动无法安装

一、前言描述接到客户报修说&#xff0c;电脑无法开机&#xff0c;即到哥上门维修立即安排人员到现场查看原因&#xff0c;到现场后&#xff0c;查看的确是电脑系统问题&#xff0c;重新安装系统&#xff0c;安装完成系统后&#xff0c;发现打印机无法使用。这个打印机型号是TS…

PHP中阶,PHP进阶

PHP功能的强大首先在于它的大量的内置函数库&#xff0c;它可以让初学者也能执行许多复杂的任务&#xff0c;而不必安装新的库和关心底层的详细情况&#xff0c;而这恰恰是其它流行的诸如Perl这样的客户端语言所不具备的。由于这个教程的限制&#xff0c;我们仅仅学习了一些与M…

安卓手机格式化怎么弄_安卓手机无法启动如何进行格式化

当我们在使用安卓智能手机的时候&#xff0c;由于使用错误或者出现的各种问题导致手机无法重启&#xff0c;相信你一定会感到很烦恼&#xff01;而如果手机混乱到无法启动&#xff0c;格式化是一个不错的尝试方法&#xff01;下面给大家介绍手机格式化的方法和注意事项&#xf…

位域 内存 字节序_JS操作内存?二进制数组了解一下

二进制数组的由来主要是为了提高浏览器与显卡之间的通信效率&#xff0c;由二进制数据代替传统的文本。二进制数组主要有三个对象&#xff1a;ArrayBufferTypedArrayDataViewArrayBuffer对象ArrayBuffer是一个构造函数&#xff0c;参数是一个数字&#xff0c;代表索取多少个字节…

求排列的逆序数(分治)

考虑1,2,…,n (n < 100000)的排列i1&#xff0c;i2&#xff0c;…&#xff0c;in&#xff0c;如果其中存在j,k&#xff0c;满足 j < k 且 ij > ik&#xff0c; 那么就称(ij,ik)是这个排列的一个逆序。 一个排列含有逆序的个数称为这个排列的逆序数。例如排列 263451 含…

mysql 查看当前事务id,MySQL 如何查询当前最新事务ID

写在前面&#xff1a;在个别时候可能需要查看当前最新的事务 ID&#xff0c;以便做一些业务逻辑上的判断(例如利用事务 ID 变化以及前后时差&#xff0c;统计每次事务的响应时长等用途)。通常地&#xff0c;我们有两种方法可以查看当前的事务 ID&#xff1a;1、执行 SHOW ENGIN…

password

pwdText wx.TextCtrl(panel, -1, ”password”, size(175, -1), stylewx.TE_PASSWORD)转载于:https://www.cnblogs.com/chengxuyuan326260/p/6364695.html

java 自带thread分析工具_java自带的jvm分析工具

这段时间觉得很有必要对java的内存分析工具进行熟悉&#xff0c;这样以后出现机器负载较高&#xff0c;或者反应很慢的时候&#xff0c;我就可以查找原因了。上网搜了搜&#xff0c;发现下面这些是比较常用的&#xff0c;然后我在机器上试试了&#xff0c;把结果也贴出来哈。1.…

Python笔记:字典的fromkeys方法创建的初始value同内存地址问题

dict中的fromkeys()函数可以通过一个list来创建一个用同一初始value的dict。 1 d dict.fromkeys(["苹果", "菠萝"], [apple, pineapple]) 2 print(d) 3 d.get("苹果").append(orange) 4 print(d){苹果: [apple, pineapple], 菠萝: [apple, pine…