JavaRelate 2018-8-10
一些代码
Java 8 编码base64
- 标准编码
//Basic编码是标准的Base64编码, 用于处理常规的需求: 输出的内容不添加换行符, 而且输出的内容由64个基本字符组成;
try {
String encoded = Base64.getEncoder().encodeToString("点点滴滴 点点滴滴d".getBytes("UTF-8"));
System.out.println(encoded);
String decoded = new String(Base64.getDecoder().decode(encoded));
System.out.println(decoded);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
管道, 在内存中 输入&输出流 连通
Java里的管道输入流PipedInputStream与管道输出流PipedOutputStream实现了类似管道的功能, 可用于不同线程之间的相互通信;
先定义一个PipedInputStream对象和一个PipedOutputStream对象, 然后调用两个对象中任意一个的connect方法将输入流和输出流关联起来, 这里调用 pipedInputStream.connect(pipedOutputStream)或者pipedOutputStream.connect(pipedInputStream)效果是一样的, 但是要注意 只能选择其中的一个而不能两个connect同时调用, 即不能像下面一样使用:
PipedInputStream pipedInputStream = new PipedInputStream();
PipedOutputStream pipedOutputStream = new PipedOutputStream();
try {
pipedInputStream.connect(pipedOutputStream);
// pipedOutputStream.connect(pipedInputStream);
} catch (IOException e) {
e.printStackTrace();
}
<!>注意: 在同一个线程内使用,会存在死锁问题!
十六进制的颜色过渡计算
public class Test {
public static void main(String[] args) {
for (int i = 0; i < 101; i++) {
System.out.println(Integer.toHexString(evaluate(i / 100f, 0xFFFFFFFF, 0x00000000)));
}
}
private static int evaluate(float fraction, Integer startValue, Integer endValue) {
// 得到ARGB值
int startInt = startValue;
int startA = (startInt >> 24) & 0xff;
int startR = (startInt >> 16) & 0xff;
int startG = (startInt >> 8) & 0xff;
int startB = startInt & 0xff;
// 过渡目标颜色
int endInt = (Integer) endValue;
int endA = (endInt >> 24) & 0xff;
int endR = (endInt >> 16) & 0xff;
int endG = (endInt >> 8) & 0xff;
int endB = endInt & 0xff;
/*
(int) (fraction * (endA - startA))//随着fraction 增加, 这里面的(endA - startA) 负值增加
(startA + (int) (fraction * (endA - startA)))//加上 负值
(int) ((startA + (int) (fraction * (endA - startA))) << 24)//左移24位, 在ARGB, A的位置保留所有1
*/
return (int) ((startA + (int) (fraction * (endA - startA))) << 24) |
(int) ((startR + (int) (fraction * (endR - startR))) << 16)|
(int) ((startG + (int) (fraction * (endG - startG))) << 8) |
(int) ((startB + (int) (fraction * (endB - startB))));
}
}关于位运算符
/**
* 关于位运算符
* @author yang
* 2016年11月15日
*/
public class BitOperation {
public static void main(String[] args) {
int a = 10;//二进制 ... 0000 1010
int b = 7; //二进制 ... 0000 0111
//按位与,运算的两个位都为 1 时, 结果才为 1, 否则为 0;
System.out.println("a&b="+(a&b)+"; " );//输出:2
//按位或,两个二进制位有一个为 1 时, 结果就为 1, 两个都为 0 时结果才为 0;
System.out.println("a|b="+ (a|b)+"; " );//输出:15
//按位异或,参与^运算两个二进制位不同时, 结果为 1, 相同时结果为 0;
System.out.println("a^b="+(a^b)+";" );//输出:13
//~ 取反 单目运算符,右结合性,作用是其二进制表示的所有位数取反,例,二进制 0001 010,取反后的结果是 1110 101
System.out.println("~1="+(~1)+"; " );//输出:-2
//左移运算符<<用来把操作数的各个二进制位全部左移若干位, 高位丢弃, 低位补0
System.out.println("a<<1="+(a<<1)+"; ");//输出:20
//右移运算符>>用来把操作数的各个二进制位全部右移若干位, 低位丢弃, 高位补 0 或 1; 如果数据的最高位是 0, 那么就补 0; 如果最高位是 1(负数), 那么就补 1 (无符号右移 >>> 则会忽略这一步)
System.out.println("a>>1="+(a>>1)+"; ");//输出:5
}
}
java byte 是有符号的, 高位存的符号, 可以使用 val&0xFF 才是正确byte值 (其实运算后会转为int)
原生DNS 查询实现
System.out.println("DNS 查询: " + getDNSRecs("dc-gateway.gdgov.cn", "19.16.8.2", new String[]{"A"}, 30000, 3) );
/**
* 获取DNS服务器信息
* @param domain
* 要获取DNS信息的域名
* @param provider
* DNS服务器
* @param types
* 信息类型 "A"(IP信息), "MX"
* @param timeout
* 请求超时
* @param retryCount
* 重试次数
* @return 所有信息组成的数组
* @throws NamingException
*/
@SuppressWarnings("rawtypes")
public static ArrayList<String> getDNSRecs(String domain, String provider, String[] types, int timeout, int retryCount) throws NamingException {
ArrayList<String> results = new ArrayList<String>(15);
Hashtable<String, String> env = new Hashtable<String, String>();
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
// 设置域名服务器
env.put(Context.PROVIDER_URL, "dns://" + provider);
// 连接时间
env.put("com.sun.jndi.dns.timeout.initial", String.valueOf(timeout));
// 连接次数
env.put("com.sun.jndi.dns.timeout.retries", String.valueOf(retryCount));
DirContext ictx = new InitialDirContext(env);
Attributes attrs = ictx.getAttributes(domain, types);
for (Enumeration e = attrs.getAll(); e.hasMoreElements();) {
Attribute a = (Attribute) e.nextElement();
int size = a.size();
for (int i = 0; i < size; i++) {
results.add((String) a.get(i));
}
}
return results;
}原生 代理Http请求转发
Map<String, String[]> bodyParams = request.getParameterMap();//参数
StringBuilder buf = new StringBuilder();
Set<String> keySet = bodyParams.keySet();
for (String key: keySet) {
String[] values = bodyParams.get(key);
for (String val: values) {
buf.append(key + "=" + URLEncoder.encode(val, "utf-8") + "&");
}
}
form-data 请求格式
multipart/form-data是基于post方法来传递数据的, 并且其请求内容格式为Content-Type: multipart/form-data,用来指定请求内容的数据编码格式; 另外, 该格式会生成一个boundary字符串来分割请求头与请求体的, 具体的是以一个boundary=${boundary}来进行分割, 伪码如下:
请求体类似于
...
Content-Type: multipart/form-data; boundary=${boundary}
--${boundary}
...
...
--${boundary}--上面boundary={boundary}来进行分割,以—${boundary}—来结束请求体内容
application/x-www-form-urlencoded
它是post的默认格式, 使用js中URLencode转码方法; 包括将name, value中的空格替换为加号; 将非ascii字符做百分号编码; 将input的name, value用‘=’连接, 不同的input之间用‘&’连接;
请求体 类似于.
q=&page=1&rows=10&原生 HttpURLConnection 上传文件
//上传多个文件:
public static int uploadMultFile(final Map<String,File> files, final String url) {
int ret = -1;
String BOUNDARY = UUID.randomUUID().toString(); //边界标识 随机生成
String PREFIX = "--", LINE_END = "\r\n";
String CONTENT_TYPE = "multipart/form-data"; //内容类型
try {
URL httpUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
conn.setReadTimeout(60*1000);
conn.setConnectTimeout(60*1000);
conn.setDoInput(true); //允许输入流
conn.setDoOutput(true); //允许输出流
conn.setUseCaches(false); //不允许使用缓存
conn.setRequestMethod("POST"); //请求方式
conn.setRequestProperty("Charset", "UTF-8");
//设置编码
conn.setRequestProperty("connection", "keep-alive");
conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);
// if(files.size()!= 0) {
/** * 当文件不为空, 把文件包装并且上传 */
OutputStream outputSteam = conn.getOutputStream();
DataOutputStream dos = new DataOutputStream(outputSteam);
Set<String> set = files.keySet();
for (String key: set) {
StringBuffer sb = new StringBuffer();
sb.append(PREFIX);
sb.append(BOUNDARY);
sb.append(LINE_END);
sb.append("Content-Disposition: form-data; name=\"" + key + "\"; filename=\"" + files.get(key).getName() + "\"" + LINE_END);
//sb.append("Content-Type: application/octet-stream; charset="+ "UTF-8" +LINE_END);
sb.append(LINE_END);
dos.write(sb.toString().getBytes());
InputStream is = new FileInputStream(files.get(key));
byte[] bytes = new byte[1024];
int len = -1;
while ((len = is.read(bytes)) != -1) {
dos.write(bytes, 0, len);
}
dos.write(LINE_END.getBytes());
FileIOUnit.closeQuietly(is);
}
byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes();
dos.write(end_data);
dos.flush();
FileIOUnit.closeQuietly(outputSteam);
/**
* 获取响应码
*/
ret = conn.getResponseCode();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return ret;
}
public static int post(String host, Map<String, String> params) {
int ret = -1;
StringBuilder buf = new StringBuilder();
Set<String> keySet = params.keySet();
for (String key: keySet) {
buf.append(key + "=" + params.get(key) + "&");
}
// buf.append("name="+ URLEncoder.encode(name.getText().toString(),"UTF-8")+"&");
// byte[]data = buf.toString().getBytes("UTF-8");
URL url = null;
OutputStream out = null;
try {
url = new URL(host);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("charset", "UTF-8");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
conn.setRequestMethod("POST");
conn.setDoOutput(true); //如果要输出, 则必须加上此句
out = conn.getOutputStream();
out.write(buf.toString().getBytes());
FileIOUnit.closeQuietly(out);
conn.connect();
ret = conn.getResponseCode();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
return ret;
}
恶心!
Quartz 框架
Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中。它提供了巨大的灵 活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,EJB 作业预构 建,JavaMail 及其它,支持 cron-like 表达式等等。
org.quartz.scheduler.instanceName = MyScheduler
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStoreorg.quartz.scheduler.instanceName - This scheduler’s name will be “MyScheduler”.
org.quartz.threadPool.threadCount - There are 3 threads in the thread pool, which means that a maximum of 3 jobs can be run simultaneously.
org.quartz.jobStore.class - All of Quartz’s data, such as details of jobs and triggers, is held in memory (rather than in a database). Even if you have a database and want to use it with Quartz, I suggest you get Quartz working with the RamJobStore before you open up a whole new dimension by working with a database.
示例
QuartzTest.java
// file: QuartzTest.java
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;
import static org.quartz.JobBuilder.*;
import static org.quartz.TriggerBuilder.*;
import static org.quartz.SimpleScheduleBuilder.*;
public class QuartzTest {
public static void main(String[] args) {
try {
// Grab the Scheduler instance from the Factory
// 这个 Scheduler 是核心 可以使用它
// 添加任务 scheduler.scheduleJob(triggerKey, trigger);
// 更新任务 scheduler.rescheduleJob(triggerKey, trigger);
// 暂停任务 scheduler#pauseJob(JobKey jobKey)
// 删除任务 scheduler.deleteJob(jobKey);
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// and start it off
scheduler.start();
scheduler.shutdown();
} catch (SchedulerException se) {
se.printStackTrace();
}
}
}Once you obtain a scheduler using StdSchedulerFactory.getDefaultScheduler(), your application will not terminate until you call scheduler.shutdown(), because there will be active threads.
触发器的用法
// define the job and tie it to our HelloJob class
JobDetail job = newJob(HelloJob.class)
.withIdentity("myJob", "group1") // name "myJob", group "group1"
.build();
// Trigger the job to run now, and then every 40 seconds
Trigger trigger = newTrigger()
.withIdentity("myTrigger", "group1")
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInSeconds(40)
.repeatForever())
.build();
// Tell quartz to schedule the job using our trigger
sched.scheduleJob(job, trigger);spring boot 注意 QuartzAutoConfiguration 自动配置 org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration.quartzScheduler(org.springframework.boot.autoconfigure.quartz.QuartzProperties,org.springframework.beans.factory.ObjectProvider,org.springframework.beans.factory.ObjectProvider,java.util.Map,org.springframework.beans.factory.ObjectProvider,org.springframework.context.ApplicationContext)
GraalVM
GraalVM High Performanсe. Cloud Native. Polyglot.
没有虚拟机的Java, 这是个神器!
Graal VM 被官方称为”Universal VM”和”Polyglot VM”, 这是一个在HotSpot虚拟机基础上增强而成的跨语言全栈虚拟机, 可以作为”任何语言”的运行平台使用, 这里”任何语言”包括了Java, Scala, Groovy, Kotlin等基于Java虚拟机之上的语言, 还包括了C, C++, Rust等基于LLVM的语言, 同时支持其他像JavaScript, Ruby, Python和R语言等等;
Graal VM可以无额外开销地混合使用这些编程语言, 支持不同语言中混用对方的接口和对象, 也能够支持这些语言使用已经编写好的本地库文件;
Java 调用大漠(dll)插件
一, 环境
dm.dll版本3.1233
系统环境win10 /jdk1.8_win32
jacob-1.17(包含 jacob.jar, jacob-1.17-x64.dll, jacob-1.17-x86.dll) 下载地址 https://sourceforge.net/projects/jacob-project/files/jacob-project/
开发工具idea
二, 版本说明
dm.dll 是win32编译的 所以这边jdk要用x86的, jacob也要用x86;
首先将下载好的jacob中的jacob-1.17-x86.dll 拷贝到jdk目录 C:\Program Files (x86)\Java\jdk1.8.0_171\jre\bin
接着工程目录引入jacob .jar包这个一定要跟dll配套
接着 将dm.dll注册到系统, 环境问题是个坑, 因为系统问题, 得先把dm.dll拷贝到C:\Windows\SysWOW64目录下, 然后右键用管理员模式运行cmd.exe 进入目录C:\Windows\SysWOW64 注册dm.dll , 命令regsvr32 dm.dll 这样才能注册成功;
然后新建个类 DmTest.java
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class DmTest {
public static void main(String[] args) {
ActiveXComponent dm = new ActiveXComponent("dm.dmsoft");
System.out.println(dm.invoke("Ver").getString());
Dispatch com = (Dispatch) dm.getObject();
Variant result = Dispatch.call(com, "FindWindow" , "" , "记事本");
System.out.println(result);
}
}
打开一个记事本, 右键运行DmTest就可以看到控制台打印输出版本号和记事本句柄
原文: https://blog.csdn.net/a807719447/article/details/80525079
OpenJDK
Windows
在win隐藏dos窗口运行jar
指定jdk版本
@echo off
chcp 65001
start javaw -jar xxx.jar
C:\Program Files\Java\jdk-11.0.3\bin\java -jar
//带参数, -指定jre 环境
start ./jre/bin/java -jar yunzySpider.jar m在win 查看进程 参数
wmic process where caption="java.exe" get processid,caption,commandline /value
windown 开机启动的注册表
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
将 jar 注册为开机启动
rem 注册bat
set CURPATH=%cd%
%SystemRoot%\System32\reg.exe add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run" /t REG_SZ /v jk-print /d "\"%CURPATH%\start.bat\"" /f
rem start.bat
cd %~dp0
%~d0
start jre\bin\javaw -jar lib\iot-print.jarJavaCV
JavaCV使用来自计算机视觉领域(OpenCV, FFmpeg, libdc1394, PGR FlyCapture, OpenKinect, librealsense, CL PS3 Eye Driver, videoInput, ARToolKitPlus, flandmark, Leptonica和Tesseract)的研究人员的常用库的JavaCPP Presets的包装器和提供实用程序类, 使其功能更易于在Java平台上使用, 包括Android;
JavaCV还具有硬件加速的全屏图像显示(CanvasFrame和GLCanvasFrame), 易于使用的方法以在多核上并行执行代码(并行), 相机和投影仪的用户友好型几何和颜色校准(GeometricCalibrator, ProCamGeometricCalibrator) , ProCamColorCalibrator), 特征点的检测和匹配(ObjectFinder), 实现投影仪与相机系统直接图像对齐的一组类(主要是GNImageAligner, ProjectiveTransformer, ProjectiveColorTransformer, ProCamTransformer和ReflectanceInitializer), 斑点分析包(Blobs), 以及JavaCV类中的其他功能; 这些类中的一些还具有OpenCL和OpenGL对应类, 它们的名称以CL结尾或以GL开头, 即: JavaCVCL, GLCanvasFrame等;
要了解如何使用API, 因为目前缺少文档, 请参阅下面的示例用法部分以及示例程序, 包括两个Android(FacePreview.java和RecordActivity.java), 也可以在samples目录中找到; 您可能还会发现参考ProCamCalib和ProCamTracker的源代码以及从OpenCV2 Cookbook和相关Wiki页面移植的示例很有用;
<!-- https://mvnrepository.com/artifact/org.bytedeco/javacv -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.4.4</version>
</dependency>
<!-- full platfrom 全平台本地库 -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.4.4</version>
</dependency>JavaCV FFmpeg
Minecraft 我的世界
模组开发 MinecraftForge
做个模组玩玩… TODO
minecraftforge 英文文档 MinecraftForge 中文文档
-
Obtain a Java Development Kit (JDK) and a 64-bit Java Virtual Machine (JVM).
-
Obtain the Mod Development Kit (MDK) from Forge’s files site.
-
Extract the downloaded MDK into an empty directory. You should see a bunch of files along with an example mod placed in src/main/java for you to look at. Only a few of these files are strictly necessary for mod development, and you may reuse these files for all your projects. These files are:
build.gradlegradlew.batgradlewsettings.gradlethe gradle folder Move the files listed above to a new folder. This will be your mod project folder.
MDK下载页 要手动跳过广告才下载 …
-
Choose your IDE
-
Generating IDE Launch/Run Configurations:
For Eclipse, run the genEclipseRuns gradle task (gradlew genEclipseRuns). This will generate the Launch Configurations and download any required assets for the game to run. After this has finished, refresh your project. For IntelliJ, run the genIntellijRuns gradle task (gradlew genIntellijRuns). This will generate the Run Configurations and download any required assets for the game to run. If you encounter an error saying “module not specified”, you can either edit the configuration to select your “main” module or specify it through the ideaModule property. For VSCode, run the genVSCodeRuns gradle task (gradlew genVSCodeRuns). This will generate the Launch Configurations and download any required assets for the game to run.
文档有问题, 没有 genIntellijRuns 之类的 gradlew 任务?