修改文件创建时间

修改文件创建时间.txt为什么我们在讲故事的时候总要加上从前?开了一夏的花,终落得粉身碎骨,却还笑着说意义。修改文件创建时间

https://www.360docs.net/doc/3c4990197.html,/f/xiu.rar
上面可以下载一个小程序,可以批量修改文件创建时间

摘要:本文讲述了在Visual C++ 下编程实现对磁盘文件的属性进行获取以及更改的一般方法,并给出部分相关的关键代码。

一、 引言

文件是数据在磁盘上最常用的一种存放形式,也是在程序设计中与之经常打交道的一种编程对象,不少程序尤其是数据传输和处理类的应用程序更是需要频繁的创 建、读取和写入文件。对于一些要求不是很严格的程序,我们往往只关心文件的内容是否正确、文件大小是否有增减或是再严格一些,看文件名是否符合规定等等。 以上这些要素对于大多数程序而言显然是可以满足实际需求的,但对于某些特殊行业的一些有着比较严格要求的软件系统,仅有以上要素还是远远不够的,往往还需 要对文件的所有属性诸如文件的创建时间、文件的最后访问时间、文件的最后修改时间等等进行提取处理与重新设置。

二、 WIN32_FIND_DATA结构

关于文件的全部属性信息,总计有以下以下9种:文件的标题名、文件的属性(只读、存档,隐藏等)、文件的创建时间、文件的最后访问时间、文件的最后修改时间、文件大小的高位双字、文件大小的低位双字、保留、保留。在这里只有文件标题名和文件的长度可以通过CFile类比较方便的获得,而对于其他几种属性的获取和设置就无能为力了。

在用findfirst()和findnext()函数去查找磁盘文件时经常使用的一个数据结构WIN32_FIND_DATA的成员变量里包含了以上所有的文件属性,因此可以通过这个结构作为获取和更改文件属性的手段。该结构的内容如下:

typedef struct _WIN32_FIND_DATA {
DWORD dwFileAttributes; //文件属性
FILETIME ftCreationTime; // 文件创建时间
FILETIME ftLastAccessTime; // 文件最后一次访问时间
FILETIME ftLastWriteTime; // 文件最后一次修改时间
DWORD nFileSizeHigh; // 文件长度高32位
DWORD nFileSizeLow; // 文件长度低32位
DWORD dwReserved0; // 系统保留
DWORD dwReserved1; // 系统保留
TCHAR cFileName[ MAX_PATH ]; // 长文件名
TCHAR cAlternateFileName[ 14 ]; // 8.3格式文件名
} WIN32_FIND_DATA, *PWIN32_FIND_DATA;

可以通过FindFirstFile()函数根据当前的文件存放路径查找该文件来把待操作文件的相关属性读取到WIN32_FIND_DATA结构中去:

WIN32_FIND_DATA ffd ;
HANDLE hFind = FindFirstFile("c:\\test.dat",&ffd);

在使用这个结构时不能手工修改这个结构中的任何数据,结构对于开发人员来说只能作为一个只读

数据,其所有的成员变量都会由系统完成填写。在MSDN帮助中可以查找到关于WIN32_FIND_DATA结构的更加详细的说明。

三、 文件属性信息的获取与更改

为了更好的保存获取到的文件属性信息,对应于文件属性构造一个自定义的FILE_INFO数据结构,获取的属性信息可暂存于此:

typedef struct _FILE_INFO {
TCHAR szFileTitle[128]; //文件的标题名
DWORD dwFileAttributes; //文件的属性
FILETIME ftCreationTime; //文件的创建时间
FILETIME ftLastAccessTime; //文件的最后访问时间
FILETIME ftLastWriteTime; //文件的最后修改时间
DWORD nFileSizeHigh; //文件大小的高位双字
DWORD nFileSizeLow; //文件大小的低位双字
DWORD dwReserved0; //保留,为0
DWORD dwReserved1; //保留,为0
} FILE_INFO, * PFILE_INFO;

