起初从网上查询到的由便携设备拷贝文件到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);
}