【问题标题】:File truncated, when opened in Perl文件被截断,在 Perl 中打开时
【发布时间】:2012-04-16 01:26:56
【问题描述】:

我是 perl 的新手,很抱歉,如果这很明显,但我查找了如何打开文件并使用标志,但对于我的生活,它们似乎无法正常工作,我将其缩小到这些行代码。

    if ($flag eq "T"){
        open xFile, ">" , "$lUsername\\$openFile";
    }
    else
    {
        open xFile, ">>", "$lUsername\\$openFile";
    }

这两种方法似乎都删除了我的文件内容。我还检查了标志的格式是否正确,我知道事实上我在这两种情况下都失败了。

编辑:我的代码http://codepaste.net/n52sma的大部分代码粘贴代码

【问题讨论】:

  • 第一个应该是删除文件。你确定第二个也在删除文件吗?你想打开阅读还是写作?
  • 第一个不删除文件。它打开它并截断它,以便您从位置 0 开始写入。

标签: perl file append truncate


【解决方案1】:

Perl 新手?我希望你使用use strictuse warnings

正如其他人所说,您应该使用测试来确保您的文件已打开。但是,这并不是真正的问题。事实上,我使用了你的代码,它对我来说似乎工作得很好。也许您应该尝试打印一些调试消息,看看它是否正在做您认为它正在做的事情:

use strict;
use warnings;
use autodie;   #Will stop your program if the "open" doesn't work.

my $lUsername = "ABaker";
my $openFile  = "somefile.txt";
if ($flag eq "T") {
    print qq(DEBUG: Flag = "$flag": Deleting file "$lUsername/$openFile");
    open xFile, ">" , "$lUsername/$openFile";
}
else {
    print qq(DEBUG: Flag = "$flag": Appending file "$lUsername/$openFile");
    open xFile, ">>", "$lUsername/$openFile";
}

您想使用strictwarnings 以确保您没有遇到变量名问题。 use strict 强制您首先声明变量。例如,您是否设置$Flag,但随后使用$flag?也许$flag 是第一次设置的,但您第二次设置的是$Flag

无论如何,DEBUG: 语句会让您更好地了解您的错误可能是什么。

顺便说一句,在 Perl 中,您正在检查 $flag 是否设置为 T 而不是 t。如果您想同时针对tT 进行测试,请测试是否是uc $flag eq 'T' 而不仅仅是$flag eq 'T'


@Ukemi

我重新格式化以遵守使用严格,我还制作了打印语句以确保我在我想要的时候被截断,而不是在我不想要的时候。它仍在删除文件。虽然现在有时它根本不写,我会在链接中给出我的代码的大部分,如果你给它一次,我真的很感激。

您是否看到它说 截断,但文件是空的?您确定该文件已经存在吗?我将标志和所有内容放在调试语句中是有原因的。你打印的越多,你知道的就越多。试试下面这段代码:

$file = "lUsername/$openFile"  #Use forward slashes vs. back slashes.
if ($flag eq "T") {
    print qq(Flag = "$flag". Truncating file "$file"\n);
    open $File , '>', $file
        or die qq(Unable to open file "$file" for writing: $!\n);
}
else {
    print qq(Flag = "$flag". Appending to file "$file"\n);
    if (not -e $file) {
        print qq(File "$file" does not exist. Will create it\n");
    }
    open $File , '>>', $file
        or die qq(Unable to open file "$file" for appending: $!\n);
}
  • 请注意,我将标记和文件名打印在引号中。这将允许我查看我的文件名中是否有任何隐藏字符。
  • 我使用qq(...) 方法来引用字符串,所以我可以在打印语句中使用引号。
  • 还请注意,我在截断时检查文件是否存在。这样,我确保文件确实存在。

这应该指出您的逻辑中任何可能的错误。您可以做的另一件事是在完成文件写入后停止程序并验证文件是否按预期写入。

print "Write to file now:\n";
my $writeToFile = <>;
printf $File "$writeToFile";
close $File;
print "DEBUG: Temporary stop. Examine file\n";
<STDIN>;     #DEBUG:

现在,如果你看到它说它正在附加到文件中,并且文件存在,但你仍然看到文件被覆盖,我们就会知道问题出在你的实际 open xFile, "&gt;&gt;" $file 语句中。

【讨论】:

  • 我重新格式化以遵守使用严格,我还制作了打印声明以确保我在我想要的时候被截断,而不是在我不想要的时候。它仍在删除文件。虽然现在有时它根本不写,我会在一个链接中给出我的代码的大部分,如果你给它一次,我真的很感激。 codepaste.net/n52sma
  • 我也知道错误的条件不是问题,因为附加是 else 语句,所以任何不是 T 的都应该附加,即使技术上它不是“A”
  • 哇,我花了这么长时间才重新发布...我只是太忙了。因此,您的帖子至少帮助我了解了有关我的程序的更多信息。实际上,当我阅读时。我不知道如何使用创建所述文件的方法来读取文件,如果尚未制作,但如果已经制作,请阅读。发生的事情是当我读取文件时,要输出其内容,它会删除其内容。
  • 我最终使用了 Fcntl 和带有 O_Creat 和 O_EXCL 标志的 sysopen 来制作文件(如果它不存在),然后在没有标志的情况下正常打开它,这可以解决我的问题。如果您有更优雅的方式,请告诉我。我将此标记为答案,再次感谢您。
【解决方案2】:

您应该使用open 的三参数版本、词法文件句柄并检查是否可能出现错误:

# Writing to file (clobbering it if it exists)
open my $file , '>', $filename 
    or die "Unable to write to file '$filename': $!";

# Appending to file
open my $file , '>>', $filename 
    or die "Unable to append to file '$filename': $!";

【讨论】:

    【解决方案3】:

    &gt;&gt; 不会破坏或截断。要么您在预期出现在“else”子句中时出现在“then”子句中,要么问题出在其他地方。

    检查$flag 包含的内容:

    use Data::Dumper;
    local $Data::Dumper::Useqq = 1;
    print(Dumper($flag));
    

    【讨论】:

      【解决方案4】:

      我在下面提到了一些基本的文件处理技术,供您参考。

      open FILE, "filename.txt" or die $!;
      

      上面的命令会将 FILE 文件句柄与文件 filename.txt 相关联。您可以使用文件句柄从文件中读取。如果文件不存在——或者你因为任何其他原因无法读取它——那么脚本将终止,并在 $!变量。

      open FILEHANDLE, MODE, EXPR
      

      可用的模式如下:

      read    < #this mode will read the file     
      write   > # this mode will create the new file. If the file already exists it will truncate and overwrite.
      append  >> #this will append the contents if the file already exists,else it will create new one.
      

      如果您对此感到困惑,可以使用名为 File::Slurp 的模块; 我已经提到了使用 File::Slurp 模块的示例代码。

      use strict;
      use File::Slurp;
      
      my $read_mode=read_file("test.txt"); #to read file contents
      write_file("test2.txt",$read_mode); #to write file
      my @all_files=read_dir("/home/desktop",keep_dot_dot=>0); #read a dir
      write_file("test2.txt",{append=>1},"@all_files"); #Append mode
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-25
        • 2023-03-07
        • 2016-01-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多