如何调用PathTooLongException?

时间:2014-06-01 16:34:46

标签: c# .net windows path pathtoolongexception

我有一个小实用程序不断触及PathTooLongException并且我被指示输出错误的文件路径,很好......有点。

但是我发现自己无法复制这个问题。我尝试创建一个路径大于MAX_PATH的文件,但我的程序处理得很好。我试图增加路径大小甚至更多,但Windows不允许这样做,并且踢球者通过CMD甚至不能进入包含文件夹因为我之前遇到了PathTooLongException,但我的程序处理它就好了,没有例外。

真正奇怪的是,虽然永远不会抛出异常,但程序只是忽略了有问题的文件,这是代码的和平,无法找到它并且不会抛出错误

string fileName;
DirectoryInfo di = new DirectoryInfo(strFolderPath);
IEnumerable<FileInfo> fileList = di.EnumerateFiles("*", SearchOption.AllDirectories);
foreach (FileInfo fi in fileList)
{
    fileName = fi.FullName.Remove(0, di.FullName.Length + 1);
}

我发现自己陷入了一种奇怪的境地,无法调用错误,我应该处理。

PS。我想我应该提一下,由于种种原因,我无法使用部署路径。

理论上,这是完整的路径:
C:\净\同步试验-1 \ G1244kljsdfglksdjflsdjlfkjajhalsjflkdsajkljsdflk \ long_name_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItI \ long_na.txt

当我从Windows地址栏中取出时,这是相同的包含文件夹: C:\净\ SYNC-T〜1 \ G1244K〜1 \ long_name_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItI

这是程序在部署中发出的堆栈跟踪:

System.IO.PathTooLongException: The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
   at System.IO.PathHelper.GetFullPathName()
   at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
   at System.Security.Util.StringExpressionSet.CanonicalizePath(String path, Boolean needFullPath)
   at System.Security.Util.StringExpressionSet.CreateListFromExpressions(String[] str, Boolean needFullPath)
   at System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList)
   at System.IO.FileSystemInfo.get_FullName()
   at Neudesic.BlobDrop.BlobDrop.SyncContainer(BlobTask task)

所以这是SyncContainer()的源代码:

// Sync local folder to container
private bool SyncContainer(BlobTask task)
{
    try
    {
        List<CloudBlob> blobList;
        Dictionary<string, CloudBlob> blobDict = new Dictionary<string,CloudBlob>();

        // Enumerate blobs in container.

        if (BlobHelper.ListBlobs(Container, out blobList))
        {
            // Put blob in a dictionary so we can easily look it up by name.
            foreach (CloudBlob blob in blobList)
            {
                blobDict.Add(blob.Name, blob);
            }

            // Enumerate the files in the watch folder - upload any files that do not yet have corresponding blobs in storage.
            string fileName;
            DirectoryInfo di = new DirectoryInfo(FolderPath);
            IEnumerable<FileInfo> fileList = di.EnumerateFiles("*", SearchOption.AllDirectories);
            foreach (FileInfo fi in fileList)
            {
                fileName = fi.FullName.Remove(0, di.FullName.Length + 1);
                if (!isPathSafe(fi.FullName))
                    continue;

                if (BlobHelper.doesTheBlobExist(fileName, Container))
                {
                    Info("  [" + Container + "\\" + fileName + "]: already in blob storage");
                }
                else
                {
                    Warning("  [" + Container + "\\" + fileName + "]: not found, adding upload task");

                    BlobQueue.Add(new BlobTask()
                    {
                        Action = "upload",
                        BlobName = fileName,
                        ContainerName = Container,
                        FilePath = fi.FullName,
                        RemainingRetryCount = MAX_RETRY_COUNT
                    });
                }
            }


            //checks the blob for all exess files in the blob and then removes them
            CloudBlobContainer container = BlobHelper.BlobClient.GetContainerReference(Container);
            BlobRequestOptions options = new BlobRequestOptions();
            options.UseFlatBlobListing = true;
            IEnumerable<IListBlobItem> blobs = container.ListBlobs(options);
            CloudBlob cbBlob;
            string mimeType;

            if (blobs.Count() > 0)
            {
                int containerLength = container.Name.Length + 2;
                foreach (IListBlobItem blob in blobs)
                {
                    if (blob is CloudBlob)
                    {
                        cbBlob = blob as CloudBlob;
                        fileName = cbBlob.Name;
                        string filePath = String.Concat(di.FullName, '\\', fileName);

                        mimeType = BlobHelper.getFileMimeTypeFromPath(filePath);
                        cbBlob.FetchAttributes();
                        // set cache-control header if necessary
                        if (cbBlob.Properties.CacheControl != BlobHelper.blobCacheHeader)
                        {
                            cbBlob.Properties.CacheControl = BlobHelper.blobCacheHeader;
                        }
                        if (cbBlob.Properties.ContentType != mimeType)
                        {
                            cbBlob.Properties.ContentType = mimeType;
                        }
                        cbBlob.SetProperties();

                        if (!File.Exists(filePath) || !isPathSafe(filePath))
                        {
                            Warning("  [" + Container + "\\" + fileName + "]: not found in system, but found in blob, adding deletion task");

                            BlobQueue.Add(new BlobTask()
                            {
                                Action = "delete",
                                BlobName = fileName,
                                ContainerName = Container,
                                FilePath = filePath
                            });
                        }
                    }
                }
            }

            return true;
        }
        return false;
    }
    catch (Exception ex)
    {
        if (ex is System.IO.PathTooLongException)
        {
            System.IO.PathTooLongException exeption = ex as PathTooLongException;
            Error(exeption.ToString());
        }
        else 
        {
            Error(ex.ToString());
        }

        return false;
    }
}


