क्या किसी को जावा फाइलों के समानांतर समकक्ष के बारे में पता है। वाल्कफाइल ट्री या कुछ ऐसा ही है? यह जावा या स्कैला पुस्तकालय हो सकता है।Files.walkFileTree (जावा या स्कैला) के समानांतर संस्करण
उत्तर
मान लीजिए कि प्रत्येक फ़ाइल पर कॉलबैक निष्पादित करना पर्याप्त है।
यह कोड फ़ाइल सिस्टम में लूप को संभाल नहीं करेगा - आपको उस रजिस्ट्री की आवश्यकता होगी जहां आप इसके लिए गए हैं (उदा। java.util.concurrent.ConcurrentHashMap
)। उन सभी प्रकार के सुधार हैं जिन्हें आप जोड़ सकते हैं, जैसे चुपचाप उन्हें अनदेखा करने की बजाय अपवादों की रिपोर्ट करना।
import java.io.File
import scala.util._
def walk(f: File, callback: File => Unit, pick: File => Boolean = _ => true) {
Try {
val (dirs, fs) = f.listFiles.partition(_.isDirectory)
fs.filter(pick).foreach(callback)
dirs.par.foreach(f => walk(f, callback, pick))
}
}
एक foreach
के बजाय एक गुना का उपयोग करके फ़ाइलें एकत्रित काफी कठिन नहीं है, लेकिन मैं छोड़ कि पाठक के लिए एक व्यायाम के रूप। (ConcurrentLinkedQueue
शायद उन सभी को कॉलबैक में स्वीकार करने के लिए पर्याप्त तेज़ है, भले ही आपके पास वास्तव में धीमी धागे और एक भयानक फाइल सिस्टम हो।)
असल में मुझे आशा है कि 'परिपक्व-ईश' लाइब्रेरी से लिंक प्राप्त हो, जो ऐसा करता है और इसमें कुछ अतिरिक्त वायदा हैं, लेकिन आपका उदाहरण मेरी वर्तमान ज़रूरतों के लिए पर्याप्त है। धन्यवाद! – matt
जैसा कि अन्य ने इंगित किया है, एक फ़ाइल पेड़ चलाना लगभग निश्चित रूप से सीपीयू बाध्य की बजाय आईओ बाध्य है, इसलिए एक बहुप्रचारित फ़ाइल पेड़ चलने के लाभ संदिग्ध हैं। लेकिन अगर आप वास्तव में चाहते थे, तो आप शायद ForkJoinPool
या इसी तरह के साथ अपना खुद का रोल कर सकते हैं।
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class MultiThreadedFileTreeWalk {
private static class RecursiveWalk extends RecursiveAction {
private static final long serialVersionUID = 6913234076030245489L;
private final Path dir;
public RecursiveWalk(Path dir) {
this.dir = dir;
}
@Override
protected void compute() {
final List<RecursiveWalk> walks = new ArrayList<>();
try {
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
if (!dir.equals(RecursiveWalk.this.dir)) {
RecursiveWalk w = new RecursiveWalk(dir);
w.fork();
walks.add(w);
return FileVisitResult.SKIP_SUBTREE;
} else {
return FileVisitResult.CONTINUE;
}
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println(file + "\t" + Thread.currentThread());
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
e.printStackTrace();
}
for (RecursiveWalk w : walks) {
w.join();
}
}
}
public static void main(String[] args) throws IOException {
RecursiveWalk w = new RecursiveWalk(Paths.get(".").toRealPath());
ForkJoinPool p = new ForkJoinPool();
p.invoke(w);
}
}
यह उदाहरण प्रत्येक निर्देशिका को एक अलग थ्रेड पर चलता है। जावा 7 की fork/join लाइब्रेरी के लिए यहां ट्यूटोरियल है।
यदि प्रत्येक तत्व पर प्रदर्शन करने के लिए कुछ कार्यक्षमता है, तो पिछले अनुभव से फ़ाइल प्रदर्शन के दौरान महत्वपूर्ण प्रदर्शन किया जा सकता है और प्रत्येक नोड पर कार्य को क्रियात्मक रूप से बनाम बनाम कार्य निष्पादित किया जा सकता है। – Hazok
@ हाज़ोक यह कार्यक्षमता पर निर्भर करता है। यदि कार्यक्षमता बहुत सीपीयू गहन है, तो यह फ़ाइल पेड़ चलने की आईओ सीमा से अधिक हो सकती है। यदि ऐसा है, तो अपना कोड समवर्ती बनाना सार्थक हो सकता है। हालांकि, यह हमेशा मामला नहीं होगा। – Jeffrey
सहमत हुए, यही कारण है कि मैंने कथन का योग्यता प्राप्त की। मैं बस यह इंगित करना चाहता था कि ऐसे मामले हैं जहां प्रदर्शन लाभ प्राप्त किए जा सकते हैं क्योंकि इसे उत्तर में "संदिग्ध" कहा गया था। – Hazok
यह अभ्यास स्कैला उत्तर के रूप में संक्षिप्त नहीं है और न ही जावा जैसे जावा उत्तर के रूप में ।
यहां विचार था कि प्रति डिवाइस धागे की तरह कुछ समानांतर चलना शुरू करें।
वॉकर फोर्कजोइनपूल धागे पर हैं, इसलिए जब वे प्रत्येक पथ परीक्षण के लिए भविष्य को निकाल देते हैं, तो वे पूल पर फोर्क किए गए कार्य होते हैं। जब निर्देशिका निर्देशिका को पढ़ती है, तो फाइलों की तलाश करते समय निर्देशिका परीक्षण प्रबंधित अवरोधन का उपयोग करता है।
परिणाम भविष्य के पथ परीक्षण के आधार पर एक वादा पूरा करके वापस किया जाता है। (खाली हाथ पूरा करने का पता लगाने के लिए यहां कोई तंत्र नहीं है।)
एक और दिलचस्प परीक्षण में ज़िप फ़ाइलों को पढ़ने में शामिल होगा, क्योंकि डिकंप्रेशन कुछ सीपीयू खाएगा।
मुझे आश्चर्य है कि paulp will do something clever with deep listing है।
import util._
import collection.JavaConverters._
import concurrent.{ TimeoutException => Timeout, _ }
import concurrent.duration._
import ExecutionContext.Implicits._
import java.io.IOException
import java.nio.file.{ FileVisitResult => Result, _ }
import Result.{ CONTINUE => Go, SKIP_SUBTREE => Prune, TERMINATE => Stop }
import java.nio.file.attribute.{ BasicFileAttributes => BFA }
object Test extends App {
val fileSystem = FileSystems.getDefault
val starts = (if (args.nonEmpty) args.toList else mounts) map (s => (fileSystem getPath s))
val p = Promise[(Path, BFA)]
def pathTest(path: Path, attrs: BFA) =
if (attrs.isDirectory) {
val entries = blocking {
val res = Files newDirectoryStream path
try res.asScala.toList finally res.close()
}
List("hello","world") forall (n => entries exists (_.getFileName.toString == n))
} else {
path.getFileName.toString == "enough"
}
def visitor(root: Path) = new SimpleFileVisitor[Path] {
def stopOrGo = if (p.isCompleted) Stop else Go
def visiting(path: Path, attrs: BFA) = {
future { pathTest(path, attrs) } onComplete {
case Success(true) => p trySuccess (path, attrs)
case Failure(e) => p tryFailure e
case _ =>
}
stopOrGo
}
override def preVisitDirectory(dir: Path, attrs: BFA) = (
if ((starts contains dir) && dir != root) Prune
else visiting(dir, attrs)
)
override def postVisitDirectory(dir: Path, e: IOException) = {
if (e != null) p tryFailure e
stopOrGo
}
override def visitFile(file: Path, attrs: BFA) = visiting(file, attrs)
}
//def walk(p: Path): Path = Files walkFileTree (p, Set().asJava, 10, visitor(p))
def walk(p: Path): Path = Files walkFileTree (p, visitor(p))
def show(store: FileStore) = {
val ttl = store.getTotalSpace/1024
val used = (store.getTotalSpace - store.getUnallocatedSpace)/1024
val avail = store.getUsableSpace/1024
Console println f"$store%-40s $ttl%12d $used%12d $avail%12d"
store
}
def mounts = {
val devs = for {
store <- fileSystem.getFileStores.asScala
if store.name startsWith "/dev/"
if List("ext4","fuseblk") contains store.`type`
} yield show(store)
val devstr = """(\S+) \((.*)\)""".r
(devs.toList map (_.toString match {
case devstr(name, dev) if devs.toList exists (_.name == dev) => Some(name)
case s => Console println s"Bad dev str '$s', skipping" ; None
})).flatten
}
starts foreach (f => future (walk(f)))
Try (Await result (p.future, 20.seconds)) match {
case Success((name, attrs)) => Console println s"Result: ${if (attrs.isDirectory) "dir" else "file"} $name"
case Failure(e: Timeout) => Console println s"No result: timed out."
case Failure(t) => Console println s"No result: $t."
}
}
इस कोड को लिखने के लिए इतना समय लेने के लिए धन्यवाद। मैंने रेक्स केर समाधान को स्वीकार करने का फैसला किया क्योंकि यह बहुत संक्षिप्त है और इसे डीबग करना आसान है। – matt
@lucek रेक्स सबसे अच्छा है। प्रश्न के लिए Thx, यह एपीआई की खोज मजेदार था। मैंने अन्य उत्तरों को भी ऊपर उठाया। –
- 1. Files.walkFileTree
- 2. स्कैला: ट्यूपल्स के समानांतर असाइनमेंट
- 3. स्कैला - जावा =? (या क्लोजर - जावा =?)
- 4. सिलोन के पास जावा या स्कैला
- 5. एसबीटी में स्कैला परियोजना के लिए जावा संस्करण लागू करना?
- 6. स्कैला/स्पार्क संस्करण संगतता
- 7. जावा समानांतर फ़ाइल प्रसंस्करण
- 8. समानांतर या साथ में
- 9. समानांतर फॉरएच या लूप
- 10. जावा/स्कैला
- 11. क्या NavigableMap का एक स्कैला संस्करण है?
- 12. मैं स्कैला के भीतर से स्कैला संस्करण कैसे प्राप्त करूं?
- 13. स्कैला/जावा
- 14. जावा/स्कैला
- 15. स्कैला: 'जावा'
- 16. जावा/स्कैला
- 17. जावा संस्करण के आंकड़े
- 18. Rubys 'प्रत्येक_स्लिस का स्कैला संस्करण?
- 19. जावा में कार्य समानांतर लाइब्रेरी के बराबर
- 20. नई ग्रीनफील्ड परियोजनाओं के लिए जावा या स्कैला?
- 21. जावा समानांतर धाराएं पास धागा
- 22. मल्टीथ्रेडिंग या कार्य समानांतर लाइब्रेरी
- 23. स्कैला
- 24. लूप के लिए समानांतर
- 25. स्कैला: जावा, सी #, स्कैला और सी ++
- 26. स्कैला: जैक्सबी या इसी तरह?
- 27. समानांतर
- 28. पाइथन और जावा/स्कैला
- 29. स्कैला बनाम जावा 8
- 30. जावा/स्कैला | वेबसाइट
मुझे नहीं लगता कि यह समझ में आता है क्योंकि सभी समांतर धागे में समान बाधा होगी - एचडीडी। और यह नेटवर्क आईओ संचालन के रूप में समान नहीं हो सकता है। – aim
समान रूप से एक अच्छा विचार में अपने फ़ाइल पेड़ क्यों चल रहा है? यह आम तौर पर आईओ बाध्य है, सीपीयू बाध्य नहीं है। –
मेरे मामले में फ़ाइल प्रसंस्करण सीपीयू बाध्य है और I/O उपयोग लगभग 10% -20% है। – matt