为什么使用 XCOPY 复制 *.txt 文件会使它们为空?

Why does usage of XCOPY for copying *.txt files makes them empty?

我在 Java 中编程时使用此批处理脚本以避免 class 文件使我的文件夹混乱。但由于某种原因,它无法复制 *.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 引用的批处理文件的字符串在此问题上最为重要。不幸的是,这个字符串没有发布。

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

@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.

在第二行检查是否使用参数字符串调用了批处理文件,如果不是这种情况则退出批处理。有关详细信息,请参阅以下答案:

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

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

找到这两个可执行文件 如果目标文件夹不存在,

XCOPY 可以创建整个目录结构到指定的目标文件夹。因此没有必要先明确创建目标文件夹。

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

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

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

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

在复制多个文件时,即在源字符串中使用 ?*,选项 /I 告诉 XCOPY 目标是目录名称,即使目标字符串不以反斜杠结尾。出于这个原因,第一个 XCOPY 命令行也可以在目标字符串 %~1Folder\.

末尾没有反斜杠的情况下工作

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

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

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

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

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

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

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