写了个读取EXIF拍摄时间更改文件名的程序 但读取到的string始终有问题 求助

问题描述

主程序:usingSystem;usingSystem.Collections.Generic;usingSystem.Windows.Forms;usingSystem.IO;namespacePhoto_name_change_tool{publicpartialclassForm1:Form{publicList<string>FilesName=newList<string>();publicForm1(){InitializeComponent();}privatevoidbutton1_Click(objectsender,EventArgse){FolderBrowserDialogFilesPathDialog=newFolderBrowserDialog();FilesPathDialog.Description="BrowsePhotoFilesPath:";if(FilesPathDialog.ShowDialog()==DialogResult.OK){stringFilesPath=FilesPathDialog.SelectedPath;textBox1.Text=FilesPath;ScanPhotoFiles(FilesPath);}}privatevoidScanPhotoFiles(stringFilesPath){FilesName.Clear();DirectoryInfoFilesFolder=newDirectoryInfo(FilesPath);for(inti=0;i<FilesFolder.GetFiles().Length;i++){if(FilesFolder.GetFiles()[i].Length>0&&FilesFolder.GetFiles()[i].Extension==".jpg"){ListViewItemlvi=newListViewItem();lvi.Text=(i+1).ToString();lvi.SubItems.Add(FilesFolder.GetFiles()[i].Name);lvi.SubItems.Add("-");lvi.SubItems.Add("-");lvi.SubItems.Add("-");listView1.Items.Add(lvi);FilesName.Add(FilesFolder.GetFiles()[i].Name);}}ChangePhotoFilesName();}privatevoidChangePhotoFilesName(){for(inti=0;i!=FilesName.Count;i++){Exif.Picturexifem=newExif.Picturexif();Exif.Picturexif.Metadatam=em.GetEXIFMetaData(textBox1.Text+@""+FilesName[i]);//获取EXIF照片拍摄时间if(m.DatePictureTaken.DisplayValue!=null){listView1.Items[i].SubItems[2].Text=m.DatePictureTaken.DisplayValue;}else{listView1.Items[i].SubItems[2].Text="-";}//更改文件名为EXIF照片拍摄时间if(listView1.Items[i].SubItems[2].Text!="-"){stringTargetName=listView1.Items[i].SubItems[2].Text.ToString();TargetName=TargetName.Replace(":","");TargetName=TargetName.Replace("","_");listView1.Items[i].SubItems[3].Text=TargetName+".jpg";if(listView1.Items[i].SubItems[1].Text!=listView1.Items[i].SubItems[3].Text){//File.Move(textBox1.Text+@""+listView1.Items[i].SubItems[1].Text,textBox1.Text+@""+listView1.Items[i].SubItems[3].Text);listView1.Items[i].SubItems[4].Text="Successful";}}}}}}

Exif类参照:http://www.cnblogs.com/yeminglong/p/3172719.html问题出在listView1.Items[i].SubItems[2].Text=m.DatePictureTaken.DisplayValue;listView1.Items[i].SubItems[3].Text=TargetName+".jpg";没有后面的.jpg且File.Move(textBox1.Text+@""+listView1.Items[i].SubItems[1].Text,textBox1.Text+@""+listView1.Items[i].SubItems[3].Text);提示路径中有非法字符求解,显示都是正常的,为啥就是无法拼接这个字符串,为啥更改文件名会出现路径非法。感谢!

解决方案

解决方案二:
那你倒把路径发出来看看啊,简单的验证方法就是把得到路径直接在文件夹地址栏里运行下,如果报错那肯定是你的问题
解决方案三:
引用1楼xdashewan的回复:

那你倒把路径发出来看看啊,简单的验证方法就是把得到路径直接在文件夹地址栏里运行下,如果报错那肯定是你的问题

路径C:UsersAirDesktop新建文件夹源文件名:C:UsersAirDesktop新建文件夹1.jpg新文件名:C:UsersAirDesktop新建文件夹20150301_135212.jpgMessageBox显示出来也正常,但执行时就报错。相当诡异。
解决方案四:
已将项目压缩上传至临时服务器:http://dev.airsky.cc/csdn_16615.rar求解析。
解决方案五:
不知道你这字段怎么输出出来的ListViewItemlvi=newListViewItem();lvi.Text=(i+1).ToString();lvi.SubItems.Add(FilesFolder.GetFiles()[i].Name);lvi.SubItems.Add("-");lvi.SubItems.Add("-");lvi.SubItems.Add("-");

File.Move(textBox1.Text+@""+listView1.Items[i].SubItems[1].Text,textBox1.Text+@""+listView1.Items[i].SubItems[3].Text);

光看这两段代码,我可以说listView1.Items[i].SubItems[1]里绝对没有文件名
解决方案六:
引用4楼xdashewan的回复:

不知道你这字段怎么输出出来的ListViewItemlvi=newListViewItem();lvi.Text=(i+1).ToString();lvi.SubItems.Add(FilesFolder.GetFiles()[i].Name);lvi.SubItems.Add("-");lvi.SubItems.Add("-");lvi.SubItems.Add("-");

File.Move(textBox1.Text+@""+listView1.Items[i].SubItems[1].Text,textBox1.Text+@""+listView1.Items[i].SubItems[3].Text);

光看这两段代码,我可以说listView1.Items[i].SubItems[1]里绝对没有文件名

里面是有文件名的,上面有遍历。如果可以的话,希望看下我上传的项目。非常感谢!
解决方案七:
引用5楼x_airsky的回复:

里面是有文件名的,上面有遍历。如果可以的话,希望看下我上传的项目。非常感谢!

我当然看了遍历了,但你的遍历里除了一个判断,其余没有任何对SubItems[1]的操作for(inti=0;i!=FilesName.Count;i++){Exif.Picturexifem=newExif.Picturexif();Exif.Picturexif.Metadatam=em.GetEXIFMetaData(textBox1.Text+@""+FilesName[i]);//获取EXIF照片拍摄时间if(m.DatePictureTaken.DisplayValue!=null){listView1.Items[i].SubItems[2].Text=m.DatePictureTaken.DisplayValue;}else{listView1.Items[i].SubItems[2].Text="-";}//更改文件名为EXIF照片拍摄时间if(listView1.Items[i].SubItems[2].Text!="-"){stringTargetName=listView1.Items[i].SubItems[2].Text.ToString();TargetName=TargetName.Replace(":","");TargetName=TargetName.Replace("","_");listView1.Items[i].SubItems[3].Text=TargetName+".jpg";if(listView1.Items[i].SubItems[1].Text!=listView1.Items[i].SubItems[3].Text){//File.Move(textBox1.Text+@""+listView1.Items[i].SubItems[1].Text,textBox1.Text+@""+listView1.Items[i].SubItems[3].Text);listView1.Items[i].SubItems[4].Text="Successful";}}}

解决方案八:
引用6楼xdashewan的回复:

Quote: 引用5楼x_airsky的回复:
里面是有文件名的,上面有遍历。如果可以的话,希望看下我上传的项目。非常感谢!

我当然看了遍历了,但你的遍历里除了一个判断,其余没有任何对SubItems[1]的操作for(inti=0;i!=FilesName.Count;i++){Exif.Picturexifem=newExif.Picturexif();Exif.Picturexif.Metadatam=em.GetEXIFMetaData(textBox1.Text+@""+FilesName[i]);//获取EXIF照片拍摄时间if(m.DatePictureTaken.DisplayValue!=null){listView1.Items[i].SubItems[2].Text=m.DatePictureTaken.DisplayValue;}else{listView1.Items[i].SubItems[2].Text="-";}//更改文件名为EXIF照片拍摄时间if(listView1.Items[i].SubItems[2].Text!="-"){stringTargetName=listView1.Items[i].SubItems[2].Text.ToString();TargetName=TargetName.Replace(":","");TargetName=TargetName.Replace("","_");listView1.Items[i].SubItems[3].Text=TargetName+".jpg";if(listView1.Items[i].SubItems[1].Text!=listView1.Items[i].SubItems[3].Text){//File.Move(textBox1.Text+@""+listView1.Items[i].SubItems[1].Text,textBox1.Text+@""+listView1.Items[i].SubItems[3].Text);listView1.Items[i].SubItems[4].Text="Successful";}}}

但编译后确实有内容,且把move后面的新文件名改为i.tstring()+".jpg"是可以执行更改文件名的。
解决方案九:
引用7楼x_airsky的回复:

但编译后确实有内容,且把move后面的新文件名改为i.tstring()+".jpg"是可以执行更改文件名的。

断点调试下
解决方案十:
引用8楼xdashewan的回复:

Quote: 引用7楼x_airsky的回复:
但编译后确实有内容,且把move后面的新文件名改为i.tstring()+".jpg"是可以执行更改文件名的。

断点调试下

调试也看不懂到底为什么出错..==大神可以帮忙看下咩。。
解决方案十一:
稍微改动了下代码,你试着看看,能否看明白1、listview中的每个item应该都有一个文件名对吧,所以用foreach循环lv.Items可能方便一点2、displayValue应该是日期时间,所以可以先转换为datetiem,下面可以直接使用了3、格式化datetime类型的数据就不用拼接字符串了4、system.io.path中有几个静态方法很好用的,比如组合路径string[]fileNames=newstring[0];ListViewlv=newListView();TextBoxtextBox1=newTextBox();foreach(ListViewItemiteminlv.Items){//Exif.Picturexifem=newExif.Picturexif();//Exif.Picturexif.Metadatam=em.GetEXIFMetaData(textBox1.Text+@""+fileNames[i]);vardir=textBox1.Text;varfileName=item.SubItems[1].Text;vardisplayValue=default(object);//没有对象,你懂的vardate=DateTime.Now;varhasValue=DateTime.TryParse(displayValue?.ToString(),outdate);//获取EXIF照片拍摄时间if(hasValue){item.SubItems[2].Text=string.Format("{0:yyyy/MM/ddHH:mm:ss",date);//更改文件名为EXIF照片拍摄时间stringtarget=string.Format("{0:yyyyMMdd_HHmmss}.jpg",date);item.SubItems[3].Text=target;if(fileName!=target){varoldPath=System.IO.Path.Combine(dir,fileName);varnewPath=System.IO.Path.Combine(dir,target);//File.Move(textBox1.Text+@""+listView1.Items[i].SubItems[1].Text,textBox1.Text+@""+listView1.Items[i].SubItems[3].Text);item.SubItems[4].Text="Successful";}}else{item.SubItems[2].Text="-";}}

解决方案十二:
引用10楼qqamoon的回复:

稍微改动了下代码,你试着看看,能否看明白1、listview中的每个item应该都有一个文件名对吧,所以用foreach循环lv.Items可能方便一点2、displayValue应该是日期时间,所以可以先转换为datetiem,下面可以直接使用了3、格式化datetime类型的数据就不用拼接字符串了4、system.io.path中有几个静态方法很好用的,比如组合路径string[]fileNames=newstring[0];ListViewlv=newListView();TextBoxtextBox1=newTextBox();foreach(ListViewItemiteminlv.Items){//Exif.Picturexifem=newExif.Picturexif();//Exif.Picturexif.Metadatam=em.GetEXIFMetaData(textBox1.Text+@""+fileNames[i]);vardir=textBox1.Text;varfileName=item.SubItems[1].Text;vardisplayValue=default(object);//没有对象,你懂的vardate=DateTime.Now;varhasValue=DateTime.TryParse(displayValue?.ToString(),outdate);//获取EXIF照片拍摄时间if(hasValue){item.SubItems[2].Text=string.Format("{0:yyyy/MM/ddHH:mm:ss",date);//更改文件名为EXIF照片拍摄时间stringtarget=string.Format("{0:yyyyMMdd_HHmmss}.jpg",date);item.SubItems[3].Text=target;if(fileName!=target){varoldPath=System.IO.Path.Combine(dir,fileName);varnewPath=System.IO.Path.Combine(dir,target);//File.Move(textBox1.Text+@""+listView1.Items[i].SubItems[1].Text,textBox1.Text+@""+listView1.Items[i].SubItems[3].Text);item.SubItems[4].Text="Successful";}}else{item.SubItems[2].Text="-";}}

感谢指导!但似乎varhasValue=DateTime.TryParse(displayValue?.ToString(),outdate);无法转换为DateTime型所有都返回False
解决方案十三:
引用11楼x_airsky的回复:

varhasValue=DateTime.TryParse(displayValue?.ToString(),outdate);无法转换为DateTime型所有都返回False

DateTime.TryParse方法尝试转换一个日期时间,成功则返回true,且date参数包含转换后的值,否则返回false,date貌似=DateTime.MinValue

时间: 2024-12-11 10:12:42

写了个读取EXIF拍摄时间更改文件名的程序 但读取到的string始终有问题 求助的相关文章

用Objective-C写了一个简单的批量更改文件名的程序

前言:因为本人要高仿一个app,从app中解压asserts得到的所有图片文件,文件名都带有~iPhone这个干扰的名字,为了去除这个~iPhone这个字符串,所以本人写了个简答的批量更改所有文件名的程序. 程序员就是应该会利用程序来帮自己偷懒,如果你一个个文件手动去改,那你就太low了啊. 因为这个程序用到的NSFileManager的很多方法本人不是很熟悉,也是花了点时间去熟悉NSFileManager的一些方法,所以写下这个笔记做个笔记,省的下次又需要却还是遗忘了方法.   我的基本需求,

如何快速更改文件名

  我们知道,很多时候需要更改文件名,在一般情况下,点击右键,然后点击重命名,再输入新的名称,这样未尝不可,但是如果更改的文件较多,就非常麻烦,我们可以使用快捷键F2,点击文件,按F2,然后就可以改名了,这样是不是很简单啊?

java遍历服务器里的所有excel文件读取特定单元格的值,循环读取文件的代码怎么写

问题描述 java遍历服务器里的所有excel文件读取特定单元格的值,循环读取文件的代码怎么写 package com.excel.action; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import jxl.Cell; import jxl.CellType; import jxl.LabelCell; import jxl.Sheet; import jxl.Workbo

c++ 写一个查询系统 ,不用数据库,从txt中读取数据,求大神指点啊 ...

问题描述 c++ 写一个查询系统 ,不用数据库,从txt中读取数据,求大神指点啊 ... 解决方案 你首先的规范text 文档的数据格式 ,然后通过文件流从文件中读取数据 解决方案二: 直接用ifstream读入,然后getline一行行读取,然后可以用sscanf格式化提取(因为你是用,分隔的) 可以把数据都存储下来(存在结构体数组或者vector都行) 之后再实现查找的功能

手把手教你写Linux设备驱动---input子系统(三)--电容屏事件坐标读取(基于友善之臂4412开发板)

前面我们学习了鼠标是如何如何通过应用程序来读取事件和坐标值的,后面也写了一个简单的input系统的按键驱动程序. 博文如下,讲的内容非常清楚,给小白来入手当然是非常容易的: http://blog.csdn.net/morixinguan/article/details/69808832 这节,我们来学习一下触摸屏事件获取,然后上一个基于4412开发板ft5x0x型号的x,y坐标值读取,后面我们将从零开始实现这款触摸屏的驱动程序: 首先,我们要明白一个概念,触摸屏在input系统中是一类什么事件

javascript-用uploadify3.2怎么读取上传的文件名到文本框

问题描述 用uploadify3.2怎么读取上传的文件名到文本框 要去掉后缀名 'onSelect': function(e, queueID, fileObj) { $('#uploadify').uploadify('upload'); alert("文件名:" + fileObj.name + "rn" + "文件类型:" + fileObj.type ); }, <input class="form_title"

c#-aspx页面下载文件时如何更改文件名

问题描述 aspx页面下载文件时如何更改文件名 这是我的下载路径 http://localhost:17262/sqlExcel/goods.xls 下载的时候如何将goods.xls更为主表.xls 解决方案 只能由肯段另存为,要么你就用aspx动态输出goods.xls,设置content-disposition为attachment;filename="主表.xls",用代码修改文件名 解决方案二: 下载文件时,文件名乱码.HTTP下载文件时的文件名编码问题seagull --

C++程序需要读取数据文件,但是总是读取不出啊

问题描述 C++程序需要读取数据文件,但是总是读取不出啊 图上的表格就是要读取的数据,程序如下,主要是我不太清楚数据文件格式是什么,程序应该没错#include#include include""stdlib.h"" #include""stdio.h""#include#includeusing namespace std;#include""time.h""#include"

一起谈.NET技术,asp.net程序来读取多语言版本Ini配置文件

这是asp.net程序来读取多语言版本Ini配置文件的开发示例,主要分为以下三个部分: 1. Ini 配置文件 2. 读取Ini配置文件的DLL 3. Web页面调用与内容显示 4. 数据库表T_User,如右图  首先说明一下Ini 文件格式:如下图其中[M_Index]节点和该节点下的所有的key和value,其中[M_Index]节点的名称是对应开发示例中的每个页面所在的文件夹名称的第一个字母加下划线再加该页面的名称组合而成,如 M_Index 则表示Manager文件夹下面有一个Inde