在java中删除文件,同时在其他线程中上传文件

发布于 2024-09-06 05:32:21 字数 250 浏览 6 评论 0原文

我正在尝试构建一个半文件共享程序,当每台计算机既充当服务器又充当客户端时。

我为多个线程提供了从系统中 DL 文件的选项。

另外,我有一个可以接收删除消息的用户界面。

我的问题是,我希望在收到删除消息的那一刻,我等待所有 DL 文件的线程完成 DL,并且只执行 file.delete()。 最好的方法是什么?

我想到了一些包含 > 的数据库并迭代并检查线程是否处于活动状态,但这看起来很笨拙。有更好的办法吗? 谢谢

i'm trying to build a semi file sharing program, when each computer acts both as a server and as a client.

I give multiple threads the option to DL the file from my system.

also, i've got a user interface that can recieve a delete message.

my problem is that i want that the minute a delete message receieved, i wait for all the threads that are DL the file to finish DL, and ONLY than excute file.delete().
what is the best way to do it?

I thought about some database that holds > and iterate and check if the thread is active, but it seems clumsy. is there a better way?
thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你如我软肋 2024-09-13 05:32:21

我认为你可以比使用数据库更简单地做到这一点。我会在 File..a TrackedFile 周围放置一个薄包装类。它里面有文件,以及正在阅读该文件的人数的计数。当您执行删除操作时,只需停止允许新人获取该文件,并等待计数达到 0。

由于您正在处理访问共享状态的许多线程,因此请确保正确使用 java.util.concurrent

I think you can do this more simply than using a database. I would put a thin wrapper class around File.. a TrackedFile. It has the file inside, and a count of how many people are reading it. When you do to delete, just stop allowing new people to grab the file, and wait for the count to get to 0.

Since you are dealing with many threads accessing shared state, make sure you properly use java.util.concurrent

心碎的声音 2024-09-13 05:32:21

我不确定这是否能解决您的所有问题,但这就是我的想法:

假设所有读/写/删除操作仅发生在同一应用程序内,则使用锁的线程同步机制可能会很有用。

对于到达的每个新文件,可以创建一个新的读/写锁(请参阅 Java 的 ReentrantReadWriteLock)。所有读操作都应该获取读锁,而写/删除操作都应该获取写锁。当然,当获得锁时,您应该检查该操作是否仍然有意义(即文件是否仍然存在)。

I am not sure this addresses all your problems, but this is what I have in mind:

Assumming that all read/write/delete operations occur only from within the same application, a thread synchronization mechanism using locks can be useful.

For every new file that arrives, a new read/write lock can be created (See Java's ReentrantReadWriteLock). The read lock should be acquired for all read operations, while the write lock should be acquired for write/delete operations. Of course, when the lock is acquired you should check whether the operation is still meaningful (i.e. whether the file still exists).

雾里花 2024-09-13 05:32:21

如果您必须等待所有读者完成,您的删除事件处理线程(可能是您的 UI)将变得无响应。相反,将删除排队并定期轮询可处理的删除。您可以使用:

private class DeleteRunnable implements Runnable {
 public void run() {
  while (!done) {
   ArrayList<DeletedObject> tmpList = null;
   synchronized (masterList) {
    tmpList = new ArrayList<DeletedObjects>(masterList);
   }

   for (DeletedObject o : tmpList)
    if (o.waitForReaders(500, TimeUnit.MilliSeconds))
     synchronized (masterList) {
      masterList.remove(o);
     }
  }
 }
}  

Your delete event handling thread (probably your UI) will become un-responsive if you have to wait for all readers to finish. Instead queue the delete and periodically poll for deletions which can be processed. You can use:

private class DeleteRunnable implements Runnable {
 public void run() {
  while (!done) {
   ArrayList<DeletedObject> tmpList = null;
   synchronized (masterList) {
    tmpList = new ArrayList<DeletedObjects>(masterList);
   }

   for (DeletedObject o : tmpList)
    if (o.waitForReaders(500, TimeUnit.MilliSeconds))
     synchronized (masterList) {
      masterList.remove(o);
     }
  }
 }
}  
一梦等七年七年为一梦 2024-09-13 05:32:21

如果您要稍微重构您的设计,以便从磁盘加载文件和将文件上传到客户端不在同一线程中完成,您可以通过锁定新线程来读取此文件,从而等待文件停止被访问文件,然后迭代从该文件读取的所有线程,并对每个线程执行 join(),一次一个。只要文件读取线程在加载文件后直接终止,迭代就会在最后一个线程不再读取文件时完成,您就可以开始了。

以下段落基于这样的假设:即使读取线程都在相同的一般时间范围内读取,您仍会多次重新读取文件数据,因为这听起来像是您正在做的事情。

通过这种方式,将文件读取分离到单独的线程中,还可以让您使用单个线程加载特定文件,并让多个客户端上传从文件的单个读取过程中获取数据。您可以使用它来实现多种优化,具体取决于它所针对的项目类型。如果这样做,请确保内存中没有保存太多文件数据,否则就会发生明显的情况。但是,如果您的项目性质保证会有很少和/或小文件不会占用太多内存,那么将文件加载分离到单独的线程中会带来很大的副作用。

如果您使用 join() 这条路线,如果您希望删除线程能够等待一段时间然后要求其他线程停止(对于大文件和/或很多时候),则可以使用 join(milliseconds) 变体文件正在被访问,因此高清速度变慢)(如果尚未访问)。只需获取 (now + theDurationYouWantToWait) 的时间戳并加入 (impatentTimestamp-currentTimestamp),然后在 if(currentTimestamp >= impatentTimestamp) 循环中间向所有文件加载线程发送中断 - 然后进行文件加载线程在读取文件数据的循环中检查它,然后重新 join() 连接(毫秒)中止的线程并继续您正在执行的 join() 迭代。

If you were to restructure your design just slightly so that loading the file from disk and uploading the file to the client were not done in the same thread, you could wait for the file to stop being accessed simply by locking out new threads from reading this file, then iterating over all of the threads reading from that file and do a join() on each one, one at a time. As long as the file-reading threads terminate directly after loading the file, the iteration will finish the moment the last thread is no longer reading the file and you are good to go.

The following paragraph is based on the assumption that you keep re-reading the file data over multiple times, even if the reading threads are both reading during the same general time frame, since that's what it sounds like you're doing.

Doing it this way, separating file-reading into separate threads, would also allow you to have a single thread loading a specific file and to have multiple client-uploads getting the data from the single reading pass over the file. There are several optimizations you could implement with this, depending on what type of project this is for. If you do, make sure you don't keep too much file data in memory, or the obvious will happen. But if you are guaranteed by the nature of your project that there will be few and/or small files that will not take up too much memory, this is a great side effect of separating file-loading into a separate thread.

If you go this route of using join(), you could use the join(milliseconds) variant if you want the deletion thread to be able to wait a certain period then demand the other threads stop (for huge files and/or times when many files are being accessed so HD is going slow), if they haven't already. Just get a timestamp of (now + theDurationYouWantToWait) and join(impatientTimestamp-currentTimestamp), and send an interrupt to all file-loading threads in the middle of the loop on if(currentTimestamp >= impatientTimestamp) - then have the file-loading threads check for it in the loop where they're reading file data, then re-join() the thread that the join(milliseconds) aborted from and continue the join()ing iteration you were doing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文