我在这里结束了我的智慧。我正在编写一些过程代码,它从excel工作表中获取文件的名称。然后代码应该从基本目录开始递归地找到每个文件,然后将每个文件复制到一个位置。
我的代码迭代一次,然后在第二次迭代时产生一个错误,指出我的' justPath'第47行的变量不能为空。
我已经发布了以下代码。非常感谢任何帮助。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
using System.IO;
namespace ExcelManip
{
class Program
{
static void Main(string[] args)
{
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(@"C:\Users\employee1234\Desktop\Reload_837_X12_Raw.xlsx", 0, false, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", true, false, 0, true, 1, 0);
Excel._Worksheet xlWorksheet = (Excel._Worksheet)xlWorkbook.Sheets[4];
Excel.Range xlRange = xlWorksheet.UsedRange;
int rowCount = xlRange.Rows.Count;
int colCount = xlRange.Columns.Count;
int actualRows = rowCount - 1;
int y = 0;
int z = 1;
string targetPath = @"C:\Users\employee1234\Desktop\dropfiles";
for (int count = 11; count <= rowCount; count++){
var currentIndex = count;
var yy = y;
Console.WriteLine(yy);
string temp = (string)(xlRange.Cells[currentIndex, 2] as Excel.Range).Value2;
string[] filePaths = Directory.GetFiles(@"\\fileshare01\Data\subfolder1\subfolder2\", temp, SearchOption.AllDirectories);
Array.Resize(ref filePaths, filePaths.Length + 1);
string filePath = filePaths[yy];
string justPath = Path.GetDirectoryName(filePath);
string sourceFile = System.IO.Path.Combine(justPath, temp);
string destFile = System.IO.Path.Combine(targetPath, temp);
Console.WriteLine("File Path " + z+ " of "+ actualRows +" : "+ filePath + "\n");
System.IO.File.Copy(sourceFile, destFile, true);
y++;
z++;
}
xlWorkbook.Save();
xlWorkbook.Close(0);
xlApp.Quit();
GC.Collect();
}
}
}
答案 0 :(得分:1)
Path.GetDirectoryName
方法:
返回值类型:System.String路径的目录信息,或 如果path表示根目录或为null ,则返回null。返回String.Empty 如果path不包含目录信息。
进一步评论:
在大多数情况下,此方法返回的字符串包含所有字符串 路径中的字符,但不包括最后一个 DirectorySeparatorChar或AltDirectorySeparatorChar。 如果路径 由根目录组成,例如“c:\”,返回null。注意 此方法不支持使用“file:”的路径。因为 返回的路径不包括DirectorySeparatorChar或 AltDirectorySeparatorChar,将返回的路径传回 GetDirectoryName方法将导致截断一个文件夹 每次后续调用结果字符串的级别。例如,传球 路径“C:\ Directory \ SubDirectory \ test.txt”进入 GetDirectoryName方法将返回“C:\ Directory \ SubDirectory”。 将该字符串“C:\ Directory \ SubDirectory”传入 GetDirectoryName将生成“C:\ Directory”。
答案 1 :(得分:1)
问题是你有一个变量y
,你每次在循环中递增。我假设您认为此行附加到数组:
string[] filePaths = Directory.GetFiles(@"\\fileshare01\Data\subfolder1\subfolder2\", temp, SearchOption.AllDirectories);
它没有。它创建了一个新数组。因此,假设只有一个文件具有您想要的名称,则下次循环y == 1
时,您将指向返回结果的外部指向附加到数组的空值。
如果要存储文件的实际路径,则需要在循环外定义一个变量并添加到该变量。例如List<string>
。但由于你只是复制,所以不需要这样做。
另外,为什么要复制yy
,currentIndex
之类的变量,如果它们只指向未经修改的变量y
和count
?
即使你知道总是有一个带有该名称的文件,实际测试它仍然不会受到伤害,当它发生时文件不存在,您可以输出错误。
你的循环应该更像:
var paths = new List<string>();
for (int count = 11; count <= rowCount; count++){
string temp = (string)(xlRange.Cells[count, 2] as Excel.Range).Value2;
string[] filePaths = Directory.GetFiles(@"\\fileshare01\Data\subfolder1\subfolder2\", temp, SearchOption.AllDirectories);
if ((filePaths == null) || (filePaths.Length == 0))
{
Console.WriteLine("Didn't find file: " + temp);
continue; // Or break, or exit, or...
}
string filePath = filePaths[0];
// If the temp is a single filename (no globs), you don't even need the next two lines
string justPath = Path.GetDirectoryName(filePath);
string sourceFile = System.IO.Path.Combine(justPath, temp);
string destFile = System.IO.Path.Combine(targetPath, temp);
Console.WriteLine("File Path " + z+ " of "+ actualRows +" : "+ filePath + "\n");
System.IO.File.Copy(sourceFile, destFile, true);
paths.Add(sourceFile); // or destFile, or what you want to store
z++;
}
答案 2 :(得分:0)
Array.Resize(ref filePaths,filePaths.Length + 1);此行将空字符串附加到filePaths数组。如果yy计数器那么远就可以了..