技术标签: ⦿ 开发技术
参考博客:https://www.cnblogs.com/dongliyang/p/4173583.html
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.ChannelSftp.LsEntry;
/**
* SFTP(Secure File Transfer Protocol),安全文件传送协议。
* @version 1.0 2014/12/18
* @author dongliyang
*/
public class SFTPUtil2 {
/** 日志记录器 */
private Logger logger = LoggerFactory.getLogger(SFTPUtil2.class);
/** Session */
private Session session = null;
/** Channel */
private ChannelSftp channel = null;
/** SFTP服务器IP地址 */
private String host;
/** SFTP服务器端口 */
private int port;
/** 连接超时时间,单位毫秒 */
private int timeout;
/** 私钥 */
private String privateKey;
/** 用户名 */
private String username;
/** 密码 */
private String password;
/**
* SFTP 安全文件传送协议
* @param host SFTP服务器IP地址
* @param port SFTP服务器端口
* @param timeout 连接超时时间,单位毫秒
* @param username 用户名
* @param password 密码
*/
public SFTPUtil2(String host,int port,int timeout,String username,String password){
this.host = host;
this.port = port;
this.timeout = timeout;
this.username = username;
this.password = password;
}
/**
* 基于秘钥认证的sftp对象
* @param host SFTP服务器IP地址
* @param port SFTP服务器端口
* @param username 用户名
* @param privateKey 秘钥
*/
public SFTPUtil2( String host, int port, String username, String privateKey) {
this.host = host;
this.port = port;
this.timeout = 30000; // 30秒超时
this.username = username;
this.privateKey = privateKey;
}
/**
* 登陆SFTP服务器
* @return boolean
*/
public boolean login() {
try {
JSch jsch = new JSch();
session = jsch.getSession(username, host, port);
if (privateKey != null) {
jsch.addIdentity(privateKey);// 设置私钥
}
if(password != null){
session.setPassword(password);
}
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
config.put("PreferredAuthentications","publickey,keyboard-interactive,password"); // 不加这行会报错 Kerberos username [xxxxxx]:
session.setConfig(config);
session.setTimeout(timeout);
session.connect();
logger.debug("sftp session connected");
logger.debug("opening channel");
channel = (ChannelSftp)session.openChannel("sftp");
channel.connect();
logger.debug("connected successfully");
return true;
} catch (JSchException e) {
logger.error("sftp login failed:"+e.getMessage());
return false;
}
}
/**
* 上传文件
* @param pathName SFTP服务器目录
* @param fileName 服务器上保存的文件名
* @param input 输入文件流
* @return boolean
*/
public boolean uploadFile(String filePath,String fileName,InputStream input,String isSkip){
try {
if(!isDirExist(filePath)){ //不存在则创建
makeDir(filePath);
}
} catch (SftpException e1) {
e1.printStackTrace();
}
//String currentDir = currentDir();
if(!changeDir(filePath)){
return false;
}
try {
if( ifExits( filePath+"/"+fileName ) && "1".equals(isSkip) ){ // 跳过文件
logger.info("Skipped.File exits:"+filePath+"/"+fileName);
return true;
}
if( ifExits( filePath+"/"+fileName ) && "3".equals(isSkip) ){ // 自动 备份/重命名:原文件名+“.bak20181016111630222”
channel.rename(filePath+"/"+fileName, filePath+"/"+fileName+".bak"+DateUtils.getNowDateTime("yyyyMMddHHmmssSSS"));
}
channel.put(input,fileName,ChannelSftp.OVERWRITE);
if(!existFile(fileName)){
logger.debug("upload failed");
return false;
}
logger.debug("upload successful");
return true;
} catch (SftpException e) {
logger.error("upload failed",e);
return false;
} finally {
changeDir("/");
}
}
/**
* 上传文件
* @param pathName SFTP服务器目录
* @param fileName 服务器上保存的文件名
* @param localFile 本地文件
* @return boolean
*/
public boolean uploadFile(String filePath,String fileName,String localFile,String isSkip){
try {
if(!isDirExist(filePath)){ //不存在则创建
makeDir(filePath);
}
} catch (SftpException e1) {
e1.printStackTrace();
}
if(!changeDir(filePath)){
return false;
}
try {
if( ifExits( filePath+"/"+fileName ) && "1".equals(isSkip) ){ // 跳过文件
logger.info("Skipped.File exits:"+filePath+"/"+fileName);
return true;
}
if( ifExits( filePath+"/"+fileName ) && "3".equals(isSkip) ){ // 自动 备份/重命名:原文件名+“.bak20181016111630222”
channel.rename( fileName, fileName+".bak"+DateUtils.getNowDateTime("yyyyMMddHHmmssSSS"));
}
channel.put(localFile, fileName ,ChannelSftp.OVERWRITE);
if(!existFile(fileName)){
logger.debug("upload failed");
return false;
}
logger.debug("upload successful");
return true;
} catch (SftpException e) {
logger.error("upload failed",e);
return false;
} finally {
changeDir("/");
}
}
/**
* 下载文件
* <p>
* 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/
* <table border="1">
* <tr><td>当前目录</td><td>方法</td><td>参数:绝对路径/相对路径</td><td>下载后</td></tr>
* <tr><td>/</td><td>downloadFile("testA","down.txt","D:\\downDir")</td><td>相对路径</td><td>D:\\downDir\\down.txt</td></tr>
* <tr><td>/</td><td>downloadFile("testA/testA_B","down.txt","D:\\downDir")</td><td>相对路径</td><td>D:\\downDir\\down.txt</td></tr>
* <tr><td>/</td><td>downloadFile("/testA/testA_B","down.txt","D:\\downDir")</td><td>绝对路径</td><td>D:\\downDir\\down.txt</td></tr>
* </table>
* </p>
* @param remotePath SFTP服务器目录
* @param fileName 服务器上需要下载的文件名
* @param localPath 本地保存绝对路径
* @return boolean
*/
public boolean downloadFile(String remotePath,String fileName,String localPath){
String currentDir = currentDir();
if(!changeDir(remotePath)){
return false;
}
try {
channel.get(fileName,localPath);
File localFile = new File(localPath);
if(!localFile.exists()){
logger.debug("download file failed");
return false;
}
logger.debug("download successful");
return true;
} catch (SftpException e) {
logger.error("download file failed",e);
return false;
} finally {
changeDir(currentDir);
}
}
/**
* 下载文件
* @param remotePath 文件的SFTP绝对路径
* @param localPath 保存文件的本地绝对路径
* @return
*/
public boolean downloadFile2(String remotePath, String localPath){
try {
//changeToHomeDir();
channel.get( remotePath,localPath);
} catch (SftpException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 切换工作目录
* <p>
* @param pathName 路径
* @return boolean
*/
public boolean changeDir(String pathName){
if(pathName == null || pathName.trim().equals("")){
logger.debug("invalid pathName");
return false;
}
try {
channel.cd(pathName.replaceAll("\\\\", "/"));
logger.debug("directory successfully changed,current dir=" + channel.pwd());
return true;
} catch (SftpException e) {
logger.error("failed to change directory",e);
return false;
}
}
/**
* 切换到上一级目录
* <p>
* 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/
* <table border="1">
* <tr><td>当前目录</td><td>方法</td><td>切换后的目录</td></tr>
* <tr><td>/testA/</td><td>changeToParentDir()</td><td>/</td></tr>
* <tr><td>/testA/testA_B/</td><td>changeToParentDir()</td><td>/testA/</td></tr>
* </table>
* </p>
* @return boolean
*/
public boolean changeToParentDir(){
return changeDir("..");
}
/**
* 切换到根目录
* @return boolean
*/
public boolean changeToHomeDir(){
String homeDir = null;
try {
homeDir = channel.getHome();
} catch (SftpException e) {
logger.error("can not get home directory",e);
return false;
}
return changeDir(homeDir);
}
/**
* 创建目录
* <p>
* 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/
* <table border="1">
* <tr><td>当前目录</td><td>方法</td><td>参数(绝对路径/相对路径)</td><td>创建成功后的目录</td></tr>
* <tr><td>/testA/testA_B/</td><td>makeDir("testA_B_C")</td><td>相对路径</td><td>/testA/testA_B/testA_B_C/</td></tr>
* <tr><td>/</td><td>makeDir("/testA/testA_B/testA_B_D")</td><td>绝对路径</td><td>/testA/testA_B/testA_B_D/</td></tr>
* </table>
* <br/>
* <b>注意</b>,当<b>中间目录不存在</b>的情况下,不能够使用绝对路径的方式期望创建中间目录及目标目录。
* 例如makeDir("/testNOEXIST1/testNOEXIST2/testNOEXIST3"),这是错误的。
* </p>
* @param dirName 目录
* @return boolean
*/
public boolean makeDir(String dirName){
try {
// channel.mkdir(dirName);
String[] folders = dirName.split( "/" );
for ( String folder : folders ) {
if ( folder.length() > 0 ) {
try {
channel.cd( folder );
}
catch ( SftpException e ) {
channel.mkdir( folder );
channel.cd( folder );
}
}
}
logger.debug("directory successfully created,dir=" + dirName);
return true;
} catch (SftpException e) {
logger.error("failed to create directory", e);
return false;
}
}
/**
* 删除文件夹
* @param dirName
* @return boolean
*/
@SuppressWarnings("unchecked")
public boolean delDir(String dirName){
if(!changeDir(dirName)){
return false;
}
Vector<LsEntry> list = null;
try {
list = channel.ls(channel.pwd());
} catch (SftpException e) {
logger.error("can not list directory",e);
return false;
}
for(LsEntry entry : list){
String fileName = entry.getFilename();
if(!fileName.equals(".") && !fileName.equals("..")){
if(entry.getAttrs().isDir()){
delDir(fileName);
} else {
delFile(fileName);
}
}
}
if(!changeToParentDir()){
return false;
}
try {
channel.rmdir(dirName);
logger.debug("directory " + dirName + " successfully deleted");
return true;
} catch (SftpException e) {
logger.error("failed to delete directory " + dirName,e);
return false;
}
}
/**
* 删除文件
* @param fileName 文件名
* @return boolean
*/
public boolean delFile(String fileName){
if(fileName == null || fileName.trim().equals("")){
logger.debug("invalid filename");
return false;
}
try {
channel.rm(fileName);
logger.debug("file " + fileName + " successfully deleted");
return true;
} catch (SftpException e) {
logger.error("failed to delete file " + fileName,e);
return false;
}
}
/**
* 当前目录下文件及文件夹名称列表
* @return String[]
*/
public String[] ls(){
return list(Filter.ALL);
}
/**
* 指定目录下文件及文件夹名称列表
* @return String[]
*/
public String[] ls(String pathName){
String currentDir = currentDir();
if(!changeDir(pathName)){
return new String[0];
};
String[] result = list(Filter.ALL);
if(!changeDir(currentDir)){
return new String[0];
}
return result;
}
/**
* 当前目录下文件名称列表
* @return String[]
*/
public String[] lsFiles(){
return list(Filter.FILE);
}
/**
* 指定目录下文件名称列表
* @return String[]
*/
public String[] lsFiles(String pathName){
String currentDir = currentDir();
if(!changeDir(pathName)){
return new String[0];
};
String[] result = list(Filter.FILE);
if(!changeDir(currentDir)){
return new String[0];
}
return result;
}
/**
* 当前目录下文件夹名称列表
* @return String[]
*/
public String[] lsDirs(){
return list(Filter.DIR);
}
/**
* 指定目录下文件夹名称列表
* @return String[]
*/
public String[] lsDirs(String pathName){
String currentDir = currentDir();
if(!changeDir(pathName)){
return new String[0];
};
String[] result = list(Filter.DIR);
if(!changeDir(currentDir)){
return new String[0];
}
return result;
}
/**
* 当前目录是否存在文件或文件夹
* @param name 名称
* @return boolean
*/
public boolean exist(String name){
return exist(ls(), name);
}
/**
* 指定目录下,是否存在文件或文件夹
* @param path 目录
* @param name 名称
* @return boolean
*/
public boolean exist(String path,String name){
return exist(ls(path),name);
}
/**
* 当前目录是否存在文件
* @param name 文件名
* @return boolean
*/
public boolean existFile(String name){
return exist(lsFiles(),name);
}
/**
* 指定目录下,是否存在文件
* @param path 目录
* @param name 文件名
* @return boolean
*/
public boolean existFile(String path,String name){
return exist(lsFiles(path), name);
}
/**
* 当前目录是否存在文件夹
* @param name 文件夹名称
* @return boolean
*/
public boolean existDir(String name){
return exist(lsDirs(), name);
}
/**
* 指定目录下,是否存在文件夹
* @param path 目录
* @param name 文家夹名称
* @return boolean
*/
public boolean existDir(String path,String name){
return exist(lsDirs(path), name);
}
/**
* 当前工作目录
* @return String
*/
public String currentDir(){
try {
return channel.pwd();
} catch (SftpException e) {
logger.error("failed to get current dir",e);
return homeDir();
}
}
/**
* 登出
*/
public void logout(){
if(channel != null){
channel.quit();
channel.disconnect();
}
if(session != null){
session.disconnect();
}
logger.debug("logout successfully");
}
//------private method ------
/** 枚举,用于过滤文件和文件夹 */
private enum Filter {/** 文件及文件夹 */ ALL ,/** 文件 */ FILE ,/** 文件夹 */ DIR };
/**
* 列出当前目录下的文件及文件夹
* @param filter 过滤参数
* @return String[]
*/
@SuppressWarnings("unchecked")
private String[] list(Filter filter){
Vector<LsEntry> list = null;
try {
//ls方法会返回两个特殊的目录,当前目录(.)和父目录(..)
list = channel.ls(channel.pwd());
} catch (SftpException e) {
logger.error("can not list directory",e);
return new String[0];
}
List<String> resultList = new ArrayList<String>();
for(LsEntry entry : list){
if(filter(entry, filter)){
resultList.add(entry.getFilename());
}
}
return resultList.toArray(new String[0]);
}
/**
* 判断是否是否过滤条件
* @param entry LsEntry
* @param f 过滤参数
* @return boolean
*/
private boolean filter(LsEntry entry,Filter f){
if(f.equals(Filter.ALL)){
return !entry.getFilename().equals(".") && !entry.getFilename().equals("..");
} else if(f.equals(Filter.FILE)){
return !entry.getFilename().equals(".") && !entry.getFilename().equals("..") && !entry.getAttrs().isDir();
} else if(f.equals(Filter.DIR)){
return !entry.getFilename().equals(".") && !entry.getFilename().equals("..") && entry.getAttrs().isDir();
}
return false;
}
/**
* 根目录
* @return String
*/
private String homeDir(){
try {
return channel.getHome();
} catch (SftpException e) {
return "/";
}
}
/**
* 判断字符串是否存在于数组中
* @param strArr 字符串数组
* @param str 字符串
* @return boolean
*/
private boolean exist(String[] strArr,String str){
if(strArr == null || strArr.length == 0){
return false;
}
if(str == null || str.trim().equals("")){
return false;
}
for(String s : strArr){
if(s.equalsIgnoreCase(str)){
return true;
}
}
return false;
}
/**
* 判断 FTP 文件是否存在
* @param absolutePath FTP绝对路径
* @return
*/
public boolean ifExits(String absolutePath){
return getFileProperties(absolutePath)==null?false:true;
}
/**
* 判断是否是目录
* @param absolutePath
* @return
*/
public boolean isDirectory(String absolutePath){
SftpATTRS sss = getFileProperties(absolutePath);
if( null!=sss ){
return sss.isDir();
}
return false;
}
/**
* 获取FTP服务器上的文件属性:修改时间,文件大小,创建时间,文件权限 等等
* @param ftpFilePath
* @return
*/
public SftpATTRS getFileProperties(String ftpFilePath ){
SftpATTRS ss=null;
try {
ss = channel.stat( ftpFilePath );
logger.debug("File Path:"+ ftpFilePath );
logger.debug("File modify time:"+ DateUtils.CSTFormat( ss.getMtimeString() )); // ss.getMtimeString()
logger.debug("File size:"+ ss.getSize()+"bytes");
} catch (SftpException e) {
//logger.error("Failed to get file properties:"+ e.getMessage());
}
return ss;
}
/**
* inputStream类型转换为byte类型
* @param iStrm
* @return
* @throws IOException
*/
public byte[] inputStreamToByte (InputStream iStrm) throws IOException {
ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
int ch;
while ((ch = iStrm.read()) != -1) {
bytestream.write(ch);
}
byte imgdata[] = bytestream.toByteArray();
bytestream.close();
return imgdata;
}
/**
* 获取远程文件的流文件
* @param sftpFilePath
* @return
* @throws SftpException
*/
public InputStream getFile (String sftpFilePath) throws SftpException {
//if (isFileExist(sftpFilePath)) {
return channel.get(sftpFilePath);
//}
//return null;
}
/**
* 获取远程文件字节流
* @param sftpFilePath
* @return
* @throws SftpException
* @throws IOException
*/
public ByteArrayInputStream getByteArrayInputStreamFile (String sftpFilePath) throws SftpException,IOException {
//if (isFileExist(sftpFilePath)) {
byte[] srcFtpFileByte = inputStreamToByte(getFile(sftpFilePath));
ByteArrayInputStream srcFtpFileStreams = new ByteArrayInputStream(srcFtpFileByte);
return srcFtpFileStreams;
//}
//return null;
}
/**
* 移动远程文件到目标目录
* @param srcSftpFilePath
* @param distSftpFilePath
* @return 返回移动成功或者失败代码和信息
* @throws SftpException
* @throws IOException
*/
public String moveFile (String srcSftpFilePath, String distSftpFilePath) throws SftpException,IOException {
String retInfo = "";
boolean dirExist = false;
//boolean result = false;
if (!(dirExist)) {
//1建立目录
makeDir(distSftpFilePath);
//2设置dirExist为true
dirExist = true;
}
if (dirExist) {
String fileName = srcSftpFilePath.substring(srcSftpFilePath.lastIndexOf("/"), srcSftpFilePath.length());
ByteArrayInputStream srcFtpFileStreams = getByteArrayInputStreamFile(srcSftpFilePath);
//二进制流写文件
channel.put(srcFtpFileStreams, distSftpFilePath + fileName);
channel.rm(srcSftpFilePath);
retInfo = "1:move success!";
}
return retInfo;
}
/**
* 判断目录是否存在
* @param directory
* @return
* @throws SftpException
*/
public boolean isDirExist (String directory) throws SftpException {
boolean isDirExistFlag = false;
try {
SftpATTRS sftpATTRS = channel.lstat(directory);
isDirExistFlag = true;
return sftpATTRS.isDir();
} catch (Exception e) {
if (e.getMessage().toLowerCase().equals("no such file")) {
isDirExistFlag = false;
}
}
return isDirExistFlag;
}
List<String> lsFTPFiles = new ArrayList<String>();
/**
* 递归:列出指定目录下的所有子目录和文件(不包含空目录)
* @param ftpPath SFTP上的绝对路径,比如 “/TEST/Cloudy”
* @return lsFiles 返回所有文件的绝对路径
*/
@SuppressWarnings("unchecked")
public void listFTPFilesByPath(String ftpPath){
try {
channel.cd(ftpPath);
Vector<LsEntry> v = channel.ls("*");// 列出服务器指定的文件列表
for(LsEntry entry : v){
String fileName = entry.getFilename();
String currentPath = ftpPath+"/"+fileName;
if(!fileName.equals(".") && !fileName.equals("..")){
if(entry.getAttrs().isDir()){
getListFilesByPath( currentPath );
} else {
lsFTPFiles.add(currentPath);
//logger.info( currentPath );
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 递归:列出指定目录下的所有子目录和文件(不包含空目录)
* @param ftpPath SFTP上的绝对路径,比如 “/TEST/Cloudy”
* @return lsFiles 返回所有文件的绝对路径
*/
public List<String> getListFilesByPath(String ftpPath){
listFTPFilesByPath(ftpPath);
return removeDuplicateString(lsFTPFiles);// 去重(防止全局变量重用时 重复设值)
}
/**
* 递归:列出指定目录下的所有子目录和文件(不包含空目录)
* @param ftpPath SFTP上的绝对路径,比如 “/TEST/Cloudy”
* @return fileNames 返回所有文件的相对于传入路径的文件名
*/
public String[] getListFilesNameByPath(String ftpPath){
String[] fileNames = null;
List<String> lsFiles = getListFilesByPath( ftpPath );
if( null!=lsFiles && lsFiles.size()>0 ){
fileNames = new String[lsFiles.size()];
for( int x=0;x<lsFiles.size();x++ ){
fileNames[x] = ( new File( lsFiles.get(x) ) ).getName();
}
}
return fileNames;
}
/**
* 去重:String
* @param list
* @return
*/
public static List<String> removeDuplicateString(List<String> list) {
List<String> list_new = new ArrayList<String>();
for( int a=0;a<list.size();a++ ){
String s1 = list.get(a);
if( null!=list_new && list_new.size()>0 ){
for( int b=0;b<list_new.size();b++ ){
if( s1.equals( list_new.get(b) ) ){
break;// 重复,去掉
}else{
if( b+1==list_new.size() ){
list_new.add( list.get(a) );
}
}
}
}else{
list_new.add( list.get(a) );
}
}
return list_new;
}
public static void main(String[] args) throws SftpException, IOException {
SFTPUtil2 sftp = new SFTPUtil2( "1.1.1.1", 22, 1111,"1111", "1111" );
sftp.login();
//String stu = DateUtils.CSTFormat( sftp.getFileProperties("/TEMP/test4/VBA traning.txt").getMtimeString() );
//String date = sftp.getFileProperties("/TEMP/test5/555.rar").getMtimeString();
//System.out.println("date== "+date);
//System.out.println("stu= "+ sftp.getFileProperties("/TEMP/test5/555.rar").getMtimeString());
//System.out.println("value is= "+DateUtils.fileTimeFormat(sftp.getFileProperties("/TEMP/test4/VBA traning.txt").getMtimeString()));
String ftpPath = "/TEST/Cloudy";
List<String> list_1 = sftp.getListFilesByPath( ftpPath);
for( int x=0;x<list_1.size();x++ ){
System.out.println( list_1.get(x) );
}
// String[] ss= sftp.getListFilesNameByPath(ftpPath);
// for( int y=0;y<ss.length;y++ ){
// System.out.println( ss[y] );
// }
}
}
文章浏览阅读2.2w次,点赞27次,收藏150次。网络安全行业产业以来,随即新增加了几十个网络安全行业岗位︰网络安全专家、网络安全分析师、安全咨询师、网络安全工程师、安全架构师、安全运维工程师、渗透工程师、信息安全管理员、数据安全工程师、网络安全运营工程师、网络安全应急响应工程师、数据鉴定师、网络安全产品经理、网络安全服务工程师、网络安全培训师、网络安全审计员、威胁情报分析工程师、灾难恢复专业人员、实战攻防专业人员…网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己录的网安视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。_ansys2022r1安装教程
文章浏览阅读44次。最近一直在看Deep Learning,各类博客、论文看得不少但是说实话,这样做有些疏于实现,一来呢自己的电脑也不是很好,二来呢我目前也没能力自己去写一个toolbox只是跟着Andrew Ng的UFLDL tutorial写了些已有框架的代码(这部分的代码见github)后来发现了一个matlab的Deep Learning的toolbox,发现其代码很简单,感觉比较适合用来学习算法再一个就是..._matlab deep learning 工具箱算例
文章浏览阅读1.8k次。2020/5/27更新:大家现在可以直接从Saleem Abdulrasool的Azure Pipeline中下载打包好的Swift Windows SDK了,在他的GitHub中找到swift-build项目,里面的CI链接里找到Artifacts就可以直接下载(类似windows-toolchain-amd64.msi这样的文件)。考虑到5.3版本的Swift将支持Windows平台,因此以下文章也许已经成为历史,大家看看就好了。-----------------------------------_windows 无法编译swift
文章浏览阅读66次。用户管理:一.用户的配置文件:用户配置文件的路径:/etc/passwd/etc/passwd的一部分内容:每一行都是一个用户的信息(内容如下):用户名 :密码 :uid :gid :用户的备注 :用户的家目录 :和根交互使用的shell路径 二.用户超级用户root ----- uid为 0系统用户 ----- 使用的shell的路径为 /sbin/nologin ,uid为 201 —— 999,添加系统用户不会默认创建家目录和邮箱普通用户 ----- uid为 1000 ——
文章浏览阅读6.9k次。心田花开为大家分享了二年级语文上册黄山奇石练习题,本部分练习题包括了看拼音,写词语;选择合适的字;填空题;造句子及句子赏析,最后附加课文原文,希望能对大家学习有帮助。【原文】黄山奇石闻名中外的黄山风景区在我国安徽省南部。那里景色秀丽神奇,尤其是那些怪石,有趣极了。就说“仙桃石”吧,它好像从天上飞下来的一个大桃子,落在山顶的石盘上。在一座陡峭的山峰上,有一只“猴子”。它两只胳膊抱着腿,一动不动..._黄山奇石阅读题及答案二年级
文章浏览阅读3.2k次,点赞45次,收藏7次。tab导航的中间开始然后向两边过渡的动画效果,增加页面的美观性..._css过度动画从中间向两边移动
文章浏览阅读3.3k次。掌控安全封神台第三关 根据题目可能要用burp进行抓包,点击传送门进入题目主页之前题目说的扫描到新的后台地址admin123 在网址后加入admin123 进入新的后台管理页面根据第二关得到的用户和密码进行登录 进入后得到这样一个页面抓包结果如下根据代码分析只需要修改host和referer的ip地址修改以后结果还是进不去分析一下问题 打开F..._掌控安全靶场第三关密码多少
文章浏览阅读3.9k次,点赞4次,收藏9次。import codecsfilecp = codecs.open('sunspot.dat', encoding ='utf-8')file_data = np.loadtxt(filecp, usecols=(0,1),skiprows=1)x = file_data[:,0]y = file_data[:,1]_python读取txt文件第二列数据
文章浏览阅读111次。一、nosql背景互联网时代背景下大机遇,为什么用nosql1单机MySQL的美好年代在90年代,一个网站的访问量一般都不大,用单个数据库完全可以轻松应付。在那个时候,更多的都是静态网页,动态交互类型的网站不多。上述架构下,我们来看看数据存储的瓶颈是什么? 1.数据量的总大小 一个机器放不下时 2.数据的索引(B+ Tree)一个机器的内存放不下时 3.访问量..._redis 理论基础学习
文章浏览阅读3.6k次,点赞2次,收藏15次。一、使用netsh命令设置IP/DNS(1)自动获取IP地址:(其中中括号内容可省略)netsh interface ip set address [name=]“以太网” [source=]dhcp(2)手动设置IP地址:例如设置 IP 为 192.168.1.198,掩码为255.255.255.0,网关为192.168.0.254,那么 cmd 命令为:netsh interface ip set address [name=]“本地连接” [source=]static [addr=]_dos设置ip地址命令
文章浏览阅读1.3k次,点赞23次,收藏23次。Rebalance负载均衡组件, 他负责相对均匀的给消费者分配需要拉取的队列信息。我们此时可能会有以下问题:一个Topic下可能会有很多逻辑队列,而消费者又有多个,这样不同的消费者到底消费哪个队列呢?如果消费者或者队列扩缩容,Topic下的队列又该分配给谁呢?这些时候负载均衡策略就有他的用武之地了。RocketMQ在处理上面的问题是统一处理的,也就是逻辑是一致的,它都是通过这个类来完成负载均衡的工作,看完本文我们就可以明白RocketMQ消费者负载均衡的核心逻辑。消费端的负载均衡是指。_rebalance mq
文章浏览阅读912次。K. 20182018 的约数只有 4 个,可以算出区间内和 2018 的最⼤公约数是1, 2, 1009, 2018 的各有⼏个,之后 4 × 4 枚举统计答案。#include <iostream>using namespace std;int main (){ int a,b,c,d; while(cin>>a>>b>>c..._湘潭邀请赛 2018 k.2018