你好,看完你的博客文章,感觉很不错!希望与你网站首页友情链接 流量卡知识网 http://53go.cn/ 专注于移动/联通/电信推出的大流量多语音活动长短期套餐手机卡的相关知识的介绍普及听说互换友情链接可以增加网站的收录量,特此来换,如果同意的话就给internetyewu@163.com[微信ganenboy]发信息或者就在此回复下吧!【建站问题也可以一起讨论!】
你好,看完你的博客文章,感觉很不错!希望与你网站首页友情链接 流量卡知识网 http://53go.cn/ 专注于移动/联通/电信推出的大流量多语音活动长短期套餐手机卡的相关知识的介绍普及听说互换友情链接可以增加网站的收录量,特此来换,如果同意的话就给internetyewu@163.com[微信ganenboy]发信息或者就在此回复下吧!【建站问题也可以一起讨论!】
你好
http://bigota.d.miui.com/V14.0.9.0.TLJCNXM/ingres_images_V14.0.9.0.TLJCNXM_20230323.0000.00_13.0_cn_chinatelecom_aff802bb3e.tgz
已添加贵站友链 Southerly 个人博客 || http://www.southerly.top || https://www.southerly.top/imgs/favicon.ico || 一个正在努力搬砖的兼职程序员,记录生活,分享生活,欢迎大家来访。
目前这种不行了
老哥呀,现在这种方法还能爬到数据嘛?可以聊聊不
https://www.aliyundrive.com/s/5N2bKDVZfxC
https://wwi.lanzoup.com/iU6FZ0o4as1i
04824ADB9F824ADB9F0400824ADB9F000F
https://lihh.lanzouf.com/ij6c80nhq7rg
https://cloud.189.cn/web/share?code=FvuIbuJBnEVr
https://lihh.lanzouf.com/ij6c80nhq7rg
https://developer.aliyun.com/plan/student?taskCode=vmfeitian2023&recordId=5246709&undefined&share_source=copy_link
已加,三天之后检查没加本站链接 就下了
首页
大佬聚集地
欢迎大家
教程分享
每日一看
Search
1
欢迎来到河马博客
41,756 阅读
2
守护者群管小栗子框架下载教程
40,887 阅读
3
烟花模拟器(php)
35,661 阅读
4
外链搜索引擎优化如何发布
13,619 阅读
5
一键搭建表白墙源码+教程
13,255 阅读
软件分享
教程分享
源码分享
游戏攻略
百科知识
SEO课程
登录
Search
标签搜索
推特
升学考试
账号
数学
饺子
笔记本电脑
笔记本
研究生考试
字符
英语
函数
马斯克
笔记本电脑排名前十
操作
初一
联想
考研
广告
注册
账户
河马
累计撰写
7,418
篇文章
累计收到
81
条评论
今日撰写
50
篇文章
首页
栏目
软件分享
教程分享
源码分享
游戏攻略
百科知识
SEO课程
页面
大佬聚集地
欢迎大家
教程分享
每日一看
用户登录
登录
搜索到
1415
篇与
的结果
2023-12-07
太疯狂了(java实现直播)java实现视频直播,JavaCV多媒体入门 - 序章直播技术,java多媒体技术,
什么是JavaCVJavaCV 是一个用于在 Java 中处理计算机视觉和多媒体任务的库,它封装了许多计算机视觉和多媒体库,包括 OpenCV 和 FFmpeg。一个开源的多媒体流技术Java处理库,用于图像和视频处理。它可以应用于各种多媒体及图像处理,包括:视频处理:可以用于视频采集、编码、解码、播放、转换等。例如,可以使用 JavaCV 来开发视频会议、视频直播、视频剪辑等应用程序。图像处理:可以用于图像采集、处理、识别等。例如,可以使用 JavaCV 来开发图像识别、图像处理、图像增强等应用程序。机器视觉:可以用于机器视觉应用,例如工业检测、医疗诊断、自动驾驶等。具体到一些应用场景视频会议:可以用于视频会议应用程序的视频采集、编码、解码、播放等。视频直播:可以用于视频直播应用程序的视频采集、编码、传输、解码等。视频剪辑:可以用于视频剪辑应用程序的视频裁剪、合并、添加特效等。图像识别:可以用于图像识别应用程序的图像分类、物体检测、人脸识别等。图像处理:可以用于图像处理应用程序的图像增强、去噪、滤波等。工业检测:可以用于工业检测应用程序的缺陷检测、质量控制等。医疗诊断:可以用于医疗诊断应用程序的图像分析、疾病识别等。自动驾驶:可以用于自动驾驶应用程序的交通标志识别、行人检测等。简单使用示例(Java)安装JavaCV<dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>版本号</version></dependency>采集桌面进行播放// 创建采集器FrameGrabber grabber = new FFmpegFrameGrabber("desktop");// 设置采集参数grabber.setFrameRate(30);// Windows 的 GDIGrab 接口grabber.setFormat("gdigrab");// 绘制鼠标grabber.setOption("draw_mouse", "1");// 视频尺寸grabber.setOption("video_size", "1920x1080");// 启动采集器grabber.start();CanvasFrame canvasFrame = new CanvasFrame("桌面");// 循环采集并播放while (true) {// 获取当前帧Frame frame = grabber.grab();// 显示当前帧canvasFrame.showImage(frame);// 休眠 10 毫秒Thread.sleep(10);}这个只是最简单JavaCV入门示例,希望对您有所帮助!章节一:录制桌面播放推流到流媒体服务器或存储视频End
2023年12月07日
0 阅读
0 评论
0 点赞
2023-12-07
深度揭秘(阿里线程池规范)阿里笔试编程题,阿里架构师实例讲解——Java多线程编程;详细的不能再详细了,java多线程实例,
欢迎关注专栏《Java架构筑基》——专注于Java技术的研究与分享!Java架构筑基zhuanlan.zhihu.com/c_1141766767415312384Java架构筑基——专注于Java技术的研究与分享!后续文章将首发此专栏!欢迎各位Java工程师朋友投稿和关注Java架构师进阶之路<常用资料分享>一、理解多线程多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。具体到java内存模型,由于Java被设计为跨平台的语言,在内存管理上,显然也要有一个统一的模型。系统存在一个主内存(Main Memory), Java中所有变量都储存在主存中,对于所有线程都是共享的。每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。多个线程的执行是并发的,也就是在逻辑上“同时”,而不管是否是物理上的“同时”。如果系统只有一个CPU,那么真正的“同时”是不可能的。多线程和传统的单线程在程序设计上最大的区别在于,由于各个线程的控制流彼此独立,使得各个线程之间的代码是乱序执行的,将会带来线程调度,同步等问题。二、在Java中实现多线程我们不妨设想,为了创建一个新的线程,我们需要做些什么?很显然,我们必须指明这个线程所要执行的代码,而这就是在Java中实现多线程我们所需要做的一切!作为一个完全面向对象的语言,Java提供了类 java.lang.Thread 来方便多线程编程,这个类提供了大量的方法来方便我们控制自己的各个线程。那么如何提供给 Java 我们要线程执行的代码呢?让我们来看一看 Thread 类。Thread 类最重要的方法是 run(),它为Thread 类的方法 start() 所调用,提供我们的线程所要执行的代码。为了指定我们自己的代码,只需要覆盖它!方法一:继承 Thread 类,重写方法 run(),我们在创建Thread 类的子类中重写 run() ,加入线程所要执行的代码即可。下面是一个例子:public class TwoThread extends Thread {public void run() {for ( int i = 0; i < 10; i++ ) {System.out.println("New thread");}}public static void main(String[] args) {TwoThread tt = new TwoThread();tt.start();for ( int i = 0; i < 10; i++ ) {System.out.println("Main thread");}}}这种方法简单明了,符合大家的习惯,但是,它也有一个很大的缺点,那就是如果我们的类已经从一个类继承,则无法再继承 Thread 类。方法二:实现 Runnable 接口Runnable 接口只有一个方法 run(),我们声明自己的类实现 Runnable 接口并提供这一方法,将我们的线程代码写入其中,就完成了这一部分的任务。但是 Runnable 接口并没有任何对线程的支持,我们还必须创建 Thread 类的实例,这一点通过 Thread 类的构造函数public Thread(Runnable target);来实现。下面是一个例子:public class MyThread implements Runnable {int count=1, number;public MyThread(int num) {number = num;System.out.println("创建线程 " + number);}public void run() {//实现了接口的run()方法while(true) {System.out.println("线程 " + number + ":计数 " + count);if(++count== 6) return;}}public static void main(String args[]) {for (int i = 0; i < 5; i++)new Thread(new MyThread(i+1)).start();}}使用 Runnable 接口来实现多线程使得我们能够在一个类中包容所有的代码,有利于封装下面让我们一起来研究一下多线程使用中的一些问题。三、线程的四种状态新状态:线程已被创建但尚未执行(start() 尚未被调用)。可执行状态:线程可以执行,虽然不一定正在执行。CPU 时间随时可能被分配给该线程,从而使得它执行。阻塞状态:线程不会被分配 CPU 时间,无法执行;可能阻塞于I/O,或者阻塞于同步锁。死亡状态:正常情况下run() 返回使得线程死亡。调用 stop()或 destroy() 亦有同样效果,但是不被推荐,前者会产生异常,后者是强制终止,不会释放锁。四、线程的优先级线程的优先级代表该线程的重要程度,当有多个线程同时处于可执行状态并等待获得 CPU 时间时,线程调度系统根据各个线程的优先级来决定给谁分配 CPU 时间,优先级高的线程有更大的机会获得 CPU 时间,优先级低的线程也不是没有机会,只是机会要小一些罢了。你可以调用 Thread 类的方法 getPriority() 和 setPriority()来存取线程的优先级,线程的优先级界于1(MIN_PRIORITY)和10(MAX_PRIORITY)之间,缺省是5(NORM_PRIORITY)。五、线程的同步由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。我们只需针对方法提出一套机制,这套机制就是 synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。①. synchronized 方法:通过在方法声明中加入synchronized关键字来声明 synchronized 方法。synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized,以控制其对类的静态成员变量的访问。synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法run()声明为synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何synchronized方法的调用都永远不会成功。②. synchronized 块:通过 synchronized关键字来声明synchronized 块。语法如下:synchronized(syncObject) {//允许访问控制的代码}synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject 的锁方能执行,具体机制同前所述。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。六、线程的阻塞为了解决对共享存储区的访问冲突,Java 引入了同步机制,现在让我们来考察多个线程对共享资源的访问,显然同步机制已经不够了,因为在任意时刻所要求的资源不一定已经准备好了被访问,反过来,同一时刻准备好了的资源也可能不止一个。为了解决这种情况下的访问控制问题,Java 引入了对阻塞机制的支持。阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪)。Java 提供了大量方法来支持阻塞,下面让对它们逐一分析。①.sleep()方法:sleep()允许指定以毫秒为单位的一段时间作为参数,它使得线程在指定的时间内进入阻塞状态,不能得到CPU 时间,指定的时间一过,线程重新进入可执行状态。典型地,sleep() 被用在等待某个资源就绪的情形:测试发现条件不满足后,让线程阻塞一段时间后重新测试,直到条件满足为止。②.suspend()和resume()方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的 resume() 被调用,才能使得线程重新进入可执行状态。典型地,suspend() 和 resume()被用在等待另一个线程产生的结果的情形:测试发现结果还没有产生后,让线程阻塞,另一个线程产生了结果后,调用resume()使其恢复。③.yield() 方法:yield() 使得线程放弃当前分得的 CPU 时间,但是不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得 CPU 时间。调用 yield() 的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程。④.wait() 和 notify() 方法:两个方法配套使用,wait()使得线程进入阻塞状态,它有两种形式,一种允许指定以毫秒为单位的一段时间作为参数,另一种没有参数,前者当对应的 notify()被调用或者超出指定时间时线程重新进入可执行状态,后者则必须对应的 notify() 被调用。2和4区别的核心在于,前面叙述的所有方法,阻塞时都不会释放占用的锁(如果占用了的话),而这一对方法则相反。上述的核心区别导致了一系列的细节上的区别。首先,前面叙述的所有方法都隶属于Thread 类,但是这一对却直接隶属于 Object 类,也就是说,所有对象都拥有这一对方法。因为这一对方法阻塞时要释放占用的锁,而锁是任何对象都具有的,调用任意对象的 wait()方法导致线程阻塞,并且该对象上的锁被释放。而调用任意对象的notify()方法则导致因调用该对象的 wait()方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。其次,前面叙述的所有方法都可在任何位置调用,但是这一对方法却必须在 synchronized 方法或块中调用,理由也很简单,只有在synchronized 方法或块中当前线程才占有锁,才有锁可以释放。同样的道理,调用这一对方法的对象上的锁必须为当前线程所拥有,这样才有锁可以释放。因此,这一对方法调用必须放置在这样的 synchronized 方法或块中,该方法或块的上锁对象就是调用这一对方法的对象。若不满足这一条件,则程序虽然仍能编译,但在运行时会出现 IllegalMonitorStateException 异常。wait()和notify()方法的上述特性决定了它们经常和synchronized 方法或块一起使用,将它们和操作系统的进程间通信机制作一个比较就会发现它们的相似性:synchronized方法或块提供了类似于操作系统原语的功能,它们的结合用于解决各种复杂的线程间通信问题。关于 wait() 和 notify() 方法最后再说明两点:第一:调用 notify() 方法导致解除阻塞的线程是从因调用该对象的 wait() 方法而阻塞的线程中随机选取的,我们无法预料哪一个线程将会被选择,所以编程时要特别小心,避免因这种不确定性而产生问题。第二:除了 notify(),还有一个方法 notifyAll() 也可起到类似作用,唯一的区别在于,调用 notifyAll()方法将把因调用该对象的wait()方法而阻塞的所有线程一次性全部解除阻塞。当然,只有获得锁的那一个线程才能进入可执行状态。谈到阻塞,就不能不谈一谈死锁,略一分析就能发现,suspend() 方法和不指定超时期限的 wait() 方法的调用都可能产生死锁。遗憾的是,Java 并不在语言级别上支持死锁的避免,我们在编程中必须小心地避免死锁。以上我们对 Java 中实现线程阻塞的各种方法作了一番分析,我们重点分析了 wait() 和 notify()方法,因为它们的功能最强大,使用也最灵活,但是这也导致了它们的效率较低,较容易出错。实际使用中我们应该灵活使用各种方法,以便更好地达到我们的目的。还有一个方法比较有用,Thread的join()方法可用于让当前线程阻塞,以等待特定线程的消亡。package cn.test.first.thread;import java.lang.Runnable;import java.lang.Thread;public class DemoThread implements Runnable {public DemoThread() {TestThread testthread1 = new TestThread(this, "1");TestThread testthread2 = new TestThread(this, "2");testthread2.start();testthread1.start();}public static void main(String[] args) {DemoThread demoThread1 = new DemoThread();}public void run() {TestThread t = (TestThread) Thread.currentThread();try {if (!t.getName().equalsIgnoreCase("1")) {synchronized (this) {wait();}}while (true) {System.out.println("@time in thread" + t.getName() + "=" + t.increaseTime());if (t.getTime() % 2 == 0) {synchronized (this) {System.out.println("****************************************");notify();if (t.getTime() == 10) {break;}wait();}}}}catch (Exception e) {e.printStackTrace();}}}class TestThread extends Thread {private int time = 0;public TestThread(Runnable r, String name) {super(r, name);}public int getTime() {return time;}public int increaseTime() {return ++time;}}运行结@time in thread1=1@time in thread1=2****************************************@time in thread2=1@time in thread2=2****************************************@time in thread1=3@time in thread1=4****************************************@time in thread2=3@time in thread2=4****************************************……@time in thread1=9@time in thread1=10****************************************@time in thread2=9@time in thread2=10****************************************七、守护线程守护线程是一类特殊的线程,它和普通线程的区别在于它并不是应用程序的核心部分,当一个应用程序的所有非守护线程终止运行时,即使仍然有守护线程在运行,应用程序也将终止,反之,只要有一个非守护线程在运行,应用程序就不会终止。守护线程一般被用于在后台为其它线程提供服务。调用方法 isDaemon() 来判断一个线程是否是守护线程,也可以调用方法setDaemon()将一个线程设为守护线程。八、一个应用:线程池1. 背景诸如 Web 服务器、数据库服务器、文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务。 服务器应用程序中经常出现的情况是:单个任务处理的时间很短而请求的数目却是巨大的。2. 解决方法构建服务器应用程序的一个过于简单的模型应该是:每当一个请求到达就创建一个新线程,然后在新线程中为请求服务。那么这种方法的严重不足就很明显。每个请求对应一个线程(thread-per-request)方法的不足之一是:为每个请求创建一个新线程的开销很大;在一个 JVM 里创建太多的线程可能会导致系统由于过度消耗内存而用完内存或“切换过度”。为了防止资源不足,服务器应用程序需要一些办法来限制任何给定时刻处理的请求数目。我们可以实现一个线程池类,其中客户机类等待一个可用线程、将任务传递给该线程以便执行、然后在任务完成时将线程归还给池,一般一个简单线程池至少包含下列组成部分:线程池管理器(ThreadPoolManager):用于创建并管理线程池工作线程(WorkThread): 线程池中线程任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行。任务队列:用于存放没有处理的任务。提供一种缓冲机制。public class WorkQueue {private final int nThreads;private final PoolWorker[] threads;private final LinkedList queue;public WorkQueue(int nThreads) {this.nThreads = nThreads;queue = new LinkedList();threads = new PoolWorker[nThreads];for (int i = 0; i < nThreads; i++) {threads[i] = new PoolWorker();threads[i].start();}}public void execute(Runnable r) {synchronized (queue) {queue.addLast(r);queue.notify();}}private class PoolWorker extends Thread {public void run() {Runnable r;while (true) {synchronized (queue) {while (queue.isEmpty()) {try {queue.wait();}catch (InterruptedException ignored) {}}r = (Runnable) queue.removeFirst();}// If we dont catch RuntimeException,// the pool could leak threadstry {r.run();}catch (RuntimeException e) {// You might want to log something here}}}}public static void main(String args[]) {WorkQueue wq = new WorkQueue(3);wq.execute(new Runnable() {public void run() {for (int i = 0; i < 10; i++) {try {Thread.sleep(1000);}catch (Exception e) {}System.out.println("this is a thread");}}});}}链接 Java程序员福利"常用资料分享"
2023年12月07日
0 阅读
0 评论
0 点赞
2023-12-07
快来看(程序员接私活平台哪个好一点)程序员接私活平台哪个好点,程序员19个接私活平台,java私活网,
01. 前 言关于程序员接私活,社会各界说法不一。按照作者的观点来说如果你确实急用钱,价格又合适,那就去做。如果不怎么缺钱,那就接私活之前要好好考虑。私活的钱不好挣是一个方面,更重要的是如果你把做私活的时间花在提升自己上,产生的价值就要大得多。等你提升了自己,提升了固定薪水,远比拿的这点私活的钱划算。千万不要“捡了芝麻丢了西瓜”。如果你主业上遇到了瓶颈,平时的时间比较充分,想有一些额外的收入,同时为了保持技术的熟练度,这种情况下,是可以考虑接一些私活的。对于那种投入时间巨大,回报很可怜的项目,千万不要接。下面介绍一些常用的接私活平台。02. 程序员客栈程序员客栈中国非常领先的自由工作平台,为中高端程序员、产品经理和设计师等等互联网相关人员提供稳定的线上工作机会,包括自由工作、远程工作和兼职工作,还支持按需雇佣,工作模式非常多,感兴趣的推荐大家尝试一下。虽然名称叫程序员客栈,但是除了程序员,像产品经理,设计师等等互联网相关人员,都能在上面找到适合自己的项目。感兴趣的可以体验一下。程序员客栈官网:https://www.proginn.com/03. 码市码市是 Coding 推出的互联网软件外包服务平台,意在连接需求方与广大开发者。让项目的需求方快速的找到合适的开发者,完成项目开发工作。码市官方网站:https://codemart.com/04. 猪八戒网猪八戒网创建于2006年,是服务中小微企业的人才共享平台。开创式地为人才与雇主搭建起双边市场,通过线上线下资源整合与大数据服务,实现人才与雇主精准无缝对接。找兼职的地方,主要是入门级项目,不适合专业程序员,只适合新手。猪八戒官网:https://luoyang.zbj.com/05. 开源众包开源众包–专业的软件众包平台,350万+ 优质开发者为您提供网站、APP、微信/小程序、企业应用等软件开发服务,有效降低企业 IT 软件开发成本、解决技术资源不足等问题。开源中国的众包平台,主要是以众包为主。开源众包官网:https://zb.oschina.net/06. 智城外包网智城外包网,聚合全国软件团队资源,官方认证,1小时响应,零交易佣金,托管安全保障。十年口碑运营,万家靠谱团队。免费比价,免费一站式外包项目管理工具。平台汇集软件咨询专家,软件技术专家,软件开发专家,软件开发公司,软件外包公司,软件外包公司。在线竞标模式,让IT外包项目和短期IT招聘、人力派遣需求可以获得高性价比的候选。海量资源池包括:网站设计、网站开发、手机应用开发、移动应用开发、安卓应用开发、苹果应用开发、微信应用开发、Java技术、C#技术、Web前端开发、IT人力外包、IT人力外派、IT人力短期招聘、技术合伙人、通用软件开发,SaaS软件实施,软件运维等服务门类。网官方网站:http://www.taskcity.com/07. 实现网北京实现与爱科技有限公司是一个互联网工程师兼职平台。解决创业公司招人难、成本高的问题。创业公司通过实现网可以快速预约知名互联网企业的工程师、设计师到自己的团队工作。上午预约工程师,最快晚上即可到班兼职。互联网工程师可以在实现网注册成为技术顾问,利用业余时间助力创业公司,并且获得以时薪为单位的报酬。目前已有9000+工程师或设计师可在线预约和支付,支付后工程师会到团队里坐班沟通,快速推进创业者的产品开发进度。实现网为企业提供BAT等名企背景的、靠谱的开发设计兼职人才和自由职业者,满足企业项目外包、驻场开发、远程兼职、技术咨询等短期人力需求。已服务2000多家企业,包括好未来、方正、人人贷、秒拍等知名企业。官方网站:https://shixian.com/08. 猿急送猿急送,一个高级技术共享平台,这里汇聚知名互联网公司的技术、设计、产品大牛,通过实际坐班、远程等方式,一对一为创业公司解决问题,提高创业效率。猿急送为您提供兼职程序员,兼职工程师信息,猿急送是一个高级技术共享平台,是优质的程序员兼职网站,这里汇聚BAT等知名互联网公司的技术开发、产品、设计大牛,通过实际坐班等方式,一对一为创业公司解决程序员、工程师等开发、产品设计能力问题。官方网站:https://www.yuanjisong.com/09. 人人开发人人开发基于可视化快速开发平台 - 捷得(Joget)/捷得云(Joget Cloud)(PaaS),集众多开发者资源,为企业提供企业管理软件服务。应用市场提供应用产品、插件的在线试用和销售,服务市场以威客众包模式提供管理软件定制开发服务,各类企业级应用开发服务,例如:协同OA产品,ERP,CRM,人事管理,项目管理,资产管理,设备管理等。官方网站:http://rrkf.com/10. 开发邦公司位于北京中关村科技园区核心区海淀园,成立于2010年,专注于为客户提供互联网软件技术开发与咨询服务,致力于利用互联网软件技术为客户提高效率、降低成本、提升效能、优化管理。团队核心成员均具有十年以上软件互联网技术开发经验,毕业于工科名校。至今,已成功执行近百个项目,涵盖管理软件、互联网系统、移动APP、前端互动开发等。先后为华为公司、商汤科技、工信部中国软件评测中心、神州数码、深鉴科技、中软集团、中国万网、中石油吐哈气举中心、华北电力大学、中科院科技政策与管理研究所、浪潮集团、ADI、世界五百强伊顿中国、北京外国语大学、51talk、勤邦生物、安龙基因等知名企业及机构提供过互联网软件技术开发与技术咨询服务。开发邦致力于成为企业业务互联网软件服务与咨询的定制方案提供商。官方网站:https://www.kaifabang.com/11. 电鸭社区电鸭社区旨在帮助更多人走上「只工作,不上班」的自由工作之路,我们是一个「分布式组织」,通过分享及行动带来积极的影响,相信点滴的力量能改变潮水的方向。官方网站:https://eleduck.com/12. 快码深圳快码科技成立于2014年11月,是一家创新型的互联网公司,致力于通过创新的开发方式,为软件技术开发行业带来改变,提供更快速、更高性价比的软件定制服务。“快码”的意思是“快速编写代码”。公司采用“专属项目经理 + 自有开发团队 + 平台程序员”的创新开发方式,严格按照互联网公司的标准来管理开发团队,确保每个项目都有充足的人员投入,确保项目的进度和开发质量。2015年,我们和全球最大的手游、APP云测试平台Testin达成战略合作协议,并获得Testin数百万的战略投资。目前平台已注册的开发者达到3万多人,涵盖各种开发语言与类型,可以提供开发的项目有iOS APP、安卓APP、微信公众号、PC网站、手机网站、微信小程序、桌面软件、智能硬件APP等。上线以来,我们已经完成了数千项目&任务的开发。创业灵感来自于快码团队的从业经验。在近十年的互联网技术经历中,对由于创业公司、外包公司人员不稳定,招聘困难、人手有限等问题而导致现有团队开发任务过重,开发进度缓慢等问题有着切身之痛,将在P2P旅游行业2年多的共享经济经验,和自身最熟悉的“软件开发”结合,创立了“快码”。快码将立足于代码开发,深耕行业,面向未来,通过持续的产品创新,为广大项目方、开发者提供专业的服务,为软件技术开发行业带来改变。快码是一个创新的软件开发平台。项目方可以更省钱、高效地完成项目的开发;开发者可以充分利用闲置时间,实现更高的商业价值!官方网站:https://www.kuai.ma/13. 英选英选,可信赖的软件外包服务。用优秀的人,做漂亮的产品,写干净的代码。平台以定制开发外包服务为主,也是外包项目平台。官方网站:https://www.yingxuan.io/14. UpworkUpwork 是全球最大的、最优秀的、最规范的综合类人力外包服务平台,由著名的 Elance 和 oDesk 合并。这里聚集 900 万来自全球各地的自由工作者,你肯定可以在找到适合你的职位。官方网站:https://www.upwork.com/15. FreelancerFreelancer 的工作类型覆盖了很多不同的领域,由程序开发到市场营销、广告、会计、法务等一系列的可以远程的工作。官方网站:https://www.freelance.com/16. DribbbleDribbble 不只是全球最受欢迎的设计师社区,同样是设计师寻找远程工作的好出处。自从被 Tiny 收购后,Dribbble 的招聘属性正在慢慢增强,试着持续 PO 出自己的好作品,等待你的伯乐,同样你可以关注 Jobs 页面,给心仪的 Team 提交简历。官方网站:https://dribbble.com/jobs17. RemoteokRemoteok 不仅提供最初的兼职类远程工作,还有全职类,签署合同类和实习类的工作。网站创始人 Pieter Levels 本身就是一名数字游民,他同样是 Nomadlist 的创始人。官方网站:https://remoteok.io/18. ToptalToptal 是一个高端一些的自由职业者平台,适合比较有经验和工作能力的远程工作者。它将企业与全球的软件工程师,设计师和业务顾问联系起来。官方网站:https://www.toptal.com/19. AngelListAngelList 主要是服务于初创公司和天使投资人的平台,这里还有初创公司提供的远程工作的机会,如果对远程加入初创公司感兴趣的,可以尝试一下。官方网站:https://angel.co/remote20. TopcoderTopcoder 通过算法比赛吸引世界顶级的程序员,他会将一下大型项目分割成很多小模块,通过竞赛的模式交给用户来做,优胜者可以拿到制定模块的奖金。附如何用明道云调取数千个API接口明道云的工作流已经支持推送与获取Webhook,有了这个功能,我们可以与互联网上丰富的API接口进行自由对接。学会了此技能,你会拓展出无穷无尽的使用场景,让自己的工作变得更智能、更高效。今天笔者就教会大家,如何在没有任何技术能力的基础上,学会调用这些API接口(以查询手机号归属地为例)第一步:找到合适的API接口网站目前,市面上已经有不少专门做API接口的网站,他们是整合了市面上已有的数据网站,或者自己拥有某项能力(例如图像识别)。这里为大家推荐几个:聚合数据(244个接口)聚合数据(www.juhe.cn)是位于苏州的一家公司,于2018年上线,在北京、杭州均设有数据处理中心。目前接口数量为244个,把这个放第一位,是因为他家的数据调取方式最方便,用起来很顺手。收费模式有免费和收费两种,收费的话需要提前充值,大部分扣费方式都是按照次数,在几分钱到几毛钱一条。iDataAPI(98个接口)iDataAPI(www.idataapi.cn)位于广州,2014年创办,目前接口数量为98个,特色是个人应用较多。万维易源(489个接口)万维易源(www.showapi.com)由昆明秀派科技有限公司在2015年成立,目前数据接口数量为489个,接口类型比较综合。极速数据(132个接口)极速数据(www.jisuapi.com)由杭州极速互联科技有限公司于2013年推出,接口数量不是很多,但胜在调取的方法非常简单。神箭云市场(44个接口)神剑云市场(www.shenjian.io)位于杭州,成立于2015年,这家不算一个典型的API集市网站,放在这里介绍是他家具有数据包的下载服务。例如,你只需要花149元,就能下载到所有的汽车型号相关数据,其他的还包括手机型号、药品、楼盘等。购买了这些数据,可以直接Excel导出,你可以把它导入到明道云中,做一些调用。API数据接口网站就介绍到这里,如果你有兴趣,还可以去研究一下百度云、阿里云的API市场,以及像企查查(查询企业工商信息)、高德地图、京东等独立数据提供商。第二步:确定你的使用需求由于这些接口数量众多,你最好不要一开始都指望都全部用上,先从一个做起,熟悉一下平台最好。如何找到应用场景呢?这里提供两条思路:如果你不知道自己需要什么接口,那么:阅读API接口说明,得到启发后,用在业务上反之,那么直接去API市场中搜索相应的接口我们这里以下场景为例来研究API的调用方法:场景:在销售管理中,每天都大量的线索生成,如果您的业务是面向全国,可能要根据客户的手机号归属地,去分配给不同城市的销售跟进。分析:拿到这个需求后,我们需要的API是查询手机号归属地,那么市面上有没有类似接口呢?当然,而且大部分都是免费的。读懂API调用规则:我们以聚合数据为例,首先找到这个API接口,看一下他的说明,在请求示例中,我们看到只需要以这种格式,往这个地址发送一个请求就行了:http://apis.juhe.cn/mobile/get?phone=13429667914&key=您申请的KEY其中phone=后面是你要查询的手机号,key=是你申请的Key,相当于调用密码/凭证(你申请此数据接口后,可以在账号后台后台看到该Key,如下图)第三步:设置明道云工作流Webhook现在我们回到明道云中,这是一家教育机构的销售线索表,给不同的销售去跟进。提示:你可以使用明道云的公开表单功能来搜集销售线索,当客户填写后,会自动进入该销售线索表中。设置工作流打开工作流,选择触发webhook,然后如图设置,其中:绿色的部分,是设置销售线索中的手机号Key=(填写您的聚合数据该接口的key)你可以预先手动填写一个手机号,获取一个数据模版获取到数据后,就可以更新到销售线索表中了,关于工作流Wehhook的用法,可以参考帮助文档:《Webhook:如何请外部系统API请求数据,并写入工作表》效果检查当生成一条新线索时,可以看到这里已经有了手机号归属地。提示:你还可以通过工作流,自动监测手机号归属地,然后自动分配给不同地区的销售总结以上设置就全部完成了,复杂吗?根据这个教程,一步步来,一定可以完成设置。看完之后,如果你想设计出更多有意思的场景,建议您:阅读这些API的说明,看看能获得哪些启发记录您的需求,然后去API市场去寻找相应接口
2023年12月07日
0 阅读
0 评论
0 点赞
2023-12-07
深度揭秘(验证码识别程序下载)验证码识别平台是干嘛的,工具应用:利用Tesseract-OCR实现验证码识别,tesseract ocr java,
实验简介 光学字符识别(OCR,Optical Character Recognition)是指对文本资料进行扫描,然后对图像文件进行分析处理,获取文字及版面信息的过程。OCR技术非常专业,一般多是印刷、打印行业的从业人员使用,可以快速的将纸质资料转换为电子资料。Tesseract的OCR引擎最先由HP实验室于1985年开始研发,至1995年时已经成为OCR业内最准确的三款识别引擎之一。Tesseract目前已作为开源项目发布在Google Project,其最新版本3.0已经支持中文OCR,并提供了一个命令行工具。验证码是一种区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式。由于验证码可以由计算机生成并评判,但是必须只有人类才能解答,所以回答出问题的用户就可以被认为是人类。但是在我们的测试开发过程中,难免会存在需要使用到验证码的时候,所以本实验则主要利用Java通过封装Tesseract-OCR命令和调用Tess4J两种方式,实现验证码的识别。实验目的 (1)理解验证码的工作原理和应用场景。(2)熟练使用Tesseract-OCR的命令完成对一张图片验证码的识别。(3)使用Java调用Tesseract-OCR的命令完全图片的验证码自动化处理。(4)使用Tess4J完成验证码的识别处理。(5)利用Java通过封装完成对一个站点的验证码自动化识别处理。实验流程 关于验证码验证码是防止程序对一个站点发起自动化请求的很重要的一种手段,特别是实现登录的过程,向站点提交数据的过程等,我们必须有一种机制防止自动化程序向网站发起请求。所谓道高一尺,魔高一丈。验证码和破解验证码就在双方的拉锯战中越来越厉害,越来越难以破解。目前的验证码通常的种类及特点如下:(1)最基础的英文验证码:纯粹的英文与数字组合,白色背景,这是最容易实现OCR识别的验证码。(2)字体变形的英文验证码:可以通过简单的机器学习实现对英文与数字的识别,准确率较高。(3)加上扰乱背景线条的验证码:可以通过程序去除干扰线,准确率较高。(4)中文验证码:中文由于字体多样,形状多变,数量组合众多,实现起来难度较大,准确率不高。(5)中文字体变形验证码:准确率更低。(6)中英文混合验证码:非常考验OCR程序的判断能力,基本上识别起来非常有难度。(7)提问式验证码:这是需要OCR结合人工智能才能实现,目前基本上无法识别。(8)GIF动态图验证码:由于GIF图片是动态图,无法定位哪一帧是验证码,所以难度很大。(9)划动式验证码:虽然程序可以模拟人的操作,但是具体拖动到哪个位置很难处理。(10)视频验证码:目前OCR识别还未实现。(11)手机验证码:手机验证码实现自动化是很容易的,但是手机号码不那么容易获得。(12)印象验证码:目前无解。我们可以看到上述形形色色的验证码,目前用纯粹的技术手段是很难处理验证码问题的。所以,也有很多人看到这件事情的价值,专门雇佣大量人员帮助客户实现人工打码,把它变成了一门生意。2. Tesseract-OCR基础使用(1)下载Tesseract-OCR,官方网站为:https://sourceforge.net/projects/tesseract-ocr-alt/files/ 。(2)安装Tesseract-OCR,建议安装在不包含空格的路径里,不要安装在默认的Program Files文件夹。比如笔者的安装路径为:C:\Tools\Tesseract-OCR 。(3)在环境变量中添加TESSDATA_PREFIX变量,值为OCR安装目录:C:\Tools\Tesseract-OCR。(4)准备一些英文和数字的验证码,可以带背景干扰线。比如将此验证码图片保存在D:\Other\VerifyCode目录中。(5)打开CMD命令行程序,执行如下命令,即可将识别到的验证码内容输出到一个.txt文本文件中。C:/Tools/Tesseract-OCR/tesseract.exe D:/Other/VerifyCode/myverifycode.jpgD:/Other/VerifyResult/output我们来看看具体的运行效果:我们可以看到,tesseract.exe是执行识别的主命令,后面跟的第一个参数为指定验证码图片所在的路径和文件名,第二个参数为识别结果的输出路径,此处指输出到文件D:/Other/VerifyResult/output.txt中,但是我们不需要在后面特别添加.txt后缀。(6)如果我们想实现中文的验证,则需要下载中文训练字库文件,文件名为:chi_sim.traineddata,将该文件下载到电脑后,保存至C:\Tools\Tesseract-OCR\tessdata文件夹中。(7)识别中文验证码时只需要在正常命令后面添加“ –l chi_sim”指定训练字库文件即可。C:/Tools/Tesseract-OCR/tesseract.exe 验证码所在路径 结果输出路径 -l chi_sim事实上,Tesseract-OCR默认使用的是英文字库,字库名称为eng.traineddata,我们也可以下载更多的字库来对其识别的准确率进行扩展。3. 使用Java调用Tesseract-OCR命令完成识别由于Tesseract-OCR并没有专门提供编程接口,所以我们不能直接通过引入Jar包的方式来进行调用。但是由于Tesseract-OCR是通过命令来完成识别的,所以我们就可以让Java去执行这段命令。并且识别到的结果也是输出到文件中,所以我们自然可以利用Java去读取这段文本内容,进而获得识别到的结果。下面我们来看看具体的实现过程。(1)Java执行Windows命令主要通过Runtime对象来完成。所以我们自然会需要调用该对象执行命令。(2)由于命令当中有三个核心参数,验证码路径,输出路径,字库名称,所以我们需要使用编程的方式对该参数进行拼接,最后变成一个字符串完成命令的发送和执行。(3)我们的验证码图片的路径和名称不一样,所以我们的识别程序应该将其参数化。同时,也可根据自身需要对三个核心参数均使用形式参数的方式在调用该识别程序时传递进来。(4)我们需要判断命令是否执行成功,如果没有执行成功,则提示出错信息,否则,读取该输出文件的内容,并将其结果返回给调用该程序的地方。核心代码实现如下,读者可根据自身需要进行修改和优化。package com.woniuxy.misc;import java.io.*;public class TesseractOCR {public static void main(String[] args) throws Exception {TesseractOCR ocr = new TesseractOCR();String result = ocr.recognizeText("D:/Other/VerifyCode/1483451259840.jpg", true);System.out.println(result);}public String recognizeText(String imageFile, boolean isChinese) {String result = ""; // 保存读取到的识别内容并返回String tesseractExe = "C:/Tools/Tesseract-OCR/tesseract.exe";String output = "D:/Other/VerifyResult/output";// 根据选项组装执行命令的字符串,注意参数之间需要加空格分隔开String command = tesseractExe + " " + imageFile + " " + output;if (isChinese) {command += " -l chi_sim";}System.out.println(command); // 对输出命令进行确认,成功后该行代码 可删除try {// 使用Process来获取执行命令的结果,并对其结果进行判断Process process = Runtime.getRuntime().exec(command);int exeCode = process.waitFor();// 执行的结果代码如果为0,表示命令执行成功if (exeCode == 0) {// 读取到输出文件中的内容,并将其赋值给变量resultInputStream fis = new FileInputStream(output + ".txt");InputStreamReader isr = new InputStreamReader(fis,"UTF-8");BufferedReader br = new BufferedReader(isr);result = br.readLine();br.close();}else {System.out.println("本次识别操作命令未正常执行.");}}catch (Exception e) {e.printStackTrace();}return result;}}4. 如何实现站点验证码的自动识别事实上,上述过程中我们已经将验证码的识别设置了自动化处理了。但是是基本文件的图片,而通常情况下,我们要识别的验证码是基于网络的,所以我们需要再提前完成一件事情,利用Java代码完成验证码的自动下载和保存,代码如下:public void download(String src, String path) {int dlstatus;try {// 发送HTTP的GET请求获取到验证码图片URL url = new URL(src);File outFile = new File(path);HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();urlConnection.connect();dlstatus = urlConnection.getResponseCode();if (dlstatus < 400) {// 通过字节流读取的方式将得到的图片字节码写入到输出文件中OutputStream os = new FileOutputStream(outFile);InputStream is = urlConnection.getInputStream();byte[] buff = new byte[4096];while(true) {int readed = is.read(buff);if(readed == -1) {break;}byte[] temp = new byte[readed];System.arraycopy(buff, 0, temp, 0, readed);os.write(temp);}is.close();os.close();dlstatus = 200;}else {System.out.println("下载验证码图片失败,请确认.");}urlConnection.disconnect();}catch (Exception e) {e.printStackTrace();}}5. 针对某个具体的站点实现自动化操作前面的很多实验我们已经了解了如何利用Java的协议通信API对象实现请求的发送和接收,以及处理HTTP的无状态特性等。那么,现在,我们不妨综合利用前面的知识,来试着完整地完成一个有验证码的操作。在此,笔者不提供代码实现,而是给大家提供一个关键思路:(1)利用协议分析工具,分析验证码图片的生成机制,确认是否可以将该验证码下载到本地。(2)获取到一个有效的验证码图片的地址,如果图片地址是动态生成的,则查看是否有规律可循环。(3)利用download()方法实现对该图片的下载。(4)利用recognizeText()方法识别到该图片的内容。(5)利用sendPost()方法实现请求的发送和响应的处理。6. 利用Java代码去除干扰线这是笔者在网络上收获的一段非常有价值的代码,在些对热心奉献的网友表示感谢。这段代码通过对图片进行像素级的处理,将一些颜色偏淡一点的背景杂色干扰线等进行了过滤,使得识别率变得更加准确。笔者亲测,效果不错。网址为: http://blog.csdn.net/lmj623565791/article/details/23960391/ 7. 如果验证码搞不定怎么办通常情况下,我们要去识别验证码不一定是为了测试我们自己的项目,而是为了去干一些坏事。所以,这是大家一定要慎重的地方。我们在自己的测试项目中,如果真的出现验证码根本无法识别,而我们又需要绕开验证码,应该怎么办呢?方法很简单,让研发团队协助我们开发一个万能的验证码,或者在测试环境中取消验证码就好了。思考练习 (1)如果自己正在测试的项目遇到复杂的验证码,应该如何处理。(2)了解一下关于图像处理和人工智能方面的知识。
2023年12月07日
0 阅读
0 评论
0 点赞
2023-12-07
万万没想到(在java里如何读取文件内容)java中如何读取文件,在Java里如何读取文件,java打开文件,
1.概述在这篇文章里, 我们将探索不同的方式从文件中读取数据。首先, 学习通过标准的的Java类,从classpath、URL或者Jar中加载文件。然后,学习通用BufferedReader, Scanner, StreamTokenizer, DataInputStream, SequenceInputStream, FileChannel读取文件内容。也会讨论如何读取UTF-8编码的文件。最后,学习Java7和Java8中新的加载和读取文件的技术。2.准备2.1 输入文件这篇文章的很多示例,从名为fileTest.txt的文件读取文本内容,文件包含Hello,World!有少量示例, 我们会读取不同的文件, 示例中会有说明。2.2 辅助方法很多示例都会用到共用的方法readFromInputStream, 该方法将InputStream转化String private String readFromInputStream(InputStream inputStream)throwsIOException{StringBuilder resultStringBuilder = new StringBuilder();try (BufferedReader br= new BufferedReader(newInputStreamReader(inputStream))) {String line;while ((line = br.readLine()) != null) {resultStringBuilder.append(line).append("\n");}}returnresultStringBuilder.toString();}3.从Classpath读取文件3.1 使用标准Java从src/main/resources读取文件fileTest.txt @Testpublic void test() throws IOException {String expectedData = "Hello,World!";Class<ReadFileTest> clazz = ReadFileTest.class;InputStream inputStream = clazz.getResourceAsStream("/fileTest.txt");String data = readFromInputStream(inputStream);Assert.assertThat(data, containsString(expectedData));}在上面的代码中,我们通过当前类的getResourceAsStream方法加载文件,入参是绝对路径。ClassLoader中相同的方法也可以使用。ClassLoader classLoader = getClass().getClassLoader();InputStream inputStream = classLoader.getResourceAsStream("fileTest.txt");String data = readFromInputStream(inputStream);这两种方法的主要区别是, 当前类的ClassLoader的getResourceAsStream方法,入参路径是从classpath开始。而类实例的入参是相对于包路径,但路径开始使用/符号, 也是绝对路径。特别要注意的是, 文件打开读取完数据后, 始终需要关闭inputStream.close();3.2 使用commons-io库另一个比较常用的方法是使用commons-io包里的FileUtils.readFileToString方法。 <dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>1.4</version></dependency> @Testpublic void useCommonIO() throws IOException {String expectedData = "Hello,World!";ClassLoader classLoader = getClass().getClassLoader();File file = new File(classLoader.getResource("fileTest.txt").getFile());String data = FileUtils.readFileToString(file,"UTF-8");assertEquals(expectedData, data.trim());}该方法入参是File对象。这个工具类的优点是不用编码InputStream实例的相关代码。这个库还提供了IOUtils类。 @Testpublic void useCommonIO2() throws IOException {String expectedData = "Hello,World!";FileInputStream fis = newFileInputStream("src/test/resources/fileTest.txt");String data = IOUtils.toString(fis, "UTF-8");assertEquals(expectedData, data.trim());}4.BufferedReader@Testpublic void bufferedReader() throws IOException {String expected_value = "Hello,World!";String file ="src/test/resources/fileTest.txt";BufferedReader reader =new BufferedReader(new FileReader(file));StringcurrentLine = reader.readLine();reader.close();assertEquals(expected_value, currentLine);}当读取结束的时候, reader.readLine()会返回null5.Java NIONIO是在JDK7中添加。5.1读取小文件首先看一下关于Files.readAllLines的示例 @Testpublic void readSmallFile() throws IOException {String expected_value = "Hello,World!";Path path = Paths.get("src/test/resources/fileTest.txt");String read = Files.readAllLines(path).get(0);assertEquals(expected_value, read);}入参Path对象,Path可以认为是java.io.File的升级版本,提供一些额外的功能。如果读取的是二进制文件,可以使用Files.readAllBytes()方法5.2读取大文件如果想要读取大文件, 我们可以使用Files类和BufferedReader类。 @Testpublic void readLargeFile() throws IOException {String expected_value = "Hello,World!";Path path = Paths.get("src/test/resources/fileTest.txt");BufferedReader reader = Files.newBufferedReader(path);String line = reader.readLine();assertEquals(expected_value, line);}5.3Files.lines在JDK8中,Files类增加了lines方法,这个方法将返回Stream<String>。跟文件操作一样,Stream需要显式调用的close()。Files API提供了很多简单读取文件的方法。6.Scanner下面我们将使用Scanner读取文件,使用逗号(,)作为定界符(delimiter)。@Testpublic void whenReadWithScanner_thenCorrect()throws IOException {String file = "src/test/resources/fileTest.txt";Scanner scanner = new Scanner(new File(file));scanner.useDelimiter(",");assertTrue(scanner.hasNext());assertEquals("Hello", scanner.next());assertEquals("World!", scanner.next());scanner.close();}Scanner默认的定界符是空格。它适用于从控制台读取输入或者内容有固定定界符的内容时。7.StreamTokenizertokenizer会指出下一个token的类型,String或Number。tokenizer.nval - 如果类型为Number时,读取该字段tokenizer.sval - 如果类型为String时,读取该字段@Testpublic void readWithTokenize()throws IOException {String file = "src/test/resources/fileTestTokenizer.txt";FileReader reader = newFileReader(file);StreamTokenizer tokenizer =new StreamTokenizer(reader);// 1tokenizer.nextToken();assertEquals(StreamTokenizer.TT_WORD, tokenizer.ttype);assertEquals("Hello", tokenizer.sval);// 2tokenizer.nextToken();assertEquals(StreamTokenizer.TT_NUMBER, tokenizer.ttype);assertEquals(1, tokenizer.nval, 0.0000001);// 3tokenizer.nextToken();assertEquals(StreamTokenizer.TT_EOF, tokenizer.ttype);reader.close();}8.DataInputStream如果要读取二进制文件或者原生数据,可以使用DataInputStream@Testpublic void whenReadWithDataInputStream() throws IOException {String expectedValue = "Hello,World!";String file ="src/test/resources/fileTest.txt";String result = null;DataInputStream reader = new DataInputStream(new FileInputStream(file));intnBytesToRead = reader.available();if(nBytesToRead > 0) {byte[] bytes = new byte[nBytesToRead];reader.read(bytes);result = newString(bytes);}assertEquals(expectedValue, result);}9.FileChannel如果读取的是一个大文件,FileChannel速度会超过standard IO。@Testpublic void whenReadWithFileChannel()throws IOException {String expected_value ="Hello,World!";String file = "src/test/resources/fileTest.txt";RandomAccessFile reader = new RandomAccessFile(file, "r");FileChannel channel = reader.getChannel();int bufferSize = 1024;if (bufferSize > channel.size()) {bufferSize = (int) channel.size();}ByteBuffer buff = ByteBuffer.allocate(bufferSize);channel.read(buff);buff.flip();assertEquals(expected_value,newString(buff.array()));channel.close();reader.close();}10.读取utf-8编码的文件@Testpublic void whenReadUTFEncodedFile()throws IOException {String expected_value = "你好,世界!";String file = "src/test/resources/fileTestUtf8.txt";BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));String currentLine = reader.readLine();reader.close();assertEquals(expected_value, currentLine);}11.从URL读取数据@Testpublic void readFromURL() throws IOException {URL urlObject = new URL("https://www.baidu.com");URLConnection urlConnection = urlObject.openConnection();InputStream inputStream = urlConnection.getInputStream();String data = readFromInputStream(inputStream);}12.从jar包中读取文件我们的目标是读取junit-4.12.jar包中的LICENSE-junit.txt文件。clazz只需要这个Jar中的类就行。@Testpublic void readFromJar() throws IOException {String expectedData = "Eclipse Public License";Class clazz = Test.class;InputStream inputStream = clazz.getResourceAsStream("/LICENSE-junit.txt");String data = readFromInputStream(inputStream);Assert.assertThat(data, containsString(expectedData));}
2023年12月07日
0 阅读
0 评论
0 点赞
1
2
...
283