\documentclass{article}
\usepackage{lipsum}
\newwrite\foo
\openout\foo=foo.foo
\begin{document}
\immediate\write\foo{A}
\immediate\write\foo{B}
\lipsum
\immediate\write\foo{C}
\lipsum
\immediate\write\foo{D}
\end{document}
\closeout\foo
编译上述代码时,foo.foo 包含
C
D
如果我删除\immediate
s,它还会包含A
和,B
正如预期的那样。是什么导致了这种行为?
答案1
你需要
\immediate\openout\foo=foo.foo
这样它就会在第一页发出之前打开,如果你想明确关闭它,你需要
\closeout\foo
因为\end{document}
没有执行任何命令,\end{document}
所以在运行结束后,文件流将被彻底关闭,\closeout
除非您需要在同一运行期间输入文件,否则不需要执行该文件流。
答案2
您可以注意到控制台显示
This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023) (preloaded format=pdflatex)
restricted \write18 enabled.
entering extended mode
(./ray.tex
LaTeX2e <2023-11-01> patch level 1
L3 programming layer <2024-01-22>
(/usr/local/texlive/2023/texmf-dist/tex/latex/base/article.cls
Document Class: article 2023/05/17 v1.4n Standard LaTeX document class
(/usr/local/texlive/2023/texmf-dist/tex/latex/base/size10.clo))
(/usr/local/texlive/2023/texmf-dist/tex/latex/lipsum/lipsum.sty
(/usr/local/texlive/2023/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty
(/usr/local/texlive/2023/texmf-dist/tex/latex/l3kernel/expl3.sty
(/usr/local/texlive/2023/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def)))
(/usr/local/texlive/2023/texmf-dist/tex/latex/lipsum/lipsum.ltd.tex))
No file ray.aux.
A
B
[1{/usr/local/texlive/2023/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
[2] [3] (./ray.aux) )</usr/local/texlive/2023/texmf-dist/fonts/type1/public/ams
fonts/cm/cmr10.pfb>
Output written on ray.pdf (3 pages, 27002 bytes).
Transcript written on ray.log.
\immediate\write\foo{A}
这意味着扫描时文件尚未打开。
每一个与写入不带前缀的文件相关的操作\immediate
将在下次发货时延迟。这包括\openout
和\closeout
。
所以你\immediate\openout
也应该这么做。
顺便说一句,请注意,expl3
只立即打开写入功能。
\documentclass{article}
\usepackage{lipsum}
\ExplSyntaxOn
\NewDocumentCommand{\openwritestream}{smm}
{
\IfBooleanT { #1 }
{% * version also allocates
\iow_new:c { g_ray_write_#2_iow }
}
\iow_open:cn { g_ray_write_#2_iow } { #3 }
}
\NewDocumentCommand{\writestream}{smm}
{
\IfBooleanTF{#1}
{ \iow_now:ce }% expanded
{ \iow_now:cn }% not expanded
{ g_ray_write_#2_iow } { #3 }
}
\NewDocumentCommand{\closewritestream}{m}
{
\iow_close:c { g_ray_write_#1_iow }
}
\ExplSyntaxOff
\openwritestream*{foo}{\jobname.foo}
\newcommand{\test}{xyz}
\begin{document}
\writestream{foo}{A}
\writestream{foo}{B}
\lipsum
\writestream{foo}{C}
\lipsum
\writestream{foo}{D}
\writestream{foo}{\test}
\writestream*{foo}{\test}
\closewritestream{foo}
\end{document}
这是该文件的内容ray.foo
:
A
B
C
D
\test
xyz
注意区别:\write
总是对参数执行完全扩展,而\writestream
除非调用,否则不会\writestream*
。