WPD 从便携设备拷贝文件到PC文件不完整的解决办法

起初从网上查询到的由便携设备拷贝文件到PC的方法如下:

private void TransferContentFromDevice(string parentObjectID, string saveToPath)
        {
            string folder = System.IO.Path.GetDirectoryName(saveToPath);
            if (!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
            }
            if (File.Exists(saveToPath))
            {
                File.Delete(saveToPath);
            }
            IPortableDeviceContent content;
            ppDevice.Content(out content);
            IPortableDeviceResources resources;
            content.Transfer(out resources);
            PortableDeviceApiLib.IStream wpdStream;
            uint optimalTransferSize = 0;
            PortableDeviceApiLib._tagpropertykey property = new PortableDeviceApiLib._tagpropertykey();
            property.fmtid = new Guid(0xE81E79BE, 0x34F0, 0x41BF, 0xB5, 0x3F, 0xF1, 0xA0, 0x6A, 0xE8, 0x78, 0x42);
            property.pid = 0;
            resources.GetStream(parentObjectID, ref property, 0, ref optimalTransferSize, out wpdStream);
            System.Runtime.InteropServices.ComTypes.IStream sourceStream = (System.Runtime.InteropServices.ComTypes.IStream)wpdStream;
            string filename = Path.GetFileName(saveToPath);
            FileStream targetStream = new FileStream(saveToPath, FileMode.Create, FileAccess.Write);
            {
                int filesize = int.Parse(optimalTransferSize.ToString());
                var buffer = new byte[filesize];
                int bytesRead = 0;
                do
                {
                    sourceStream.Read(buffer, filesize, new IntPtr(bytesRead));
                    targetStream.Write(buffer, 0, filesize);
                } while (bytesRead > 0);
                targetStream.Close();
                targetStream.Dispose();
            }
            //若不添此行,在本方法执行一次后再次执行时会报资源占用错误
            Marshal.ReleaseComObject(wpdStream);
        }
但在实际操作中发现,当文件大小超过256K时,文件拷贝异常,即文件只能拷贝设备建议的最大传输大小256k

解决:

private void TransferContentFromDevice(string parentObjectID, string saveToPath)
        {
            string folder = System.IO.Path.GetDirectoryName(saveToPath);
            if (!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
            }
            if (File.Exists(saveToPath))
            {
                File.Delete(saveToPath);
            }
            IPortableDeviceContent content;
            ppDevice.Content(out content);
            IPortableDeviceResources resources;
            content.Transfer(out resources);
            PortableDeviceApiLib.IStream wpdStream;
            uint optimalTransferSize = int.MaxValue;
            PortableDeviceApiLib._tagpropertykey property = new PortableDeviceApiLib._tagpropertykey();
            property.fmtid = new Guid(0xE81E79BE, 0x34F0, 0x41BF, 0xB5, 0x3F, 0xF1, 0xA0, 0x6A, 0xE8, 0x78, 0x42);
            property.pid = 0;

            resources.GetStream(parentObjectID, ref property, 0, ref optimalTransferSize, out wpdStream);
            System.Runtime.InteropServices.ComTypes.IStream sourceStream = (System.Runtime.InteropServices.ComTypes.IStream)wpdStream;
            string filename = Path.GetFileName(saveToPath);

            FileStream targetStream = new FileStream(saveToPath, FileMode.Create, FileAccess.Write);
            {
                int filesize = int.Parse(optimalTransferSize.ToString());
                var buffer = new byte[filesize];
                int bytesRead = 0;
                IntPtr bytesReadIntPtr = new IntPtr(bytesRead);
                //设备建议读取长度optimalTransferSize长度一般为262144即256k,
                //注释掉的sourceStream.Read不能更新bytesRead值,do循环只能执行一次即写入256k数据。
                //创建nextBufferSize变量,用于每次Read后计算下一次buffer长度
                int nextBufferSize = 0;
                do
                {
                    if (bytesReadIntPtr == IntPtr.Zero)
                    {
                        bytesReadIntPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)));
                    }
                    //sourceStream.Read(buffer, filesize, new IntPtr(bytesRead));
                    sourceStream.Read(buffer, filesize, bytesReadIntPtr);
                    nextBufferSize = Marshal.ReadInt32(bytesReadIntPtr);
                    if (filesize > nextBufferSize)
                    {
                        filesize = nextBufferSize;
                    }
                    
                    targetStream.Write(buffer, 0, filesize);
                } while (nextBufferSize > 0);
                //} while (bytesRead > 0);
                targetStream.Close();
                targetStream.Dispose();
                Marshal.FreeCoTaskMem(bytesReadIntPtr);
            }
            //若不添此行,在本方法执行一次后再次执行时会报资源占用错误
            Marshal.ReleaseComObject(wpdStream);
        }



你可能感兴趣的:(c#开发)