簡體   English   中英

如何從 Windows 7 上的 C# 程序讀取 Android 手機上的文件?

[英]How to read files on Android phone from C# program on Windows 7?

當我使用 USB 數據線將我的 Android 手機連接到我的 Windows 7 時,Windows 會彈出一個窗口,並通過 Windows 資源管理器在Computer\HTC VLE_U\Internal storage中向我顯示手機的內部存儲。 但是沒有與此手機存儲鏈接的驅動器號,在 Windows 資源管理器中。 我可以操縱文件系統。

如何從 C# 程序中操作相同的文件或文件夾?

正如我測試的那樣,

DirectoryInfo di = new DirectoryInfo(@"C:\"); 

有效,但是

DirectoryInfo di = new DirectoryInfo(@"Computer\HTC VLE_U\Internal storage");

失敗的。

但在 Windows 資源管理器中,它是Computer\HTC VLE_U\Internal storage 沒有盤符!

是的,這是 MTP 設備。

我在 Stack Overflow 中看到了這個答案,但是運行這段代碼后返回結果對我來說是空的

var drives = DriveInfo.GetDrives();
var removableFatDrives = drives.Where(
    c=>c.DriveType == DriveType.Removable &&
    c.DriveFormat == "FAT" && 
    c.IsReady);
var androids = from c in removableFatDrives
    from d in c.RootDirectory.EnumerateDirectories()
    where d.Name.Contains("android")
    select c;

我得到正確的drives 但是安卓手機的內部存儲不在這里。 removableFatDrivesandroids對我來說都是空的。

我使用了 nugetpackage "Media Devices by Ralf Beckers v1.8.0" 這使我可以輕松地將照片從我的設備復制到我的計算機,反之亦然。

 public class Program
{
    static void Main(string[] args)
    {
        var devices = MediaDevice.GetDevices();
        using (var device = devices.First(d => d.FriendlyName == "Galaxy Note8"))
        {
            device.Connect();
            var photoDir = device.GetDirectoryInfo(@"\Phone\DCIM\Camera");

            var files = photoDir.EnumerateFiles("*.*", SearchOption.AllDirectories);

            foreach (var file in files)
            {
                MemoryStream memoryStream = new System.IO.MemoryStream();
                device.DownloadFile(file.FullName, memoryStream);
                memoryStream.Position = 0;
                WriteSreamToDisk($@"D:\PHOTOS\{file.Name}", memoryStream);
            }
            device.Disconnect();
        }

    }

    static void WriteSreamToDisk(string filePath, MemoryStream memoryStream)
    {
        using (FileStream file = new FileStream(filePath, FileMode.Create, System.IO.FileAccess.Write))
        {
            byte[] bytes = new byte[memoryStream.Length];
            memoryStream.Read(bytes, 0, (int)memoryStream.Length);
            file.Write(bytes, 0, bytes.Length);
            memoryStream.Close();
        }
    }
}

這個問題肯定對我有幫助! 我試圖編寫一個簡單的程序來自動將我的照片/視頻從 android 設備同步到我的計算機。 因此,我最終問了與Herbert Yu相同的問題,當沒有驅動器號時如何訪問設備路徑?

ZackOfAllTrades的回答幫助了我。 豎起大拇指!

我復制了 ZackOfAllTrades 的代碼,根據我的需要對其進行了調整,砰! 它奏效了,但時間不長。 我的小米 Note 10 Pro 上有一個 108MP 的攝像頭,4 分鍾的視頻可以輕松超過 1GB; 我的一些視頻有 4GB 大。 使用 ZackOfAllTrades 的代碼,我在調用 MediaDevice.DownloadFile(string, Stream) 時很快遇到了OutOfMemoryException

[1] 我最初嘗試解決這個問題是轉到項目屬性,將我的項目設置為為 x64 構建,這似乎擺脫了 OutOfMemoryException; 我能夠開始在 1GB 到 2GB 之間復制文件而沒有任何問題。

[2] 然而,一旦我開始復制 2.5GB 大的文件,ZackOfAllTrades 編寫的 WriteStreamToDisk() 實用程序就開始抱怨 Stream 太長了。

然后我意識到 DownloadFile 需要一個 Stream 對象,它不需要像 Zack 使用的那樣是 MemoryStream。 所以我將它切換到 FileStream 對象如下

static void Main(string[] args)
{
    string DeviceNameAsSeenInMyComputer = "Mi Note 10 Pro";

    var devices = MediaDevice.GetDevices();

    using (var device = devices.Where(d => d.FriendlyName == DeviceNameAsSeenInMyComputer || d.Description == DeviceNameAsSeenInMyComputer).First())
    {
        device.Connect();
        var photoDir = device.GetDirectoryInfo(@"\Internal shared storage\DCIM\Camera");
        var files = photoDir.EnumerateFiles("*.*", SearchOption.TopDirectoryOnly);

        foreach (var file in files)
        {
            string destinationFileName = $@"F:\Photo\{file.Name}";
            if (!File.Exists(destinationFileName))
            {
                using (FileStream fs = new FileStream(destinationFileName, FileMode.Create, System.IO.FileAccess.Write))
                {
                    device.DownloadFile(file.FullName, fs);
                }
            }

            
        }
        device.Disconnect();
    }

    Console.WriteLine("Done...");
    Console.ReadLine();
}

工作得很漂亮。 當我使用 ZackOfAllTrades 的代碼時,VS 分析器顯示的內存消耗約為文件大小的 2.5 倍。 例如:如果文件大小為 1.5GB,則內存消耗大約為 4GB。

但是如果是直接拷貝到文件系統,內存消耗可以忽略不計(<50mb)

另一個問題是MediaDevice.FriendlyName 在 ZackOfAllTrades 的例子中,他使用的是三星,我猜三星手機支持這個屬性。 我沒有費心挖出我的舊三星來嘗試一下。 我確定我的小米 Note 10 Pro支持 FriendlyName,而對我有用的MediaDevice.Description

希望這可以幫助其他提出相同問題的人。

使用@Ji_in_coding 對我將文件從 Android 下載到 PC 有很大幫助。

我嘗試使用 device.UploadFile() 將文件從 PC 上傳到 android,但我收到一個錯誤,即即使目錄路徑正確,也找不到目錄。

你知道為什么會這樣嗎?

private void PCToPDA()
    {
        try
        {
            string DeviceNameAsSeenInMyComputer = "DT50";
            string tempFileName = "CaptureImport.txt";
            var devices = MediaDevice.GetDevices();

            using (var device = devices.Where(d => d.FriendlyName == DeviceNameAsSeenInMyComputer || d.Description == DeviceNameAsSeenInMyComputer).First())
            {
                device.Connect();
                var photoDir = device.GetDirectoryInfo(@"\Internal shared storage\Download");
                var files = photoDir.EnumerateFiles("*.*", SearchOption.TopDirectoryOnly);

                foreach (var file in files)
                {
                    string originalFileName = $@"D:\KhineThein\Testing\TransferTesting\photo\{tempFileName}";

                    string transferToFileName = $@"{DeviceNameAsSeenInMyComputer}\Internal shared storage\Download\{tempFileName}";

                    using (FileStream fs = new FileStream(originalFileName, FileMode.Open, System.IO.FileAccess.Read))
                    {
                        //device.DownloadFile(file.FullName, fs);                       //Path, Stream
                        device.UploadFile(fs, transferToFileName);                      //Stream, Path
                    }


                }
                device.Disconnect();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "PCToPDA-ERR", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM