Работает ли экземпляр DirectoryInfo на другом ПК? - PullRequest
0 голосов
/ 30 апреля 2018

Если вы отправляете экземпляр DirectoryInfo с ПК1 на ПК2, работают ли 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);
        }
    }

Если вы выполняете этот код на том же ПК, он работает, но у меня нет среды, чтобы проверить, работает ли он на 2 разных ПК.

Возможно, подкаталоги и файлы сохранены в массиве в классе directoryinfo, потому что я нашел эту функцию сериализации: Serialization function in DirectoryInfo

1 Ответ

0 голосов
/ 30 апреля 2018

Ну, это работает, только если у вас одинаковое имя каталога на обеих машинах. Давайте посмотрим на справочный источник ...

Сначала 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);
    }

Где base - это FileSystemInfo, и этот конструктор используется:

    [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;
    }

Итак, вы можете видеть, что единственное, что сериализуется, это значения FullPath и OriginalPath. Данные внутри каталога не сериализуются, и если вы вызовете 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();
    }

И снова вы видите, что из сериализованной информации ничего не используется.

...