首先用FindFirstFile()函数将文件属性获取到WIN32_FIND_DATA 结构对象FindFileData中去,之后可以用FindClose()将其关闭,并把FindFileData中的有关文件属性信息的内容复制到自定 义结构FILE_INFO的结构对象FileInfo中备用。下面是关于这部分描述的部分关键代码:

//声明结构对象
FILE_INFO FileInfo;
WIN32_FIND_DATA FindFileData;
……
//获取文件属性信息
FindClose(FindFirstFile("Test.txt",&FindFileData));
memset(&FileInfo,0,sizeof(FILE_INFO));
……
//将文件属性信息保存到FileInfo中备用
strcpy(FileInfo.szFileTitle,myFile.GetFileTitle());
FileInfo.dwFileAttributes = FindFileData.dwFileAttributes;
FileInfo.ftCreationTime = FindFileData.ftCreationTime;
FileInfo.ftLastAccessTime = FindFileData.ftLastAccessTime;
FileInfo.ftLastWriteTime = FindFileData.ftLastWriteTime;
FileInfo.nFileSizeHigh = FindFileData.nFileSizeHigh;
FileInfo.nFileSizeLow = FindFileData.nFileSizeLow;
……

在获取到文件的原始属性信息后既可以原封不动的将属性重新写到文件,也可以对其中某一项或某几项属性内容进行修改后再行写入文件,从而达到更改文件属性 的目的。比如可以用SetFileTime()函数设置文件的创建时间、最近一次访问时间以及最近一次修改的时间等等:

SetFileTime((HANDLE)destFile.m_hFile, //待写入的文件句柄
&FileInfo.ftCreationTime, //文件的创建时间
&FileInfo.ftLastAccessTime, //文件最近一次的访问时间
&FileInfo.ftLastWriteTime); //文件最近一次的修改时间

也可以用SetFileAttributes() 函数实现对文件属性的修改:

SetFileAttributes(FileInfo.szFileTitle,FileInfo.dwFileAttributes);

至于文件名的修改则更加简单,直接在创建文件时在CreateFile()或CFile类的成员函数Open里直接对文件名参数进行设置即可。



三层架构
三层架构,数据层(DAL)、逻辑层(BLL)、表示层(UI);
三层结构的优点
分层式结构究竟其优势何在?Martin Fowler在《Patterns of Enterprise Appl

ication Architecture》一书中给出了答案:
1、开发人员可以只关注整个结构中的其中某一层;
2、可以很容易的用新的实现来替换原有层次的实现;
3、可以降低层与层之间的依赖;
4、有利于标准化;
5、利于各层逻辑的复用。
概括来说,分层式设计可以达至如下目的:分散关注、松散耦合、逻辑复用、标准定义。
一个好的分层式结构,可以使得开发人员的分工更加明确。一旦定义好各层次之间的接口,负责不同逻辑设计的开发人员就可以分散关注,齐头并进。例如UI人员只需考虑用户界面的体验与操作,领域的设计人员可以仅关注业务逻辑的设计,而数据库设计人员也不必为繁琐的用户交互而头疼了。每个开发人员的任务得到了确认,开发进度就可以迅速的提高。
松散耦合的好处是显而易见的。如果一个系统没有分层,那么各自的逻辑都紧紧纠缠在一起,彼此间相互依赖,谁都是不可替换的。一旦发生改变,则牵一发而动全身,对项目的影响极为严重。降低层与层间的依赖性,既可以良好地保证未来的可扩展,在复用性上也是优势明显。每个功能模块一旦定义好统一的接口,就可以被各个模块所调用,而不用为相同的功能进行重复地开发。
进行好的分层式结构设计,标准也是必不可少的。只有在一定程度的标准化基础上,这个系统才是可扩展的,可替换的。而层与层之间的通信也必然保证了接口的标准化。
如果是一个考试系统,考试合格的最低分数线要改,只需要修改业务逻辑相对应函数就可以了,只要此函数的入口参数和返回内容不变,在客户端不需作任何改动。在这里,看到了面向对象编程的特性之一封装性的优点,而这一点在开发大型应用时尤其有用,可以把开发人员分成两组,一组负责开发界面层,另一组负责开发商业逻辑层,双方只要按照事先商定的函数接口,并行地开发就可以,而不必向从前那样,后面的工作必须等前面的工作完成后才能开始。当然,这样的开发模式需要很好的项目协调和文档作支持。
如果现在用的系统是SQL SERVER数据库,由于各种原因要更改用ORACLE。如果不是三层结构系统的话,可能需要改很多代码,延长了开发周期。现在使用了三层结构,只要在加一个Oracle的数据访问层。这样就可以实现多数据库了。
现在可能要做另外一个系统了,该系统也要对数据库进行操作。如果以前编写过,这样的一个数据层。只要把以前写的那个数据层拷贝过来就可以了。实现代码复用。从而减短了软件的开发周期了。
三层结构的缺点
“金无足赤,人无完人”,分层式结构也不可避免具有一些缺陷:
1、

