【问题标题】:Why does usage of XCOPY for copying *.txt files makes them empty?为什么使用 XCOPY 复制 *.txt 文件会使它们为空?
【发布时间】:2018-04-07 04:30:06
【问题描述】:

我在使用 Java 编程时使用此批处理脚本,以避免文件夹与类文件混淆。但由于某种原因,它不能复制 *.txt 文件。

这是复制到另一个文件夹之前的 *.txt 文件内容:

U 450
I 100
I 5000
U 500

批处理文件包含:

@echo off
set TEST=%1
mkdir %TEST%Folder
xcopy *.txt %TEST%Folder
xcopy %TEST%.java %TEST%Folder
cd %TEST%Folder
javac -encoding utf8 %TEST%.java
java %TEST%
cd..
::RD /S /Q %TEST%Folder //is commented out while I'm debugging 

这是复制文件的内容:

 

它是空的。

奇怪的是,如果我自己运行xcopy *.txt DestinationFolder,它就可以正常工作。


编辑: %1 变量是程序将编译的 java 的名称,我的所有路径都设置正确,这部分代码工作正常,唯一有问题的部分是 xcopy

【问题讨论】:

  • 收到的参数字符串%1的具体内容是什么?
  • @Compo 是要编译的java文件的名字
  • @Waitwuut,如果您也注释掉javacjava 行,并且文件正确且可读地复制到保存目录,那么您可以将问题确定为与编译器有关。如果文件未到达保存目录或命名不正确,则问题可能与您的输入参数%1 有关。如果文件完全按预期到达那里并且是空的、不可读的或损坏的,则问题很可能是系统问题。
  • @Compo 文件按预期到达但为空。
  • @Waitwuut,根据我之前的评论,如果文件正确到达但为空,那么您接受的答案只有在 java 编译器遇到 Windows 通常允许的字符问题时才是正确的/命令.exe。 (十多个小时前,有人向您询问%1 的内容以确定这一点)。在这种情况下,我不相信 Xcopy 会清空您的文件,即使这是可能的,将 XCopy 更改为 CopyRoboCopy 将是建议的解决方案,而不是用双引号括住文件名。

标签: batch-file xcopy


【解决方案1】:

作为第一个参数传递给以%1 引用的批处理文件的字符串在此问题上是最重要的。不幸的是,这个字符串没有发布。

我建议使用这个批处理文件:

@echo off
if "%~1" == "" goto :EOF
%SystemRoot%\System32\xcopy.exe *.txt "%~1Folder\"   /I /C /K /Q /R /Y >nul
%SystemRoot%\System32\xcopy.exe "%~1.java" "%~1Folder\" /C /K /Q /R /Y >nul
pushd "%~1Folder"
javac.exe -encoding utf8 "%~1.java"
java.exe "%~1"
popd
rem rd /S /Q "%~1Folder" & rem Is commented out while I'm debugging.

在第二行检查是否使用参数字符串调用了批处理文件,如果不是这种情况,则退出批处理。详情见回复:Where does GOTO :EOF return to?

上面的批处理文件引用了第一个参数字符串,可能存在的周围双引号总是被删除,因为参数字符串与其他字符串连接到命令和可执行文件的新参数字符串。不带或带有包含空格或字符之一的路径的文件/文件夹名称 &()[]{}^=;!'+,`~ 需要在完整的参数字符串周围使用双引号。

建议在批处理文件中指定始终使用文件扩展名的可执行文件,并且如果可执行文件的路径众所周知,还使用完整路径,因为这使得批处理文件独立于环境变量 PATHPATHEXT 的当前值.这就是使用完整路径和文件扩展名两次指定xcopy 的原因。 javacjava 仅使用文件扩展名指定,因为我不知道它们在 Windows 计算机上的存储位置。因此,Windows 命令解释器必须使用环境变量 PATH 找到这两个可执行文件。

如果目标文件夹不存在,

XCOPY 可以将整个目录结构创建到指定的目标文件夹。因此,不必先显式创建目标文件夹。

XCOPY 可用于将单个文件、多个文件或整个目录结构复制到单个文件、多个文件或目录中。 XCOPY 的挑战是查找用户是否指定了文件名或目录名。

如果目标/目标字符串的最后一个反斜杠后有?*,则目标被解释为文件名模式,例如使用xcopy *.txt "%TEMP%\*.tmp"

如果目标字符串以反斜杠结尾,则目标被解释为目录名称。

但是,如果目标字符串不包含 ?*(在最后一个反斜杠之后)并且也不以反斜杠结尾,那么 XCOPY 不清楚目标字符串是否指定了目录或文件。

在复制多个文件时,即在源字符串中使用?*,选项/I 告诉XCOPY即使目标字符串不以一个反斜杠。因此,第一个 XCOPY 命令行也可以在目标字符串 %~1Folder\ 的末尾没有反斜杠的情况下工作。

但是在复制单个文件的第二个 XCOPY 命令行上,使用选项 /I 将没有任何帮助,因为 XCOPY 仍然会提示用户如果destination 指定一个文件或一个目录。这就是目标文件夹路径末尾的反斜杠以避免出现此提示的原因。

PUSHD命令将当前目录的路径压栈,并将指定目录设置为新的当前目录。如果默认启用命令扩展,这甚至适用于使用 UNC 路径指定的目录,因为在这种情况下 PUSHD 会动态地将驱动器号分配给 UNC 文件夹路径。命令 POPD 从堆栈中弹出目录路径并将该目录再次设置为当前目录。我只能假设这是该任务的正确当前目录管理。

我建议测试这个批处理文件,将第一行 @echo off 更改为 @echo ON,方法是在当前目录设置正确的命令提示符窗口中运行它,而不是双击它来查看 Windows 命令解释器之后真正执行的内容根据第一个参数字符串预处理批处理文件中的每个命令行以及可能输出的错误消息。

要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • call /? ...解释%~1
  • cmd /? ... 说明文件/目录名称或任何其他参数字符串何时必须用双引号括起来。
  • echo /?
  • goto /?
  • if /?
  • popd /?
  • pushd /?
  • rd /?
  • rem /?
  • xcopy /?

另请阅读有关 Using Command Redirection Operators 的 Microsoft 文章,了解对 >nul 的解释。

【讨论】:

  • 试过你的批处理文件,由于某种原因它仍然清空复制的文本文件。
  • @Waitwuut 正如我在答案中建议的那样,从命令提示符窗口中运行批处理文件的输出是什么?是否显示任何错误消息?目标目录中复制文件的文件大小是多少?他们真的有0字节吗?您是否在编辑器中打开了要复制的文件,该编辑器使用读/写锁打开它们,因此没有其他应用程序可以在运行批处理文件时读取文件?
  • 无错误信息,文件为 0 字节。复制java文件就可以了,只是txt文件丢失了数据。
【解决方案2】:

重新安装windows,将解决所有问题

【讨论】:

  • 换句话说,我们可以假设您在批处理文件中使用了两次 xcopy 而不是 %SystemRoot%\System32\xcopy.exe,正如我在我的回答中发布的那样,因此 Windows 命令解释器执行了一些不同的操作文件名xcopyPATH 中列出的任何其他目录中,文件扩展名在PATHEXT 中列出。而这个备用的xcopy 可执行文件或脚本能够只复制一个像"%~1.java" 这样的文件,但不能复制与通配符模式*.txt 匹配的一组文件。 PATHPATHEXT 现在按照重新安装 Windows 后的定义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 2018-04-15
  • 2010-09-15
  • 1970-01-01
  • 2018-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多