common-lisp
स्ट्रीम
खोज…
वाक्य - विन्यास
-
(read-char &optional stream eof-error-p eof-value recursive-p)
=> वर्ण -
(write-char character &optional stream)
=> चरित्र -
(read-line &optional stream eof-error-p eof-value recursive-p)
=> लाइन, अनुपलब्ध-नईलाइन-पी -
(write-line line &optional stream)
=> लाइन
पैरामीटर
पैरामीटर | विस्तार |
---|---|
stream | से पढ़ने या लिखने की धारा। |
eof-error-p | यदि फ़ाइल के अंत का सामना करना पड़ा है, तो एक त्रुटि का संकेत दिया जाना चाहिए। |
eof-value | यदि ईओएफ का सामना किया गया है, तो क्या मूल्य लौटाया जाना चाहिए और eof-error-p गलत है। |
recursive-p | रीड-ऑपरेशन को READ से पुनरावर्ती कहा जाता है। आमतौर पर इसे NIL रूप में छोड़ दिया जाना चाहिए। |
character | लिखने का पात्र, या पढ़ा जाने वाला चरित्र। |
line | लिखने की लाइन, या पढ़ी जाने वाली लाइन। |
तार से इनपुट स्ट्रीम बनाना
एक स्ट्रिंग से एक धारा बनाने के लिए WITH-INPUT-FROM-STRING
मैक्रो का उपयोग किया जा सकता है।
(with-input-from-string (str "Foobar")
(loop for i from 0
for char = (read-char str nil nil)
while char
do (format t "~d: ~a~%" i char)))
; 0: F
; 1: o
; 2: o
; 3: b
; 4: a
; 5: r
;=> NIL
इसे MAKE-STRING-INPUT-STREAM
का उपयोग करके मैन्युअल रूप से किया जा सकता है।
(let ((str (make-string-input-stream "Foobar")))
(loop for i from 0
for char = (read-char str nil nil)
while char
do (format t "~d: ~a~%" i char)))
एक स्ट्रिंग के लिए उत्पादन लेखन
WITH-OUTPUT-TO-STRING
मैक्रो का उपयोग एक स्ट्रिंग आउटपुट स्ट्रीम बनाने के लिए किया जा सकता है, और परिणामी स्ट्रिंग को अंत में वापस कर सकता है।
(with-output-to-string (str)
(write-line "Foobar!" str)
(write-string "Barfoo!" str))
;=> "Foobar!
; Barfoo!"
इसे मैन्युअल- MAKE-STRING-OUTPUT-STREAM
और GET-OUTPUT-STREAM-STRING
का उपयोग करके मैन्युअल रूप से किया जा सकता है।
(let ((str (make-string-output-stream)))
(write-line "Foobar!" str)
(write-string "Barfoo!" str)
(get-output-stream-string str))
धूसर धाराएँ
ग्रे स्ट्रीम एक गैर-मानक एक्सटेंशन है जो उपयोगकर्ता परिभाषित धाराओं को अनुमति देता है। यह कक्षाएं और विधियाँ प्रदान करता है जो उपयोगकर्ता बढ़ा सकता है। आपको यह देखने के लिए अपने कार्यान्वयन मैनुअल की जांच करनी चाहिए कि क्या यह ग्रे स्ट्रीम प्रदान करता है।
एक सरल उदाहरण के लिए, एक चरित्र इनपुट स्ट्रीम जो यादृच्छिक वर्ण लौटाता है, इसे इस तरह लागू किया जा सकता है:
(defclass random-character-input-stream (fundamental-character-input-stream)
((character-table
:initarg :character-table
:initform "abcdefghijklmnopqrstuvwxyz
" ; The newline is necessary.
:accessor character-table))
(:documentation "A stream of random characters."))
(defmethod stream-read-char ((stream random-character-input-stream))
(let ((table (character-table stream)))
(aref table (random (length table)))))
(let ((stream (make-instance 'random-character-input-stream)))
(dotimes (i 5)
(print (read-line stream))))
; "gyaexyfjsqdcpciaaftoytsygdeycrrzwivwcfb"
; "gctnoxpajovjqjbkiqykdflbhfspmexjaaggonhydhayvknwpdydyiabithpt"
; "nvfxwzczfalosaqw"
; "sxeiejcovrtesbpmoppfvvjfvx"
; "hjplqgstbodbalnmxhsvxdox"
;=> NIL
फ़ाइल पढ़ना
एक फाइल को बिना WITH-OPEN-FILE
मैक्रो का उपयोग किए एक स्ट्रीम के रूप में पढ़ने के लिए खोला जा सकता है।
(with-open-file (file #P"test.file")
(loop for i from 0
for line = (read-line file nil nil)
while line
do (format t "~d: ~a~%" i line)))
; 0: Foobar
; 1: Barfoo
; 2: Quuxbar
; 3: Barquux
; 4: Quuxfoo
; 5: Fooquux
;=> T
इसे मैन्युअल रूप से OPEN
और CLOSE
का उपयोग करके किया जा सकता है।
(let ((file (open #P"test.file"))
(aborted t))
(unwind-protect
(progn
(loop for i from 0
for line = (read-line file nil nil)
while line
do (format t "~d: ~a~%" i line))
(setf aborted nil))
(close file :abort aborted)))
ध्यान दें कि READ-LINE
प्रत्येक पंक्ति के लिए एक नया स्ट्रिंग बनाता है। यह धीमा हो सकता है। कुछ कार्यान्वयन एक प्रकार प्रदान करते हैं, जो एक स्ट्रिंग बफर में एक पंक्ति पढ़ सकते हैं। उदाहरण: READ-LINE-INTO
Allegro CL के लिए।
एक फ़ाइल के लिए लेखन
किसी फाइल को WITH-OPEN-FILE
मैक्रो के WITH-OPEN-FILE
स्ट्रीम के रूप में लिखने के लिए खोला जा सकता है।
(with-open-file (file #P"test.file" :direction :output
:if-exists :append
:if-does-not-exist :create)
(dolist (line '("Foobar" "Barfoo" "Quuxbar"
"Barquux" "Quuxfoo" "Fooquux"))
(write-line line file)))
इसे मैन्युअल रूप से OPEN
और CLOSE
साथ किया जा सकता है।
(let ((file (open #P"test.file" :direction :output
:if-exists :append
:if-does-not-exist :create)))
(dolist (line '("Foobar" "Barfoo" "Quuxbar"
"Barquux" "Quuxfoo" "Fooquux"))
(write-line line file))
(close file))
एक फाइल कॉपी करना
किसी फाइल की बाइट-प्रति-बाइट कॉपी करें
निम्न फ़ंक्शन एक फ़ाइल को एक सटीक बाइट-प्रति-बाइट प्रतिलिपि बनाकर कॉपी करता है, सामग्री की तरह की अनदेखी (जो कि कुछ एन्कोडिंग या बाइनरी डेटा में वर्णों की पंक्तियां हो सकती हैं):
(defun byte-copy (infile outfile)
(with-open-file (instream infile :direction :input :element-type '(unsigned-byte 8)
:if-does-not-exist nil)
(when instream
(with-open-file (outstream outfile :direction :output :element-type '(unsigned-byte 8)
:if-exists :supersede)
(loop for byte = (read-byte instream nil)
while byte
do (write-byte byte outstream))))))
प्रकार (unsigned-byte 8)
8-बिट बाइट्स का प्रकार है। वर्णों पर काम करने वाले read-char
और write-char
बजाय बाइट्स पर read-byte
और write-byte
काम करते हैं। यदि दूसरा वैकल्पिक पैरामीटर NIL
(तो यह एक त्रुटि का संकेत देता है) यदि read-byte
स्ट्रीम के अंत में, या फाइल के अंत में NIL
से पढ़ता है।
थोक प्रति
एक सटीक प्रतिलिपि, पिछले एक से अधिक कुशल। एकल बाइट्स के बजाय हर बार डेटा की बड़ी मात्रा के साथ फ़ाइलों को पढ़ने और लिखने के द्वारा किया जा सकता है:
(defun bulk-copy (infile outfile)
(with-open-file (instream infile :direction :input :element-type '(unsigned-byte 8)
:if-does-not-exist nil)
(when instream
(with-open-file (outstream outfile :direction :output :element-type '(unsigned-byte 8)
:if-exists :supersede)
(let ((buffer (make-array 8192 :element-type '(unsigned-byte 8))))
(loop for bytes-read = (read-sequence buffer instream)
while (plusp bytes-read)
do (write-sequence buffer outstream :end bytes-read)))))))
read-sequence
और write-sequence
का उपयोग यहां बफ़र के साथ किया जाता है जो बाइट्स का एक वेक्टर है (वे बाइट्स या वर्णों के अनुक्रम पर काम कर सकते हैं)। read-sequence
हर बार पढ़ी जाने वाली बाइट्स के साथ एरे को भरता है, और रीड किए गए बाइट्स की संख्या लौटाता है (जो फ़ाइल के अंत में पहुंचने पर एरे के आकार से कम हो सकती है)। ध्यान दें कि सरणी को विनाशकारी रूप से प्रत्येक पुनरावृत्ति पर संशोधित किया गया है।
किसी फ़ाइल की सटीक प्रतिलिपि लाइन-प्रति-पंक्ति
अंतिम उदाहरण इनपुट फ़ाइल के वर्णों की प्रत्येक पंक्ति को पढ़कर और आउटपुट फ़ाइल पर लिखकर की गई प्रतिलिपि है। ध्यान दें कि, चूंकि हम एक सटीक प्रतिलिपि चाहते हैं, इसलिए हमें यह देखना होगा कि इनपुट फ़ाइल की अंतिम पंक्ति समाप्त हो गई है या लाइन वर्ण (नों) के अंत तक नहीं है। इस कारण से, हम read-line
द्वारा लौटाए गए दो मानों का उपयोग करते read-line
: अगली पंक्ति के वर्णों वाला एक नया स्ट्रिंग, और एक बूलियन मान जो कि यदि रेखा फ़ाइल के अंतिम है और अंतिम न्यूलाइन वर्ण शामिल नहीं है, तो सत्य है (रों)। इस मामले में write-line
बजाय write-string
का उपयोग किया जाता है, क्योंकि पूर्व लाइन के अंत में एक नई पंक्ति नहीं जोड़ता है।
(defun line-copy (infile outfile)
(with-open-file (instream infile :direction :input :if-does-not-exist nil)
(when instream
(with-open-file (outstream outfile :direction :output :if-exists :supersede)
(let (line missing-newline-p)
(loop
(multiple-value-setq (line missing-newline-p)
(read-line instream nil nil))
(cond (missing-newline-p ; we are at the end of file
(when line (write-string line outstream)) ; note `write-string`
(return)) ; exit from simple loop
(t (write-line line outstream)))))))))
ध्यान दें कि यह प्रोग्राम प्लेटफ़ॉर्म स्वतंत्र है, क्योंकि न्यूलाइन कैरेक्टर (एस) (विभिन्न ऑपरेटिंग सिस्टम में भिन्न) स्वचालित रूप से read-line
और write-line
फ़ंक्शन द्वारा प्रबंधित किया जाता है।
स्ट्रिंग्स से और उसके लिए पूरी फाइलें पढ़ना और लिखना
निम्न फ़ंक्शन एक पूरी फ़ाइल को एक नए स्ट्रिंग में पढ़ता है और उसे लौटाता है:
(defun read-file (infile)
(with-open-file (instream infile :direction :input :if-does-not-exist nil)
(when instream
(let ((string (make-string (file-length instream))))
(read-sequence string instream)
string))))
फ़ाइल मौजूद नहीं है, तो परिणाम NIL
है।
निम्न फ़ंक्शन किसी फ़ाइल में एक स्ट्रिंग लिखता है। एक कीवर्ड पैरामीटर का उपयोग यह निर्दिष्ट करने के लिए किया जाता है कि यदि फ़ाइल पहले से मौजूद है (डिफ़ॉल्ट रूप से यह एक त्रुटि का कारण बनता है, तो स्वीकार्य मान with-open-file
मैक्रो के साथ हैं)।
(defun write-file (string outfile &key (action-if-exists :error))
(check-type action-if-exists (member nil :error :new-version :rename :rename-and-delete
:overwrite :append :supersede))
(with-open-file (outstream outfile :direction :output :if-exists action-if-exists)
(write-sequence string outstream)))
इस मामले में write-sequence
को write-string
साथ प्रतिस्थापित किया जा सकता है।