降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。
2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。
基于组件的三层B/S结构概述
在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层、业务逻辑层(又或成为领域层)、表示层。
三层结构原理
3个层次中,系统主要功能和业务逻辑都在业务逻辑层进行处理。
所谓三层体系结构,是在客户端与数据库之间加入了一个“中间层”,也叫组件层。这里所说的三层体系,不是指物理上的三层,不是简单地放置三台机器就是三层体系结构,也不仅仅有B/S应用才是三层体系结构,三层是指逻辑上的三层,即使这三个层放置到一台机器上。
三层体系的应用程序将业务规则、数据访问、合法性校验等工作放到了中间层进行处理。通常情况下,客户端不直接与数据库进行交互,而是通过COM/DCOM通讯与中间层建立连接,再经由中间层与数据库进行交互。
表示层
位于最外层(最上层),离用户最近。用于显示数据和接收用户输入的数据,为用户提供一种交互式操作的界面
业务逻辑层
业务逻辑层(Business Logic Layer)无疑是系统架构中体现核心价值的部分。它的关注点主要集中在业务规则的制定、业务流程的实现等与业务需求有关的系统设计,也即是说它是与系统所应对的领域(Domain)逻辑有关,很多时候,也将业务逻辑层称为领域层。例如Martin Fowler在《Patterns of Enterprise Application Architecture》一书中,将整个架构分为三个主要的层:表示层、领域层和数据源层。作为领域驱动设计的先驱Eric Evans,对业务逻辑层作了更细致地划分,细分为应用层与领域层,通过分层进一步将领域逻辑与领域逻辑的解决方案分离。
业务逻辑层在体系架构中的位置很关键,它处于数据访问层与表示层中间,起到了数据交换中承上启下的作用。由于层是一种弱耦合结构,层与层之间的依赖是向下的,底层对于上层而言是“无知”的,改变上层的设计对于其调用的底层而言没有任何影响。如果在分层设计时,遵循了面向接口设计的思想,那么这种向下的依赖也应该是一种弱依赖关系。因而在不改变接口定义的前提下,理想的分层式架构,应该是一个支持可抽取、可替换的“抽屉”式架构。正因

为如此,业务逻辑层的设计对于一个支持可扩展的架构尤为关键,因为它扮演了两个不同的角色。对于数据访问层而言,它是调用者;对于表示层而言,它却是被调用者。依赖与被依赖的关系都纠结在业务逻辑层上,如何实现依赖关系的解耦,则是除了实现业务逻辑之外留给设计师的任务。
数据层
数据访问层:有时候也称为是持久层,其功能主要是负责数据库的访问,可以访问数据库系统、二进制文件、文本文档或是XML文档。
简单的说法就是实现对数据表的Select,Insert,Update,Delete的操作。如果要加入ORM的元素,那么就会包括对象和数据表之间的mapping,以及对象实体的持久化。