private bool isPathSafe(string path)
{
    //checks to see if the file is hidden or not, if so do not upload
    if ((File.GetAttributes(path) & FileAttributes.Hidden) == FileAttributes.Hidden)
        return false;

    //Checks to see if any of the folders in the path are hidden
    FileInfo fi = new FileInfo(path);
    if (isAnyPathDirHidden(fi.Directory))
        return false;

    //check to see if the file is one of the exception files, if so do not upload.
    return !Regex.IsMatch(path, regexFileExeption, RegexOptions.IgnoreCase | RegexOptions.Singleline);
}

/// <summary>
/// Checks to see if any of the folder's path folders are hidden or not.
/// </summary>
/// <param name="dir">The DirectoryInfo for the currently checked folder</param>
/// <returns>TRUE if the folder is hidden and FALSE if not</returns>
private bool isAnyPathDirHidden(DirectoryInfo dir)
{
    if (dir.Parent == null)
        return false;
    if ((File.GetAttributes(dir.FullName) & FileAttributes.Hidden) == FileAttributes.Hidden)
        return true;
    return isAnyPathDirHidden(dir.Parent);
}

// Upload a local file as a blob.
// Result: 0=success, 1=failed, retry scheduled, 2=failed

private int UploadBlob(BlobTask task)
{
    try
    {
        if (!File.Exists(task.FilePath))
        {
            Warning("   [" + task.BlobName + "]: file not found");
            return 2;
        }

        if (IsFileInUse(task.FilePath))
        {
            Warning("   [" + task.BlobName + "]: file in use");
            task.RemainingRetryCount--;
            if (task.RemainingRetryCount > 0)
            {
                Thread.Sleep(RETRY_SLEEP_INTERVAL);
                lock (BlobQueue)
                {
                    BlobQueue.Add(task);
                }
                return 1;
            }
            return 2;
        }

        if (BlobHelper.PutFileToBlob(task.FilePath, task.ContainerName, task.BlobName))
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }

    // Failed to upload due to a storage service problem.

    catch(StorageException ex)
    {
        Error(ex.ToString());
        Warning("   [" + task.BlobName + "]: storage error");
        task.RemainingRetryCount--;
        if (task.RemainingRetryCount > 0)
        {
            Thread.Sleep(RETRY_SLEEP_INTERVAL);
            lock (BlobQueue)
            {
                BlobQueue.Add(task);
            }
            return 1;
        }
        return 2;
    }

    // Failed to upload due to a file access problem.

    catch (IOException ex)
    {
        Error(ex.ToString());
        Warning("   [" + task.BlobName + "]: could not access file");
        task.RemainingRetryCount--;
        if (task.RemainingRetryCount > 0)
        {
            Thread.Sleep(RETRY_SLEEP_INTERVAL);
            lock (BlobQueue)
            {
                BlobQueue.Add(task);
            }
            return 1;
        }
        return 2;
    }
    catch (Exception ex)
    {
        Error(ex.ToString());
        return 2;
    }
}


// Delete a blob.

private bool DeleteBlob(BlobTask task)
{
    bool ret;
    if (BlobHelper.doesTheBlobExist(task.BlobName, Container))
    {
        ret = DeleteSingleBlob(task.ContainerName, task.BlobName);
    }
    else
    {
        //checks to see if the deletion task is a folder
        //the way it is checked if the virtual folder exists is to check for all subitems (even in subfolders) and then removed all found-
        ret = true;

        CloudBlobContainer container = BlobHelper.BlobClient.GetContainerReference(Container);
        CloudBlobDirectory test = container.GetDirectoryReference(task.BlobName);
        BlobRequestOptions options = new BlobRequestOptions();
        options.UseFlatBlobListing = true;
        IEnumerable<IListBlobItem> blobs = test.ListBlobs(options);
        if (blobs.Count() > 0)
        {
            foreach (IListBlobItem blob in blobs)
            {
                if (blob is CloudBlob)
                {
                    if (!DeleteSingleBlob(task.ContainerName, (blob as CloudBlob).Name))
                    {
                        ret = false;
                    }
                }
            }
        }
    }

    return ret;
}


private bool DeleteSingleBlob(string containerName, string blobName)
{
    try
    {
        return BlobHelper.DeleteBlob(containerName, blobName);
    }
    catch (Exception ex)
    {
        Error(ex.ToString());
        return false;
    }
}

0 个答案:

没有答案