Unix 文件和 do s 文件的转换(40分)

  • 主题发起人 主题发起人 question
  • 开始时间 开始时间
Q

question

Unregistered / Unconfirmed
GUEST, unregistred user!
我需要一个 能将do
S 下的文本文件和 Unxi 下的文件互相转换的东东。
就像 UltraEdit 的转换功能一样。谢谢
 
Unix下的什么文件?
如果是文本文件,这两种格式的文件都符合ASCII标准,
但由于特殊原因,DOS文本采用#$0D+#$0A作为换行回车,
而Unix文本采用#$0A达到上述目的.
 
unix文本中换行符是一个字节$0a,do
s文本中是$0d$0a两个字节. 好象就这点不同
哦, 对了, 过去的dos文本有个结尾符(EOF). 不过这好象是dos3.0以前时代的事了.
就是用仍用记录块(FCB)读文件时遗留下来的, 现在都是用流来读写, 这样的带结尾
符的dos文本大概已经不存在了.
下面给出一个简单的dos到unix的转换例子, 转换中去除了所有不需要的控制符:
functiondo
sToUnix(File1, File2: string): boolean;
var
Fid1, i: integer;
buffer: string;
begin
Result:=false;
if not FileExits(File1) then
exit;
// source not found
Fid1:=FileOpen(File1, fmOpenRead);
if Fid1<=0 then
exit;
// can't open
i:=FileSeek(Fid1,0,2);
FileSeek(Fid1,0,0);
try
buffer:=SetString(Buffer, nil, i);
FileRead(Fid1, Buffer[1], i);
FileClose(Fid1);
Fid1:=FileCreate(File2);
i:=1;
while i<=length(Buffer)do
begin
if (Buffer<#32) and (Buffer<>#10) then
Delete(Buffer, i, 1)
else
Inc(i);
end;
FileWrite(Fid1, Buffer[1], Length(buffer));
Result:=true;
Finally
FileClose(Fid1);
end;
end;

同理也可写出UnixToDos.
 
更正:
....
try
SetString(Buffer, nil, i);
......
while....
if (ord(Buffer)<32) and....
....
 
加一点补充:
Unix的文件结束符是^D(#$04), 而Dos的文件结束符为^Z(#$1A),
在做文本文件转换时要考虑.
 
大虾,能不能烦您组合一下,生成一个完整的函数,最好是支持 Memo 编辑构件存盘时转换。
 
大家讨论的是在程序中实现吗?
如果不是,请用ftp 的ASC模式来传输
就可以不带格式符了!
注意:perl 的某些语句还是对格式符敏感的!
 
//送你两段代码, 以供参考:
//把Dos文本转换为Unix文本
functiondo
sToUnix(sDosText:string):string;
var
ch : char;
sReturn : string;
i : integer;
begin
sReturn := '';
for i:=1 to length(sDosText)do
begin
ch := sDosText;
case ch of
#$D :;

#$1A:begin
sReturn := sReturn + #$04;
break
end;
else
sReturn := sReturn + ch
end
end;
result := sReturn
end;

//把Unix文本转换Dos为文本
function UnixToDos(sUnixText:string):string;
var
ch : char;
sReturn : string;
i : integer;
begin
sReturn := '';
for i:=1 to length(sUnixText)do
begin
ch := sUnixText;
case ch of
#$A :sReturn := sReturn + #$D#$A;
#$04:begin
sReturn := sReturn + #$1A;
break;
end
else
sReturn := sReturn + ch
end
end;
result := sReturn
end;

//调用示范
//存储Memo
SaveToDisk(DosToUnix(Memo1.Text));
//恢复Memo
Memo1.Text := UnixToDos(LoadFromDisk);
//procedure SaveToDisk(sStr:string);
//把字符串存入磁盘
//function LoadFromDisk;
//从磁盘调出字符串
当然, SaveToDisk, LoadFromDisk都由你来编写.
我这里还有面向流(Stream Object)的Dos-Unix转换源码, 在某些场合用
也是很方便的,不知你用那一些?
 
谢谢 walkdan,你的函数对我帮助很大,能麻烦您将面向流(Stream Object)的Dos-Unix转换源码给我吗?^_^
 
接受答案了.
 

这是UDDF上的源码, 以供参考:
Unix strings (Reading and Writing Unix Files)
From: miano@worldnet.att.net (John M. Miano)
This is a unit that I wrote for reading and writing Unix files.
--------------------------------------------------------------------------------

unit StreamFile;
{
Unix Stream File Interface
Copyright 1996 by John Miano Software
miano@worldnet.att.net
}
interface
Uses
SysUtils ;
Procedure AssignStreamFile (var F : Text ;
Filename : String) ;
implementation
Const
BufferSize = 128 ;
Type
TStreamBuffer = Array [1..High (Integer)] of Char ;
TStreamBufferPointer = ^TStreamBuffer ;
TStreamFileRecord = Record
Case Integer Of
1:
(
Filehandle : Integer ;
Buffer : TStreamBufferPointer ;
BufferOffset : Integer ;
ReadCount : Integer ;
) ;
2:
(
Dummy : Array [1 .. 32] Of Char
)
End ;

Function StreamFileOpen (var F : TTextRec) : Integer ;
Var
Status : Integer ;
begin
With TStreamFileRecord (F.UserData)do
begin
GetMem (Buffer, BufferSize) ;
Case F.Mode Of
fmInput:
FileHandle := FileOpen (StrPas (F.Name), fmShareDenyNone) ;
fmOutput:
FileHandle := FileCreate (StrPas (F.Name)) ;
fmInOut:
begin
FileHandle := FileOpen (StrPas (F.Name), fmShareDenyNone Or
fmOpenWrite or fmOpenRead) ;
If FileHandle <> -1 then
status := FileSeek (FileHandle, 0, 2) ;
{ Move to end of file. }
F.Mode := fmOutput ;
End ;
End ;
BufferOffset := 0 ;
ReadCount := 0 ;
F.BufEnd := 0 ;
{ If this is not here it thinks we are at eof. }
If FileHandle = -1 then
Result := -1
else
Result := 0 ;
End ;
End ;
Function StreamFileInOut (var F : TTextRec) : Integer ;
Procedure Read (var Data : TStreamFileRecord) ;
Procedure CopyData ;
begin
While (F.BufEnd < Sizeof (F.Buffer) - 2)
And (Data.BufferOffset <= Data.ReadCount)
And (Data.Buffer [Data.BufferOffset] <> #10)do
begin
F.Buffer [F.BufEnd] := Data.Buffer^ [Data.BufferOffset] ;
Inc (Data.BufferOffset) ;
Inc (F.BufEnd) ;
End ;
If Data.Buffer [Data.BufferOffset] = #10 then
begin
F.Buffer [F.BufEnd] := #13 ;
Inc (F.BufEnd) ;
F.Buffer [F.BufEnd] := #10 ;
Inc (F.BufEnd) ;
Inc (Data.BufferOffset) ;
End ;
End ;
begin

F.BufEnd := 0 ;
F.BufPos := 0 ;
F.Buffer := '' ;
Repeat
begin
If (Data.ReadCount = 0) Or (Data.BufferOffset > Data.ReadCount) then
begin
Data.BufferOffset := 1 ;
Data.ReadCount := FileRead (Data.FileHandle, Data.Buffer^, BufferSize)
;
End ;
CopyData ;
End Until (Data.ReadCount = 0)
Or (F.BufEnd >= Sizeof (F.Buffer) - 2) ;
Result := 0 ;
End ;
Procedure Write (var Data : TStreamFileRecord) ;
Var
Status : Integer ;
Destination : Integer ;
II : Integer ;
begin
With TStreamFileRecord (F.UserData)do
begin
Destination := 0 ;
For II := 0 To F.BufPos - 1do
begin
If F.Buffer [II] <> #13 then
begin
Inc (Destination) ;
Buffer^[Destination] := F.Buffer [II] ;
End ;
End ;
Status := FileWrite (FileHandle, Buffer^, Destination) ;
F.BufPos := 0 ;
Result := 0 ;
End ;
End ;
begin
Case F.Mode Of
fmInput:
Read (TStreamFileRecord (F.UserData)) ;
fmOutput:
Write (TStreamFileRecord (F.UserData)) ;
End ;
End ;
Function StreamFileFlush (var F : TTextRec) : Integer ;
begin
Result := 0 ;
End ;
Function StreamFileClose (var F : TTextRec) : Integer ;
begin
With TStreamFileRecord (F.UserData)do
begin
FreeMem (Buffer) ;
FileClose (FileHandle) ;
End ;
Result := 0 ;
End ;
Procedure AssignStreamFile (var F : Text ;
Filename : String) ;
begin
With TTextRec (F)do
begin
Mode := fmClosed ;
BufPtr := @Buffer ;
BufSize := Sizeof (Buffer) ;
OpenFunc := @StreamFileOpen ;
InOutFunc := @StreamFileInOut ;
FlushFunc := @StreamFileFlush ;
CloseFunc := @StreamFileClose ;
StrPLCopy (Name, FileName, Sizeof(Name) - 1) ;
End ;
End ;
end.
 
Dos -> Unix
$ cp -m a:aaa.txt /tmp
Unix ->do
s
$do
scp aaa.txt a:
 
后退
顶部