MVC与三层架构的异同点
同样是架构级别的,它们有什么相同点和不同点呢?这篇文章讨论一下它们的异同点。希望能帮助读者理解其中的玄机。 :)
其实它们相同的地方在于他们都有一个表现层。
但是他们不同的地方在于其他的两个层。
首先先解释一下MVC。V即View.是视图的意思。C即Controler.是控制器的意思。而M即Model,是模型的意思。这三个里.最不容易理解的应该是Model.就是什么是Model,而为什么叫Model。我先不说为什么叫Model,先解释Controler。
Controller是控制器的意思,所谓控制器,就是将用户请求转发给模型层,经过处理后把结果返回到界面展现的一个中间层,那么Controler到底管什么工作呢?先不说.先来看下在Java Web中这三个层一般的定义,一般在Java Web里,JSP充当V,Servlet充当C,JavaBean充当M,这里的Servlet管什么工作呢?接受输入,转到Model层去处理,处理结果保存后转发到JSP,然后展现数据。所以它的功能就是控制器的基本功能,它就管转发,在V和M之间转来转去。
再来说说M,即Model,在Java Web里说的是JavaBean,我认识的很多人都把JavaBean误认为是实体类,其实JavaBean有比实体类更丰富的定义,在JavaBean中除了其属性和字段,还可以有行为及其事件,JavaBean可以理解为普通Java对象。Java普通对象,就是符合Java规范的所有对象,这和实体类完全是两回事。所以,我认为在MVC中。业务逻辑和数据访问应该放在Model层,也就是V负责展示数据,Controler除了转发不做业务逻辑。真正的逻辑事务,数据访问,甚至算法都放到Model去。
再说三层架构。三层其实很好理解,界面,业务,数据访问,就这三个,从字面都可以理解出它们的意思。我要说的是它和MVC的区别。在三层架构中没有定义Controler的概念。这是我认为最不同的地方。而MVC也没有把业务的逻辑访问看成两个层,这是采用三层架构或MVC搭建程序最主要的区别。
当然了。在三层中也提到了

Model,但是三层架构中Model的概念与MVC中Model的概念是不一样的,“三层”中典型的Model层是已实体类构成的,而MVC里,则是由业务逻辑与访问数据组成的。不一样的概念。虽然名字一样。






https://www.360docs.net/doc/3c4990197.html,中图片如何实现上传



目前,在很多的应用中,都有碰到上传照片或者图片的情况,那么就来看一下,在.Net中是如何实现这个功能的。



