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

来源:互联网 发布:代理商域名转到阿里云 编辑:程序博客网 时间:2024/05/21 14:50

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

[csharp] view plain copy
  1. private void TransferContentFromDevice(string parentObjectID, string saveToPath)  
  2.         {  
  3.             string folder = System.IO.Path.GetDirectoryName(saveToPath);  
  4.             if (!Directory.Exists(folder))  
  5.             {  
  6.                 Directory.CreateDirectory(folder);  
  7.             }  
  8.             if (File.Exists(saveToPath))  
  9.             {  
  10.                 File.Delete(saveToPath);  
  11.             }  
  12.             IPortableDeviceContent content;  
  13.             ppDevice.Content(out content);  
  14.             IPortableDeviceResources resources;  
  15.             content.Transfer(out resources);  
  16.             PortableDeviceApiLib.IStream wpdStream;  
  17.             uint optimalTransferSize = 0;  
  18.             PortableDeviceApiLib._tagpropertykey property = new PortableDeviceApiLib._tagpropertykey();  
  19.             property.fmtid = new Guid(0xE81E79BE, 0x34F0, 0x41BF, 0xB5, 0x3F, 0xF1, 0xA0, 0x6A, 0xE8, 0x78, 0x42);  
  20.             property.pid = 0;  
  21.             resources.GetStream(parentObjectID, ref property, 0, ref optimalTransferSize, out wpdStream);  
  22.             System.Runtime.InteropServices.ComTypes.IStream sourceStream = (System.Runtime.InteropServices.ComTypes.IStream)wpdStream;  
  23.             string filename = Path.GetFileName(saveToPath);  
  24.             FileStream targetStream = new FileStream(saveToPath, FileMode.Create, FileAccess.Write);  
  25.             {  
  26.                 int filesize = int.Parse(optimalTransferSize.ToString());  
  27.                 var buffer = new byte[filesize];  
  28.                 int bytesRead = 0;  
  29.                 do  
  30.                 {  
  31.                     sourceStream.Read(buffer, filesize, new IntPtr(bytesRead));  
  32.                     targetStream.Write(buffer, 0, filesize);  
  33.                 } while (bytesRead > 0);  
  34.                 targetStream.Close();  
  35.                 targetStream.Dispose();  
  36.             }  
  37.             //若不添此行,在本方法执行一次后再次执行时会报资源占用错误  
  38.             Marshal.ReleaseComObject(wpdStream);  
  39.         }  
但在实际操作中发现,当文件大小超过256K时,文件拷贝异常,即文件只能拷贝设备建议的最大传输大小256k

解决:

[csharp] view plain copy
  1. private void TransferContentFromDevice(string parentObjectID, string saveToPath)  
  2.         {  
  3.             string folder = System.IO.Path.GetDirectoryName(saveToPath);  
  4.             if (!Directory.Exists(folder))  
  5.             {  
  6.                 Directory.CreateDirectory(folder);  
  7.             }  
  8.             if (File.Exists(saveToPath))  
  9.             {  
  10.                 File.Delete(saveToPath);  
  11.             }  
  12.             IPortableDeviceContent content;  
  13.             ppDevice.Content(out content);  
  14.             IPortableDeviceResources resources;  
  15.             content.Transfer(out resources);  
  16.             PortableDeviceApiLib.IStream wpdStream;  
  17.             uint optimalTransferSize = int.MaxValue;  
  18.             PortableDeviceApiLib._tagpropertykey property = new PortableDeviceApiLib._tagpropertykey();  
  19.             property.fmtid = new Guid(0xE81E79BE, 0x34F0, 0x41BF, 0xB5, 0x3F, 0xF1, 0xA0, 0x6A, 0xE8, 0x78, 0x42);  
  20.             property.pid = 0;  
  21.   
  22.             resources.GetStream(parentObjectID, ref property, 0, ref optimalTransferSize, out wpdStream);  
  23.             System.Runtime.InteropServices.ComTypes.IStream sourceStream = (System.Runtime.InteropServices.ComTypes.IStream)wpdStream;  
  24.             string filename = Path.GetFileName(saveToPath);  
  25.   
  26.             FileStream targetStream = new FileStream(saveToPath, FileMode.Create, FileAccess.Write);  
  27.             {  
  28.                 int filesize = int.Parse(optimalTransferSize.ToString());  
  29.                 var buffer = new byte[filesize];  
  30.                 int bytesRead = 0;  
  31.                 IntPtr bytesReadIntPtr = new IntPtr(bytesRead);  
  32.                 //设备建议读取长度optimalTransferSize长度一般为262144即256k,  
  33.                 //注释掉的sourceStream.Read不能更新bytesRead值,do循环只能执行一次即写入256k数据。  
  34.                 //创建nextBufferSize变量,用于每次Read后计算下一次buffer长度  
  35.                 int nextBufferSize = 0;  
  36.                 do  
  37.                 {  
  38.                     if (bytesReadIntPtr == IntPtr.Zero)  
  39.                     {  
  40.                         bytesReadIntPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)));  
  41.                     }  
  42.                     //sourceStream.Read(buffer, filesize, new IntPtr(bytesRead));  
  43.                     sourceStream.Read(buffer, filesize, bytesReadIntPtr);  
  44.                     nextBufferSize = Marshal.ReadInt32(bytesReadIntPtr);  
  45.                     if (filesize > nextBufferSize)  
  46.                     {  
  47.                         filesize = nextBufferSize;  
  48.                     }  
  49.                       
  50.                     targetStream.Write(buffer, 0, filesize);  
  51.                 } while (nextBufferSize > 0);  
  52.                 //} while (bytesRead > 0);  
  53.                 targetStream.Close();  
  54.                 targetStream.Dispose();  
  55.                 Marshal.FreeCoTaskMem(bytesReadIntPtr);  
  56.             }  
  57.             //若不添此行,在本方法执行一次后再次执行时会报资源占用错误  
  58.             Marshal.ReleaseComObject(wpdStream);  
  59.         } 
原创粉丝点击