Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从文件中一次读取一行文本,并将文本分配给Clojure中的变量_Clojure_Io - Fatal编程技术网

如何从文件中一次读取一行文本,并将文本分配给Clojure中的变量

如何从文件中一次读取一行文本,并将文本分配给Clojure中的变量,clojure,io,Clojure,Io,我想在Clojure中打开一个大型XML文件,每行处理一行文本,然后将选定的字符串转储到工作文件中 我对这个完全陌生,所以现在我只想能够(1)读取一个文件,(2)将选择分配给一个变量。我将处理大型XML文件,因此不能选择slurping 不管怎样,我正在使用从教程中获得的代码。每当我在REPL中执行它时,它都会打印出文件中包含的文本,但似乎无法创建变量str1(未解决的符号错误) 代码如下: (defn readfile [] (let [str1 ;; I want the text

我想在Clojure中打开一个大型XML文件,每行处理一行文本,然后将选定的字符串转储到工作文件中

我对这个完全陌生,所以现在我只想能够(1)读取一个文件,(2)将选择分配给一个变量。我将处理大型XML文件,因此不能选择slurping

不管怎样,我正在使用从教程中获得的代码。每当我在REPL中执行它时,它都会打印出文件中包含的文本,但似乎无法创建变量str1(未解决的符号错误)

代码如下:

(defn readfile []
  (let [str1    ;; I want the text inside the text file to fill this variable
        (with-open [rdr (io/reader "resources/loremipsum.txt")]
          (reduce conj [] (line-seq rdr)))] str1))
(readfile)

let
中声明的绑定仅在
let
主体中可见。由于
readfile
函数返回文件的行,因此可以创建一个var并将调用函数的结果分配给它:

(def lines (readfile))

这里列出的代码是正确的,在复制和粘贴过程中是否发生了更改

user=> (require '[clojure.java.io :as io])
nil

(defn readfile []
  (let [str1 (with-open [rdr (io/reader "lorum-lispsum")]
               (reduce conj [] (line-seq rdr)))] 
    str1))
#'user/readfile

user=> (readfile)
["let lambda bind lambda let lambda"]
模式
(reduce conj…
通常更容易使用
写入
函数

(defn readfile []
  (let [str1 (with-open [rdr (io/reader "lorum-lispsum")]
               (into [] (line-seq rdr)))] 
    str1))
由于
进入
的作用是使其成为一个向量,同时将整个文件拉入内存,因此可以用调用
vec

(defn readfile []
  (let [str1 (with-open [rdr (io/reader "lorum-lispsum")]
               (vec (line-seq rdr)))] 
    str1))
由于您还提到了不将整个文件存储在内存中是一个目标,因此我们可能希望重新安排内容以保持文件处于打开状态,同时将序列作为惰性序列进行处理

(require '[clojure.java.io :as io])

(defn process-a-line [line]
  :your-code-here)

(defn the-main-part-of-my-program [lazy-sequence-of-lines]
  (dorun (map process-a-line)))

(defn readfile []
  (let [str1 (with-open [rdr (io/reader "lorum-lispsum")]
               (line-seq rdr))] 
    (the-main-part-of-my-program str1)))

如果您试图在clojure中处理xml,我建议使用clojure.data.zip。下面是一个简单的例子:

(require '[clojure.xml :as xml])
(require '[clojure.zip :as zip])
(require '[clojure.data.zip.xml :as zf])
(import '[java.io ByteArrayInputStream])
(with-open [in-stream (ByteArrayInputStream. (.getBytes "
<xml>
  <test>something</test>
  <fish>dog</fish>
  <test>something else</test>
</xml>"))]
  (let [parsed (zip/xml-zip (xml/parse in-stream))]
    (zf/xml-> parsed :xml :test zf/text)))
(需要“[clojure.xml:as-xml]”
(需要“[clojure.zip:as-zip]”)
(需要“[clojure.data.zip.xml:作为zf])
(导入“[java.io ByteArrayInputStream])
(在流中打开[ByteArrayInputStream.(.getBytes)”
某物
狗
别的
"))]
(让[parsed(zip/xml-zip(xml/parse-in-stream))]
(zf/xml->parsed:xml:test-zf/text)))

它将生成所提供选择器的延迟序列。使用XML通常是一种非常好的方法,可能适合您的需要。

我相信字符串的值仅在LET body的范围内可用,Lee的最新帖子证实了这一点。您的示例使用惰性序列处理看起来很有希望。我认为这正是我的情况所需要的,我需要处理的文件和我必须筛选的数据量。顺便说一句,使用lorum lispsum进行智能移动。欣赏:)您的示例已经正确地放置了
str1
名称的所有用法已经正确地将符号放置在let的范围内。它在
[]
部分中给该符号一个值,然后将相同的值放入let绑定主体的返回位置。let表达式的主体是
[]
是的,您关心的是正确的。确切地说,为什么str1的值不再可用。您能详细说明一下为什么要逐行处理大型XML文件吗?通常,您不能假设标记和内容包含在同一行中,这决定了解析器遵循“标记流”方法,但在您的情况下,可能会有所不同,这会改变建议。最初的计划是将XML转换为CSV,但是LOAD-INTO无法处理重复的标记,所以我不得不强行逐行读取文件以获取值。还需要做一些分类什么的,所以重新发明轮子似乎是一条路要走。