代码1:
//上传照片,没有保存到数据库,只是暂存在Session中,并在image控件上显示
private void btn_upload_Click(object sender, System.EventArgs e)
{
//每次上传照片之前,先清空图片Session["imageData"],Session["imageSize"]和Session["tempImage"]中的内容
Session["imageData"] = null;
Session["imageSize"] = null;
Session["tempImage"] = null;

HttpPostedFile upFile = this.up_file.PostedFile;
int iFileLength = upFile.ContentLength;
string imageType;
try
{
if( upFile.FileName.Equals("") )
{
imageType = "";
}
else
{
imageType = upFile.FileName.Substring( https://www.360docs.net/doc/3c4990197.html,stIndexOf('.'), upFile.FileName.Length - https://www.360docs.net/doc/3c4990197.html,stIndexOf('.') ).Trim().ToLower();
}
if(iFileLength == 0)
{
Response.Write("");
return;
}
else if( iFileLength > 1048576)
{
Response.Write("");
return;
}
else if(this.tb_gh.Text == "")
{
Response.Write("");
return;
}
else if( imageType != ".jpg" && imageType != ".bmp" && imageType != ".gif")
{
Response.Write("");
return;
}
else
{
this.Image1.ImageUrl = this.up_file.PostedFile.FileName;

if(this.Image1.Width.Value > 100 || this.Image1.Height.Value > 120 )
{
this.Image1.ImageUrl = "";
Response.Write("");
return;
}
else
{
this.lb_msg.Visible = true;
this.lb_msg.Text = "电子照片上传成功!";

byte[] FileByteArray = new byte[iFileLength];
Stream StreamObject = upFile.InputStream;
int ImgSize = upFile.ContentLength;
string ImgType = upFile.ContentType;
string ImgID = this.tb_gh.Text.Trim();

Session["tempImage"] = (Http

PostedFile)upFile;

//重新将图片信息赋值给Session
Session["imageData"] = (byte [])FileByteArray;
Session["imageSize"] = Convert.ToInt32(ImgSize.ToString());
}

}
}
catch(Exception ex)
{
this.lb_msg.Visible = true;
this.lb_msg.Text = ex.Message.ToString();
}
}
本例中,是把图片以二进制byte []的形式存入数据库;取出时,先读取二进制流,然后再写入一个temp.jpg文件中进行显示,代码如下:
//创建一个temp.jpg文件,若已经存在,则改写该文件为空文件
FileStream fs = new FileStream(Server.MapPath("..\\image\\temp.jpg"), FileMode.Create);
fs.Write( (byte [])read["lzb2dzzp"], 0, Convert.ToInt32(read["lzb2imageSize"]) );
this.Image1.ImageUrl = "..\\image\\temp.jpg";

fs.Close();
Session["imageData"] = (byte [])read["lzb2dzzp"];
Session["imageSize"] = Convert.ToInt32( read["lzb2imageSize"] );
也可以选择将图片存入文件目录中,在读取和存储效率方面,可能会更好一些。
存在的问题是:假如第一次查询数据库(或者目录),选择显示A的照片,可以正常显示在image上;第二次,重新进行查询,然后选择显示B的照片,则显示的仍是A的照片,需要刷新一次才可以正常显示B的照片;该问题,自己还未能解决,可能是与缓存有关,但并不清楚具体问题出在哪里。若有谁可以提供一个好的解决方案,希望可以在此留言。

代码2:

try
{
//((Image)gvGradeUser.FindControl(ImageGrade)).ImageUrl.ToString().Trim();
//根据等级的编修改
int enbale = 0;
if (ddlStart.Text.ToString().Trim() == "正常")
{
enbale = 0;
}
else
{
enbale = 1;
}
//图片存在时
if (FtxtFlileName.HasFile)
{
FtxtFlileName.SaveAs(Server.MapPath("../GradeImage/") + FtxtFlileName.FileName.ToString().Trim());
if (objCusGradelevelService.SetOneGradelevelInfo(Convert.ToInt32(lblcode.Text.ToString().Trim()), txtName.Text.ToString().Trim(), Convert.ToInt32(txtJiFenFanWei.Text.ToString().Trim()), enbale, "~/PersonnelManagement/GradeImage/" + FtxtFlileName.FileName.ToString().Trim(), txtText.Text.ToString().Trim()))
{
lblMessage.Visible = true;
lblMessage.Text = "修改成功";

}
else
{
lblMessage.Visible = true;
lblMessage.Text = "修改失败";
}

}
//图片不存在时
else
{
if (objCusGradelevelService.SetOneGradelevelInfoNoimage(Convert.ToInt32(lblcode.Text.ToString().Trim()), txtName.Text.ToString().Trim(),

Convert.ToInt32(txtJiFenFanWei.Text.ToString().Trim()), enbale, txtText.Text.ToString().Trim()))
{
lblMessage.Visible = true;
lblMessage.Text = "修改成功";
}
else
{
lblMessage.Visible = true;
lblMessage.Text = "修改失败";
}
}
dt_GradeUser = objCusGradelevelService.GetAllGradelevelInfo();
dtGradeUser();
btnAdd.Visible = true;
btnClearUpdate.Visible = false;
btnUpdate.Visible = false;
}
catch (Exception)
{
lblMessage.Visible = true;
lblMessage.Text = "修改失败";
}



FCK在线编辑器上传图片加入水印功能

在线编辑器Fckeditor优点很多,如:适应多种开发语言环境,功能强大免费开源,能根据自己要求扩展功能。
大家可以到官方网站下载最新源代码。现在最新官方消息FCKEditor已经改名CKEditor了。最新版本是https://www.360docs.net/doc/3c4990197.html, 3.5.3
本文要实现功能是:利用编辑器在图片上传时,加入水印功能。
如何在自己的网站中架设FCKeditor编辑器?我就不说了,本文默认你已经架设过并且熟悉FCKeditor内部结构。
在下载FCKeditor编辑器的同时,如果是使用.net版本,还必须下载一个源代码包,在里面有一些功能类,和编译出来的DLL文件,存放在BIN文件中,我们所需要做的就是修改源代码,重新编译源代码,生成新的DLL,在自己的网站中替换就可以了。
我使用的是(源代码版本号是https://www.360docs.net/doc/3c4990197.html,_2.5,编辑器文件版本号为FCKeditor_2.6.3)
用VS2008打开代码包根目录下的FredCK.FCKeditorV2.csproj文件,待文件树展开后,找到FileBrowser文件夹下的FileWorkerBase.cs文件,对其进行修改。
我们需要的是修改FileWorkerBase类中的FileUpload方法函数。
在看代码之前,先做好准备工作。
在自己的网站中建立了watermark.config文件,用于存放网站的一些配置信息,如水印的类型(文字型,图片型),是否需要加水印,文字型水印的文字内容等等和本文无关的重要配置信息。
所以在如下代码中,有一段是用来读取这些配置信息的。
在FileUpload方法中找到oFile.SaveAs( sFilePath );语句。在其后加入

try
{
DataSet configds = new DataSet();
configds.ReadXml(Server.MapPath("~/config/watermark.config"));
DataTable configdt = configds.Tables[0];
if (configdt.Rows[0]["Watermarkstatus"].ToString() == "1")
{
Image img = Image.FromFile(sFilePath);
if (configdt.Rows[0]["Watermarktype"].ToString() == "0")
{
Graphics g = Graphics.FromImage(img);
g.DrawImage(img, 0, 0, img.Width, img.Height);
Font f = new Font("

华文行楷", 40);
Brush b = new SolidBrush(Color.White);
string addText = configdt.Rows[0]["Watermarktext"].ToString();
g.DrawString(addText, f, b, img.Width - 174, img.Height - 40);
g.Dispose();
}
if (configdt.Rows[0]["Watermarktype"].ToString() == "1")
{
System.Drawing.Image copyImage = System.Drawing.Image.FromFile(Server.MapPath("~/watermark/watermark.gif"));
Graphics g = Graphics.FromImage(img);
g.DrawImage(copyImage, new Rectangle(img.Width - copyImage.Width, img.Height - copyImage.Height, copyImage.Width, copyImage.Height), 0, 0, copyImage.Width, copyImage.Height, GraphicsUnit.Pixel);
g.Dispose();
}
sFileName = System.IO.Path.GetFileNameWithoutExtension(oFile.FileName);
string newPath = sFileName+"_"+DateTime.Now.ToString("yyMMddhhmmss") + "." + sExtension;
newPath = https://www.360docs.net/doc/3c4990197.html,bine(sServerDir, newPath);
sFileName = newPath;
img.Save(newPath);
img.Dispose();
if (File.Exists(sFilePath))
{
File.Delete(sFilePath);
}
}
}
catch
{
this.SendFileUploadResponse(808, isQuickUpload);
}



请注意,一定要在自己的站点根目录下新建config文件夹,将watermark.config存放其中,
watermark.config中必须出现的几个字段如下:
0
1
ABCD
watermark.gif



相关文档
最新文档