【问题标题】:Does a DirectoryInfo instance still work on a different PC?DirectoryInfo 实例是否仍可在不同的 PC 上运行?
【发布时间】:2018-04-30 15:02:10
【问题描述】:

如果您将 DirectoryInfo 实例从 PC1 发送到 PC2,GetFiles 或 GetDirectories 是否仍然有效?

public void DirTest()
    {
        //On first PC:

        DirectoryInfo driveC = new DirectoryInfo(@"C:\randomdir\");

        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream ns = new MemoryStream();

        bf.Serialize(ns, driveC);
        SendStream(ns); //Sending the stream to the second PC


        //On second PC:


        ns = ReceiveStream(); //Receiving the stream from the first PC
        ns.Position = 0;
        DirectoryInfo di = (DirectoryInfo)bf.Deserialize(ns);

        //Does this work?
        foreach (FileInfo item in di.GetFiles())
        {
            Debug.WriteLine(item);
        }
    }

如果您在同一台 PC 上执行该代码,它可以工作,但我没有环境来测试这是否可以在 2 台不同的电脑上工作。

也许 SubDirectories 和 Files 保存在 directoryinfo 类的数组中,因为我找到了这个序列化函数:

【问题讨论】:

  • 您希望得到来自 PC1 或 PC2 的信息吗?你到底关心什么?序列化还是检索信息?
  • 我认为你正处于危险的境地,试图序列化你不知道以这种方式使用是安全的类,甚至可能没有允许你正确序列化的构造函数。为什么不使用您实际需要的属性创建您自己的类并通过网络发送它们呢?当然,除非它是网络驱动器,否则您期望 DirectoryInfo 在另一台机器上有用仍然很奇怪。
  • Patrick Hofman 我想知道来自 PC1 的 DirectoryInfo 实例是否仍在 PC2 上工作。如果 GetDirectories() 仍然返回 PC1 的目录
  • @DavidG DirectoryInfo 被特别标记为Serializable,因此以这种方式使用它是安全的,但是它不像 OP 所期望的那样运行。
  • @RonBeyer 你对“安全”的定义与我的不同,尤其是当唯一真正重要的字段是目录路径时。

标签: c# serialization directoryinfo


【解决方案1】:

好吧,它只有在两台机器上的目录名称相同时才有效。一起来看看reference source...

首先,DirectoryInfo继承FileSystemInfo,所以当你反序列化DirectoryInfo时,会调用这个构造函数:

    [System.Security.SecurityCritical]  // auto-generated
    private DirectoryInfo(SerializationInfo info, StreamingContext context) : base(info, context)
    {
        Directory.CheckPermissions(string.Empty, FullPath, checkHost: false);
        DisplayPath = GetDisplayName(OriginalPath, FullPath);
    }

其中baseFileSystemInfo,并且使用了这个构造函数:

    [ResourceExposure(ResourceScope.None)]
    [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
    protected FileSystemInfo(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
            throw new ArgumentNullException("info");
        Contract.EndContractBlock();

        // Must use V1 field names here, since V1 didn't implement 
        // ISerializable.
        FullPath = Path.GetFullPathInternal(info.GetString("FullPath"));
        OriginalPath = info.GetString("OriginalPath");

        // Lazily initialize the file attributes.
        _dataInitialised = -1;
    }

所以你可以看到唯一被序列化的是FullPathOriginalPath 值。目录中的数据未序列化,如果您调用DirectoryInfo.GetFiles(),您将枚举本地计算机中的文件,而不是首先序列化DirectoryInfo 的计算机。事实上,源码中特别提到了Lazily initialize the file attributes,意思是在请求时加载它们。

    // Returns an array of Files in the DirectoryInfo specified by path
    [ResourceExposure(ResourceScope.Machine)]
    [ResourceConsumption(ResourceScope.Machine)]
    public FileInfo[] GetFiles()
    {
        return InternalGetFiles("*", SearchOption.TopDirectoryOnly);
    }

调用者:

    // Returns an array of Files in the current DirectoryInfo matching the 
    // given search criteria (ie, "*.txt").
    [ResourceExposure(ResourceScope.Machine)]
    [ResourceConsumption(ResourceScope.Machine)]
    private FileInfo[] InternalGetFiles(String searchPattern, SearchOption searchOption)
    {
        Contract.Requires(searchPattern != null);
        Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);

        IEnumerable<FileInfo> enble = FileSystemEnumerableFactory.CreateFileInfoIterator(FullPath, OriginalPath, searchPattern, searchOption);
        List<FileInfo> fileList = new List<FileInfo>(enble);
        return fileList.ToArray();
    }

再一次,您看到序列化信息中没有使用任何内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-19
    • 1970-01-01
    • 2018-04-02
    • 2015-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多