`
LilyEnjoyingLife
  • 浏览: 70593 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

java 多个线程操作同一文件夹下的文件 代码,遇到的问题及解决方案

    博客分类:
  • java
阅读更多

最近课程需要,写了一个抓取新浪微博数据存入文件中再将文件所在路径传给服务器的小程序,主要思想是,两个线程,一个用来从新浪微博不断抓取数据,实时地新建文件,写入文件,另一个线程则负责在这些文件所在的文件夹中实时地读取文件,得到文件名列表,将没传给服务器的文件名传给服务器。

 

代码如下(只贴一个演示原理的代码吧):

 

主程序

Java代码 复制代码
  1. public static void main(String[] args) throws Exception   
  2.     {   
  3.         //抓取微博数据并写入D:\\weibo\\status\\,D:\\weibo\\comment\\   
  4.         WBDataRetriver retriver = new WBDataRetriver();   
  5.         retriver.start();   
  6.         //读取D:\\weibo\\status\\ 目录中的文件,把文件夹中文件名列出来发送服务器   
  7.      Client statusReader = new Client("D:\\weibo\\status\\");   
  8.         statusReader.start();   
  9.        //读取D:\\weibo\\comment\\ 目录中的文件,把文件夹中文件名列出来发送服务器   
  10.      Client commentReader = new Client("D:\\weibo\\comment\\");   
  11.         commentReader.start();   
  12.   }   

 //client 线程,当文件夹中有新的文件加进来的时候能提取新加入的文件名传给服务器,传的字符串格式自定义

Java代码 复制代码
  1. import java.io.File;   
  2. import java.io.IOException;   
  3. import java.io.PrintWriter;   
  4. import java.net.InetAddress;   
  5. import java.net.Socket;   
  6. import java.util.HashSet;   
  7.   
  8. public class Client extends Thread   
  9. {   
  10.     private Socket client;   
  11.   
  12.     private HashSet<String> isReaden;   
  13.     //这里先不从server读取确认信息   
  14.     // private BufferedReader in;   
  15.   
  16.     private PrintWriter out;   
  17.   
  18.     private String filePath;   
  19.   
  20.     public Client(String filePath) throws Exception, IOException   
  21.     {   
  22.         this.isReaden = new HashSet<String>();   
  23.         this.client = new Socket(InetAddress.getLocalHost(), 9081);   
  24.         // this.in = new BufferedReader(new   
  25.         // InputStreamReader(this.client.getInputStream()));   
  26.         this.out = new PrintWriter(this.client.getOutputStream());   
  27.         this.filePath = filePath;   
  28.     }   
  29.   
  30.     public HashSet<String> getIsReaden()   
  31.     {   
  32.         return isReaden;   
  33.     }   
  34.   
  35.     public boolean isReaden(String fileName)   
  36.     {   
  37.         if (fileName == null || this.isReaden.contains(fileName))   
  38.         {   
  39.             return true;   
  40.         }   
  41.         this.isReaden.add(fileName);   
  42.         return false;   
  43.     }   
  44.   
  45.     public void run()   
  46.     {   
  47.         try  
  48.         {   
  49.             process();   
  50.         }   
  51.         catch (Exception e)   
  52.         {   
  53.             // TODO Auto-generated catch block   
  54.             e.printStackTrace();   
  55.         }   
  56.     }   
  57.   
  58.     public void process() throws Exception   
  59.     {   
  60.         File file = null;   
  61.         while (true)   
  62.         {   
  63.             file = null;   
  64.             file = new File(this.filePath);   
  65.             File[] fileArray = file.listFiles();   
  66.             // 遍历文件列表   
  67.             for (int i = 0; i < fileArray.length; i++)   
  68.             {   
  69.                 // 如果是文件类型   
  70.                 if (fileArray[i].isFile())   
  71.                 {   
  72.                     String fileName = fileArray[i].getName().trim();   
  73.                     // 如果已读取的文件中没有这个文件,则发送   
  74.                     if (!isReaden(fileName))   
  75.                     {   
  76.                         String[] temp = fileName.split("_");   
  77.                         // if (temp.length < 3)   
  78.                         // {   
  79.                         // continue;   
  80.                         // }   
  81.                         String url = "1&"  
  82.                                      + fileArray[i].getAbsolutePath()   
  83.                                      + "&"  
  84.                                      + temp[0]   
  85.                                      + "&"  
  86.                                      + temp[1]   
  87.                                      + "&"  
  88.                                      + temp[2];   
  89.                         // 发送给服务器内容!   
  90.                         System.out.println("sent to server : " + url);   
  91.                         out.println(url);   
  92.                         out.flush();   
  93.                     }   
  94.                     else  
  95.                     {   
  96.                         continue;   
  97.                     }   
  98.                 }   
  99.             }   
  100.             // // 注意这里!!!输出从server中读取的内容,如果server返回的内容中不包含/n则readline会堵塞在这里 不进入下一个循环   
  101.         // String temp = in.readLine();   
  102.             // if (temp.contains("end"))   
  103.             // {   
  104.             // break;   
  105.             // }   
  106.             // else   
  107.             // {   
  108.             // System.out.println("server said : " + temp);   
  109.             // }   
  110.             // //每隔3秒重复读取   
  111.             sleep(300);   
  112.         }   
  113.         // client.close();   
  114.     }   
  115. }  

 

//server端 比较简单的输出接收的文件名并返回给client一个反馈

Java代码 复制代码
  1. import java.net.*;   
  2. import java.io.*;   
  3.   
  4. public class Server extends Thread {   
  5.     private Socket server;   
  6.   
  7.     public Server(Socket c) {   
  8.         this.server = c;   
  9.     }   
  10.   
  11.     public void run() {   
  12.         try {   
  13.             BufferedReader in = new BufferedReader(new InputStreamReader(   
  14.                     server.getInputStream()));   
  15.             PrintWriter out = new PrintWriter(server.getOutputStream());   
  16.             while (true) {   
  17.                 String str = in.readLine();   
  18.                 System.out.println(str);   
  19.                 out.println("received "+str);   
  20.                 out.flush();   
  21.                 if (str.equals("end"))   
  22.                     break;   
  23.             }   
  24.             server.close();   
  25.         } catch (IOException ex) {   
  26.                ex.printStackTrace();   
  27.         }   
  28.     }   
  29.   
  30.     public static void main(String[] args) throws IOException {   
  31.         ServerSocket server = new ServerSocket(9081);   
  32.         while (true) {   
  33.             Server mu = new Server(server.accept());   
  34.             mu.start();   
  35.         }   
  36.     }   
  37. }  

运行程序时发现一个问题,写文件的线程正常运行,不断产生新文件,但是两个读文件的线程却像被‘卡住’了,不能增量读取新加入的文件名给服务器,开始时还在想难道是多线程共同操作一个文件夹也需要什么锁吗,后来发现不是!注意client中while的后半部分(被注释掉的几行),这里client等待server反馈并输出从server中读取的内容,但是如果server返回的内容中不包含/n则readline会堵塞在这里 不进入下一个循环,因此造成“卡住”的情况,所以两端之间的通信内容要注意格式(这里如果client一定要输出服务器的反馈,那么可以对服务器返回的内容做一些处理,比如如果客户端送过来的内容是null的,也返回一个带/n的串)。

 

顺带着了解了java的HashSet和ArrayList和Array的比较,见这位博主的链接:http://www.diybl.com/course/3_program/java/javajs/20071111/85300.html

 

谢谢zz指点~加油~

 

 

 

0
0
分享到:
评论

相关推荐

    下载网络图片 (整合多线程、内存缓存、本地文件缓存~)

    本文将深入探讨如何在Java环境下,结合多线程、内存缓存和本地文件缓存技术,实现高效且可靠的网络图片下载功能。 首先,多线程是提高应用程序性能的关键。在下载网络图片时,如果使用单线程,当请求大量图片时,...

    JAVA基于局域网的聊天室系统(源代码+论文)

    ".rar"文件是压缩格式,通常包含多个文件或文件夹,这里可能包括了项目的源代码文件、编译后的可执行文件、配置文件以及论文文档。"上传专用.txt"可能是上传者提供的额外说明文件,可能包含关于如何使用源代码、运行...

    java小代码

    以上就是Java小代码可能涵盖的一些关键知识点,实际的小代码可能涉及其中的一个或多个方面,通过实践和学习,开发者能够不断提升Java编程能力,解决复杂的问题。在【新建文件夹】中,可能包含了各种这样的小代码示例...

    多线程序示例:赛马程序

    `Threads.sln`就是这个赛马程序的解决方案文件,打开它可以加载整个工程,包括相关的源代码、配置信息等。 `Threads`可能是一个包含源代码的项目文件夹,其中可能有`.cpp`或`.c`文件,这些文件包含了实现赛马程序...

    Mutual-Exclusion-for-Distributed-Systems:设计并开发了一个系统,该系统使用 Maekawa 基于仲裁的互斥协议,允许多个请求站点中的一个站点在给定时间使用 SCTP 和 Java 中的多线程进入临界区

    4. `CountDownLatch`和`CyclicBarrier`:用于协调多个线程的启动或同步点。 在 Mutual-Exclusion-for-Distributed-Systems-master 文件夹中,源代码可能包含了实现Maekawa协议、SCTP通信以及Java多线程的类和方法。...

    java学习资源

    9. **设计模式**:设计模式是解决常见编程问题的标准化解决方案,如单例模式、工厂模式、观察者模式等,熟练掌握设计模式可以提高代码的可读性和可维护性。 10. **框架应用**:Spring框架是Java开发中的常用框架,...

    Java netbeans oracle数据库写的局域网扫描程序

    6. **多线程**:可能涉及到并发编程,因为扫描多个设备或端口时,使用多线程可以提高效率。 7. **异常处理**:学习了如何在代码中正确地捕获和处理可能发生的网络和数据库异常。 8. **软件工程实践**:如代码组织...

    Java极品学习资料

    - 类文件冲突通常发生在多个不同版本的类文件同时存在于类路径中。 - 解决方案包括调整类路径、使用特定版本的类文件等。 - 示例代码说明如何避免类文件冲突。 **基本数据类型强制转换** - 强制类型转换用于将一个...

    thinking-in-java-exercises:我的练习解决方案来自Bruce Eckel着名的Java书籍“ Thinking in Java 4th edition”

    在"thinking-in-java-exercises-master"这个文件夹中,很可能包含了上述各种主题的练习题目和解决方案。通过分析和解决这些练习,读者不仅可以加深对Java的理解,还能提升解决问题的能力。这种实践性的学习方式对于...

    Java经典面试题+答案(带书签)pdf

    - 锁是一种实现同步的技术手段,用于控制多个线程对共享资源的访问。 **6. 多线程中stop为什么不合适** - `stop`方法已被废弃,因为它可能导致数据不一致等问题。 - 更安全的做法是使用标志位控制线程的运行。 **...

    基于consul的分布式锁工具,包含:互斥锁、信号量等工具

    - **信号量**:信号量允许多个线程同时访问共享资源,但会限制并发数量。在Java中,`java.util.concurrent.Semaphore`类可以实现信号量。 3. **基于Consul的分布式锁实现** 在这个项目中,通过Consul的KV存储实现...

    c#学习笔记.txt

    接口可以从多个基接口继承,而类或结构可以实现多个接口。接口可以包含方法、属性、事件和索引器。接口本身不提供它所定义的成员的实现。接口只指定实现该接口的类或接口必须提供的成员。接口可以是命名空间或类的...

    wordtohtml

    `wordtohtml` 工具提供了一个简单而有效的解决方案,用于批量转换 `.doc` 文件为 HTML 格式。通过 Java 编程语言和 `com.jacob` 库的强大功能,实现了高效的文件转换任务。对于需要处理大量 Word 文档的用户来说,这...

    IdeaProjects:Java的

    7. **多线程**:Java内置对多线程的支持,通过Thread类或实现Runnable接口可以创建并运行多个执行线程。 8. **网络编程**:Java的Socket编程允许开发网络应用程序,进行客户端-服务器通信。 9. **泛型**:泛型提供...

    基于Android的WIFI局域网聊天完整源码

    【标题解析】 ...综上所述,这个项目涵盖了Android应用程序开发的多个核心方面,涉及网络通信、UI设计、多线程处理等多个知识点,对于学习Android即时通讯和P2P技术的开发者来说,是一个非常有价值的参考资源。

    局域网聊天程序.需要服务器

    开发人员可能使用了多种编程语言(如C++、Java或Python)和框架,涉及网络编程、多线程、数据库管理等多个IT领域的知识点。同时,考虑到用户体验,还可能运用了图形用户界面设计和前端技术。对于学习网络通信、软件...

    NetDiscovery 是一款基于 Vert.x、RxJava 2 等框架实现的通用爬虫框架_中间件。.zip

    在爬虫框架中,这种特性意味着 NetDiscovery 可以并行处理多个请求,避免了传统同步模型中的线程阻塞问题,提高了爬取效率。 RxJava 2 是一个用于处理异步数据流的库,它引入了 Observables(可观察者)的概念,将...

    Log4cxx 使用文档

    Log4cxx是Apache Logging Service下的一个开源项目,它是基于Java社区著名日志工具log4j的C++版本,专门为C++应用程序提供强大的日志记录功能。通过Log4cxx,开发人员能够方便地在C++程序中集成日志功能,这对于调试...

    Java101:练习我的Java技能

    在"Java101-main"这个文件夹中,你可以找到相关的代码示例、练习和可能的解决方案,这些都是加深理解和实践Java知识的宝贵资源。通过系统学习和不断实践,你将能掌握Java编程的核心技能,为更高级的主题打下坚实基础...

Global site tag (gtag.js) - Google Analytics