7

现在我有这个代码:

int number = 0;
DirectoryInfo di = new DirectoryInfo(scpath + @"Screenshots\");

if (di.Exists) {

} else {
    di.Create();
}
int screenWidth = Screen.GetBounds(new Point(0, 0)).Width;
int screenHeight = Screen.GetBounds(new Point(0, 0)).Height;
Bitmap bmpScreenShot = new Bitmap(screenWidth, screenHeight);
Graphics gfx = Graphics.FromImage((Image)bmpScreenShot);
gfx.CopyFromScreen(0, 0, 0, 0, new Size(screenWidth, screenHeight));
bmpScreenShot.Save(di + "Screenshot_" + number, ImageFormat.Jpeg);

程序截取屏幕截图(有效)并保存。我想要做的是让程序检查并查看屏幕截图是否存在(“Screenshot_*”),如果不存在则创建它。如果是这样,请递增文件名,直到它达到“屏幕截图_”末尾未使用的数字。鉴于文件和递增更多,不确定如何处理。我正在考虑一个 for 循环,但我现在正在玩它。

4

8 回答 8

12

获取不存在的文件的名称听起来像是一种方法的工作。

string IndexedFilename(string stub, string extension) 
{
    int ix = 0;
    string filename = null;
    do {
        ix++;
        filename = String.Format("{0}{1}.{2}", stub, ix, extension);
    } while (File.Exists(filename));
    return filename;
}

如果您从多个线程调用它,则会出现竞争条件。假设您只有一个应用程序和应用程序中的一个线程要求文件名,那么这应该可以工作。

使用该方法的代码如下所示:

string di = Path.Combine(scpath, "Screenshots");
if (!Directory.Exists(di) { 
    Directory.Create(di); 
} 
int screenWidth = Screen.GetBounds(new Point(0, 0)).Width; 
int screenHeight = Screen.GetBounds(new Point(0, 0)).Height; 
Bitmap bmpScreenShot = new Bitmap(screenWidth, screenHeight); 
Graphics gfx = Graphics.FromImage((Image)bmpScreenShot); 
gfx.CopyFromScreen(0, 0, 0, 0, new Size(screenWidth, screenHeight));
string filename = IndexedFilename(Path.Combine(di,"Shot_"),"jpg");
bmpScreenShot.Save(filename, ImageFormat.Jpeg); 
于 2012-04-12T21:02:22.370 回答
9

就像@Quintin 所说,使用 datetime 作为文件名:

string filename = Path.Combine(
    di.FullName,
    String.Format("{0}.jpg", DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss")));
bmpScreenShot.Save(filename, ImageFormat.Jpeg);
于 2012-04-12T21:03:28.210 回答
3

这是一种可能

string[] files = System.IO.Directory.GetFiles(scpath, "Screenshot_*.jpg");
string baseName = Path.Combine(scpath, "Screenshot_");
string filename;
int i = 0;
do {
    filename = baseName + ++i + ".jpg";
} while (files.Contains(filename));

这种方法的优点是文件系统只被查询一次。如果文件号变大,请考虑将文件名添加到哈希集中以进一步加快检查速度:

var files = new HashSet<string>(Directory.GetFiles(scpath, "Screenshot_*.jpg"));
于 2012-04-12T21:06:08.020 回答
2

我会使用 GUID ...

try{
    bmpScreenShot.Save(di + "Screenshot_" + Guid.NewGuid().ToString(), ImageFormat.Jpeg);
}catch(Exception e)
{ 
    //handle the problems here, for example if file already exists, try again
}

在您用完唯一的 GUID 之前,这应该可以正常工作......

于 2012-04-12T21:07:16.710 回答
2

不要使用数字来区分屏幕截图,而是使用时间戳:

string currentDT = string.Format("{0:D4}.{1:D2}.{2:D2}-{3:D2}.{4:D2}.{5:D2}",
                   DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day,
                   DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second)
bmpScreenShot.Save(di + "Screenshot_" + currentDT, ImageFormat.Jpeg); 
于 2012-04-12T21:02:39.737 回答
1
public static string MakeUniqueFileName(string file)
{
    string dir = Path.GetDirectoryName(file);
    string fn;

    for (int i = 0; ; ++i)
    {
        fn = Path.Combine(dir, string.Format(file, i));

        if (!File.Exists(fn))
            return fn;
    }
}

像这样使用它:

string file = scpath + @"Screenshots\" + "Screenshot_{0}.png";
bmpScreenShot.Save(MakeUniqueFileName(file), ImageFormat.Jpeg);
于 2012-04-12T21:18:05.970 回答
0

这将创建 output_0.jpg output_1.jpg ... output_n.jpg:

int filecount = 0;
string path = Environment.CurrentDirectory;
for (int i = 0; File.Exists(path + @"\output_" + i + ".jpg"); i++)
{
    filecount = i + 1;
}
File.Create(path + @"\output_" + filecount + ".jpg");
于 2018-11-09T19:10:04.920 回答
0
private static string GetUniqueFile(string path, string file, string ext)
{
    int filecount = 0;
    int i = 0;
    for (i = 0; File.Exists(path + "\\" + file + "_" + i + "." + ext); i++)
    {
        filecount = i + 1;
    }

    return path + "\\" + file + "_" + i.ToString() + "." + ext;
}
于 2019-02-19T21:38:30.097 回答