ক্লোজার ১.৩-এ ফাইল পড়ার এবং লেখার "প্রস্তাবিত" উপায়টি আমি জানতে চাই।
- কীভাবে পুরো ফাইলটি পড়বেন
- কীভাবে একটি ফাইল লাইন লাইন পড়তে হয়
- কিভাবে একটি নতুন ফাইল লিখবেন
- একটি বিদ্যমান ফাইলে কীভাবে একটি লাইন যুক্ত করবেন
ক্লোজার ১.৩-এ ফাইল পড়ার এবং লেখার "প্রস্তাবিত" উপায়টি আমি জানতে চাই।
উত্তর:
ধরে নেওয়া আমরা এখানে কেবল পাঠ্য ফাইল করছি এবং কিছু ক্রেজি বাইনারি স্টাফ নয়।
নম্বর 1: কীভাবে একটি সম্পূর্ণ ফাইলকে মেমরিতে পড়তে হয়।
(slurp "/tmp/test.txt")
এটি যখন সত্যিই বড় ফাইল হয় তখনই প্রস্তাবিত হয় না।
সংখ্যা 2: কীভাবে লাইন দ্বারা ফাইল লাইন পড়তে হয়।
(use 'clojure.java.io)
(with-open [rdr (reader "/tmp/test.txt")]
(doseq [line (line-seq rdr)]
(println line)))
with-open
ম্যাক্রো যত্ন নেয় যে পাঠক শরীর শেষে বন্ধ করা হয়। পাঠক ফাংশন একটি স্ট্রিং (এটা এছাড়াও একটি URL, ইত্যাদি কাজ করতে পারেন) একটি মধ্যে coerces BufferedReader
। line-seq
একটি অলস Sequ বিতরণ। অলস সিকের পরবর্তী উপাদানগুলির দাবি পাঠকের কাছ থেকে পড়া একটি লাইনে তৈরি করা।
নোট করুন যে ক্লোজুর ১.7 থেকে আপনি পাঠ্য ফাইলগুলি পড়ার জন্য ট্রান্সডুসারও ব্যবহার করতে পারেন ।
নম্বর 3: একটি নতুন ফাইলে কীভাবে লিখবেন।
(use 'clojure.java.io)
(with-open [wrtr (writer "/tmp/test.txt")]
(.write wrtr "Line to be written"))
আবার, with-open
যত্ন নিন যে BufferedWriter
শরীরের শেষে বন্ধ রয়েছে। লেখক একটি স্ট্রিংকে একটিতে প্রচ্ছন্ন করে BufferedWriter
, যা আপনি জাভা ইন্টারপের মাধ্যমে ব্যবহার করেন:(.write wrtr "something").
আপনি spit
এর বিপরীতেও ব্যবহার করতে পারেন slurp
:
(spit "/tmp/test.txt" "Line to be written")
সংখ্যা 4: একটি বিদ্যমান ফাইলে একটি লাইন যুক্ত করুন।
(use 'clojure.java.io)
(with-open [wrtr (writer "/tmp/test.txt" :append true)]
(.write wrtr "Line to be appended"))
উপরের মত একই, তবে এখন সংযোজন অপশন সহ।
বা আবার এর সাথে spit
, এর বিপরীতে slurp
:
(spit "/tmp/test.txt" "Line to be written" :append true)
পিএস: আপনি যে কোনও ফাইল পড়ছেন এবং লিখছেন এবং অন্য কিছু নয় সে সম্পর্কে আরও স্পষ্ট করে বলার জন্য আপনি প্রথমে একটি ফাইল অবজেক্ট তৈরি করতে পারেন এবং তারপরে এটিকে কোনও BufferedReader
লেখক বা জোর করে জোর করতে পারেন :
(reader (file "/tmp/test.txt"))
;; or
(writer (file "tmp/test.txt"))
ফাইল ফাংশনটি Clojure.java.io এও রয়েছে।
PS2: কখনও কখনও এটি বর্তমান ডিরেক্টরি (তাই "।") কী তা দেখতে সক্ষম হয়ে উঠতে সুবিধাজনক। আপনি দুটি উপায়ে পরম পথ পেতে পারেন:
(System/getProperty "user.dir")
অথবা
(-> (java.io.File. ".") .getAbsolutePath)
(with-open [rdr (reader "/tmp/test.txt")] (line-seq rdr))
ফলন IOException Stream closed
হয়। কি করো? যদিও @ সত্যগ্রহের উত্তর দিয়ে ভাল ফলাফল পাচ্ছি।
(with-open [rdr (reader "/tmp/test.txt")] (doall (line-seq rdr)))
doseq
রিটার্নগুলি nil
দু: খ-না-প্রত্যাবর্তন-মূল্য বারের দিকে নিয়ে যেতে পারে।
যদি ফাইলটি মেমরির সাথে ফিট করে তবে আপনি স্লার্প এবং থুতু দিয়ে এটি পড়তে এবং লিখতে পারেন:
(def s (slurp "filename.txt"))
(গুলি এখন স্ট্রিং হিসাবে একটি ফাইলের বিষয়বস্তু রয়েছে)
(spit "newfile.txt" s)
এটি newfile.txt তৈরি করে যদি এটি প্রস্থান না করে এবং ফাইলের লিখিত সামগ্রীটি লিখতে পারে। আপনি যদি ফাইলটিতে যুক্ত করতে চান তবে আপনি এটি করতে পারেন
(spit "filename.txt" s :append true)
ফাইল পড়তে বা লেখার জন্য লাইনওয়াইজ করতে আপনি জাভার পাঠক এবং লেখক ব্যবহার করবেন। তারা নাম স্থান Clojure.java.io জড়িত হয়:
(ns file.test
(:require [clojure.java.io :as io]))
(let [wrtr (io/writer "test.txt")]
(.write wrtr "hello, world!\n")
(.close wrtr))
(let [wrtr (io/writer "test.txt" :append true)]
(.write wrtr "hello again!")
(.close wrtr))
(let [rdr (io/reader "test.txt")]
(println (.readLine rdr))
(println (.readLine rdr)))
; "hello, world!"
; "hello again!"
নোট করুন যে স্লার্প / স্পিট এবং পাঠক / লেখকের উদাহরণগুলির মধ্যে পার্থক্যটি হ'ল ফাইলটি পরবর্তীকালে খোলা থাকে (লেট স্টেটমেন্টগুলিতে) এবং পড়া এবং লেখার বাফার হয়, এভাবে কোনও ফাইল থেকে বারবার / লেখার সময় বারবার পড়ার সময় আরও কার্যকর।
আরও তথ্যের হল: গবগব করে খাওয়া থুতু clojure.java.io জাভার BufferedReader জাভার রাইটার
প্রশ্ন 2 সম্পর্কিত, কেউ কখনও কখনও প্রথম-শ্রেণীর অবজেক্ট হিসাবে লাইনের স্রোত ফিরে আসতে চায়। এটি একটি অলস ক্রম হিসাবে পেতে এবং এখনও ইওএফ-তে ফাইল স্বয়ংক্রিয়ভাবে বন্ধ হয়ে গেছে, আমি এই ফাংশনটি ব্যবহার করেছি:
(use 'clojure.java.io)
(defn read-lines [filename]
(let [rdr (reader filename)]
(defn read-next-line []
(if-let [line (.readLine rdr)]
(cons line (lazy-seq (read-next-line)))
(.close rdr)))
(lazy-seq (read-next-line)))
)
(defn echo-file []
(doseq [line (read-lines "myfile.txt")]
(println line)))
defn
বাঁধাই আদর্শিক ক্লোজার। আপনার read-next-line
, যতদূর আমি বুঝতে পারি, আপনার read-lines
ফাংশনের বাইরে দৃশ্যমান । এর (let [read-next-line (fn [] ...))
পরিবর্তে আপনি হয়ত ব্যবহার করেছেন ।
লাইন দ্বারা একটি ফাইল লাইন পড়ার জন্য আপনাকে আর ইন্টারোপ অবলম্বন করতে হবে না:
(->> "data.csv"
io/resource
io/reader
line-seq
(drop 1))
এটি ধরে নিয়েছে যে আপনার ডেটা ফাইলটি সম্পদ ডিরেক্টরিতে রাখা হয়েছে এবং প্রথম লাইনটি শিরোনাম সম্পর্কিত তথ্য যা বাতিল করা যেতে পারে।