【问题标题】:dotnet core File.Move issuedotnet core File.Move 问题
【发布时间】:2019-11-21 15:41:04
【问题描述】:

我的 Dockerfile 是这个

FROM mcr.microsoft.com/dotnet/core/runtime:3.0

COPY publish/ app/
RUN mkdir -p /in
RUN mkdir -p /tmp

ENTRYPOINT ["dotnet", "app/Watcher.dll"]

我用这个命令构建图像

docker build -t watcher/sl_user_test:1.1 .

所以,我的 docker-compose 是这样的

watcher.sl_user_test:
  image: watcher/sl_user_test:1.1
  container_name: watcher_sl_user_test
  build: .
  restart: always
  volumes:
    - /var/storage/in:/in:z
    - /var/storage/tmp:/tmp:z

在我的 dotnet 核心应用程序中,我在 /in 文件夹中获得了一个文件,然后将其移动到 /tmp/aaa 代码是这样的

string destination = $"/tmp/{Guid.NewGuid()}/git.zip";
new FileInfo(destination).Directory.Create();
File.Move("/in/git.zip", destination, true);

问题是这个命令复制文件并没有移动它,为什么? 如果我进入容器内部,我可以从 bash 执行 mv 并且它可以工作

【问题讨论】:

  • 你可以对原始文件使用 File.Delete 吗? File.GetAttributes 返回什么?同一个程序可以读取移动文件的源吗?
  • File.Delete 作品
  • File.GetAttributes 说“正常”

标签: c# docker .net-core


【解决方案1】:

由于您要在路径中创建新的 GUID,因此可以保证该目录不存在。因此File.Move 将抛出一个DirectoryNotFoundException

在移动文件之前创建它。

var tmpDir = $"/tmp/{Guid.NewGuid()}";
Directory.CreateDirectory(tmpDir);
File.Move("/in/git.zip", $"{tmpDir}/git.zip", true);

假设您正在这样做,如果 File.Move 方法只是复制而不是移动,那么很可能原始文件正在使用中。来自the docs(在备注部分):

如果您尝试跨磁盘卷移动文件并且该文件正在使用中,则该文件会复制到目标位置,但不会从源中删除。

【讨论】:

  • 这是一个很好的提示,但是我使用这个功能来验证文件是否在使用中,并且总是没有锁定stackoverflow.com/questions/876473/…
  • 如果我直接运行应用程序(没有 docker)File.Move 工作
【解决方案2】:

问题是我试图将文件从一个卷移动到另一个卷。 如果您在 GoLang 中尝试此代码,则会收到此错误

"rename /dir1/test.txt /dir2/test.txt: invalid cross-device link"

所以,解决办法是

  • 编写自己的 FileMove 函数(带有复制和删除源)
  • 只使用一卷

所以,就我而言,从这个

volumes:
  - /var/storage/in:/in:z
  - /var/storage/tmp:/tmp:z

我会这样做

volumes:
  - /var/storage/data/:/data:z

在 /data 中有“in”和“tmp”文件夹

【讨论】:

    猜你喜欢
    • 2021-04-16
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    相关资源
    最近更新 更多