如何使用Lazarus将TFilestream保存到硬盘驱动器

时间:2016-09-28 02:20:17

标签: xml save filestream xmldocument lazarus

我在更改某些值后遇到保存xml文件的问题。 我使用Lazarus 1.6作为IDE与FPC版本3.0.0 这是我用于这篇文章的xml文件的结构:

<?xml version="1.0" encoding="UTF-8"?>
 <wbpickeys>
  <picture>
    <name>C:\IMG_1.JPG</name>
    <imagedate>p-06/04/2014 16:22:10</imagedate>
    <favorit>n</favorit>
    <remark>aaa</remark>
    <drive>DRIVE_FIXED</drive>
  </picture>
</wbpickeys>

我使用以下用法条款(可能不是所有这些都是必要的,但我认为至少重要的一次是可用的):

uses
Windows, ShellAPI, FileUtil, Graphics, Menus, ComCtrls, ExtCtrls, ExtDlgs, Classes, SysUtils, LResources, Forms, Controls, StdCtrls, Dialogs, CheckLst, Buttons, inifiles,
laz2_DOM, laz2_XMLRead, laz2_XMLWrite, laz2_XMLCfg, laz2_XMLUtils, laz_XMLStreaming;

在程序启动时,我将此xml文件加载到Tfilestream(g_stream:TfileStream)中。原因是在程序运行期间具有独占访问权限。 为此,我使用以下open函数:

function open_xml:Boolean;
begin
    if g_stream <> nil then FreeAndNil(g_stream);
    try
            //with load from (TFile)-Stream the xml file can be opened with Share Exclusive
            //when loading only from file there is no possibility to open it exclusive
            g_stream:= TFileStream.Create('wbpickeys.xml',fmShareExclusive);
            //Read the XML file into an XML Document
        readxmlfile(g_wbpickeys,g_stream);
            result:= true;
    except
        on E:EFOpenError do
        begin
             beep();
                MessageDlg
        (
          //br is defined as a constance for line feed
        '*** A T T E N T I O N ***' + br + br +
          'When trying to open the file for the keywords' + br +  '"wbpickeys.xml"' + br +
          'the following error occurs:' + br +
          E.Message + br +
          'Please check if the file is available' + br +
          'or deleted or moved or what else',mtError,[mbOK],0
        );
        result:= false;
        end;
    end;
end;

比我更改一个子节点的文本值:

procedure TForm1.BChangeNodeClick(Sender: TObject);
var
  pictures          : TDOMNodeList;
  pic, tempnode     : TDOMNode;
  i                 : integer;
begin
  // Get all nodes with name "picture"
  pictures:= g_wbpickeys.GetElementsByTagName('picture');
  // For all Member nodes
  for i:= 0 to pictures.Count - 1 do
  begin
    pic:= pictures[i];
    tempnode:= pic.FindNode('remark');
    // if content is 'bbb' change it
    if(tempnode.TextContent = 'bbb') then
    begin
      tempnode.TextContent:= 'aaa';
      //than I try to save the xmldocument to the hard drive    
      writeXMLFile(g_wbpickeys,'wbpickeys.xml');
    end;
end;

这是我的问题: 新文本已设置,我可以在备忘录中看到结果。但是,该值仅在运行时加载xml的内存中更改,但在物理上不更改为硬盘驱动器上的文件。 我几乎看到了整个网络,但我找不到将流保存到硬盘驱动器上相应文件的解决方案。

如果我用这个 “writeXMLFile(g_wbpickeys,'wbpickeys.xml');” 我在文件lazutf8classes.pas第143行中收到了一个EFCreateError“无法创建文件wbpickeys.xml”。

问题是我不想创建一个xml文件 - 我想更改一个现有文件。

我找到了将流保存到磁盘上文件的可能性。不幸的是,我没有找到任何东西。

我确实犯了一个错误,但我看不到它。有人可以告诉我吗?

1 个答案:

答案 0 :(得分:1)

将修改后的文档写回磁盘时,必须替换整个文件,不能将操作限制为仅修改的节点。因此,您必须首先删除旧的xml文件(或更好:重命名它,以防在写入过程中出现问题),然后使用WriteXMLFile编写文档。或者写一个新的临时文件名,以保持原始文件一直锁定;然后销毁读取流(结束独占访问),删除原始文件并将新文件重命名为旧文件。