首先过程是这样的,我在JAVA中写了一个servlet,通过servlet将oracle中blob字段中的excel文件取出并且转换为二进制流,通过JAVA的base64类将byte数组转换为字符串,通过xml发送到delphi端,delphi端接收到这个xml文件后,需要对这个字符串进行解析重新转变成base64的byte数组。可是我现在的问题主要是卡在了delphi端,没有一个比较好的实现这种形式的base64算法。我这里有一个,可是不知道能不能使用。看不太懂,我把从xml中得到的字符串放到decode中,可是得不到byte数组。function Decode(const S: AnsiString): AnsiString;
const
Map: array[Char] of Byte = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0);
var
I: LongInt;
begin
case Length(S) of
2:
begin
I := Map[S[1]] + (Map[S[2]] shl 6);
SetLength(Result, 1);
Move(I, Result[1], Length(Result))
end;
3:
begin
I := Map[S[1]] + (Map[S[2]] shl 6) + (Map[S[3]] shl 12);
SetLength(Result, 2);
Move(I, Result[1], Length(Result))
end;
4:
begin
I := Map[S[1]] + (Map[S[2]] shl 6) + (Map[S[3]] shl 12) +
(Map[S[4]] shl 18);
SetLength(Result, 3);
Move(I, Result[1], Length(Result))
end
end
end;
const
Map: array[Char] of Byte = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0);
var
I: LongInt;
begin
case Length(S) of
2:
begin
I := Map[S[1]] + (Map[S[2]] shl 6);
SetLength(Result, 1);
Move(I, Result[1], Length(Result))
end;
3:
begin
I := Map[S[1]] + (Map[S[2]] shl 6) + (Map[S[3]] shl 12);
SetLength(Result, 2);
Move(I, Result[1], Length(Result))
end;
4:
begin
I := Map[S[1]] + (Map[S[2]] shl 6) + (Map[S[3]] shl 12) +
(Map[S[4]] shl 18);
SetLength(Result, 3);
Move(I, Result[1], Length(Result))
end
end
end;
还有就是在java中的base64算法和delphi中的base64算法,是不是一样的。
BASE64:***
这个"base64:"头要去掉。
oracle.sql.BLOB blob = (oracle.sql.BLOB)obj;
String dataText = "";
int i = 0;
try {
InputStream sr = blob.getBinaryStream();
FileOutputStream fos = new FileOutputStream("c:/dddd.txt");
/*
int data = sr.read();
while(data != -1){
binStr += String.valueOf(data);
fos.write(data);
data = sr.read();
}*/
int buf = (int)blob.length();
byte[] blobByte = new byte[buf];
while ((i = sr.read(blobByte))!= -1) {
fos.write(blobByte, 0, i);
}
dataText = Base64.encodeBytes(blobByte); //用base64位算法将byte二进制转换成字符串
fos.close();
sr.close();
} catch(Exception e) {
e.printStackTrace();
}
return dataText;这是我JAVA中写的程序,
在JAVA中,我是把二进制数组转换成base64.然后发送到delphi那么在delphi中,我是这样的。
f := TFileStream.Create('d:/abcd.xls',fmCreate);
node := xmlNodeList.Get(0);
tempValue := node.ChildNodes.FindNode('TEMPLATE_FILE');
str := DecodeString(tempValue.Text);
//showmessage(inttostr(length(str)));
SetLength(ByteArray, Length(str));
for i := 1 to Length(str) do
begin
byteArray[i-1]:=Ord(str[i]);
end;
f.Write(byteArray,length(byteArray));可是无法使用,这可怎么办呀。
我一直也调不通。
const
Map: array[Char] of Byte = (
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0,
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
var
I6,I8: Cardinal;
P,P1: PChar;
I,Count:Integer;
begin
I := Length(Encoded);
SetLength(result,I div 4 * 3);
P1 := PChar(Result);
Count := 0;
P := PChar(Encoded);
while I>0 do
begin
if I<4 then break;
I6 := Map[P^];
Inc(P);
I6 := (I6 shl 6) + Map[P^];
Inc(P);
if P^ = '=' then Dec(Count);
I6 := (I6 shl 6) + Map[P^];
Inc(P);
if P^ = '=' then Dec(Count); I6 := (I6 shl 6) + Map[P^];
Inc(P); P1^ := Chr(I6 shr 16);
Inc(P1);
Inc(Count);
P1^ := Chr((I6 shr 8) and $ff);
Inc(P1);
Inc(Count);
P1^ := Chr(I6 and $ff);
Inc(P1);
Inc(Count);
Dec(I,4);
end;
SetLength(Result, Count);
end;
type
TBytes = array of Byte;
function DecodeBase64(Encoded: String):TBytes;
const
Map: array[Char] of Byte = (
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0,
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
var
I6,I8: Cardinal;
P,P1: PChar;
I,Count:Integer;
begin
I := Length(Encoded);
SetLength(result,I div 4 * 3);
P1 := PChar(Result);
Count := 0;
P := PChar(Encoded);
while I>0 do
begin
if I<4 then break;
I6 := Map[P^];
Inc(P);
I6 := (I6 shl 6) + Map[P^];
Inc(P);
if P^ = '=' then Dec(Count);
I6 := (I6 shl 6) + Map[P^];
Inc(P);
if P^ = '=' then Dec(Count); I6 := (I6 shl 6) + Map[P^];
Inc(P); P1^ := Chr(I6 shr 16);
Inc(P1);
Inc(Count);
P1^ := Chr((I6 shr 8) and $ff);
Inc(P1);
Inc(Count);
P1^ := Chr(I6 and $ff);
Inc(P1);
Inc(Count);
Dec(I,4);
end;
SetLength(Result, Count);
end;
TBytes = array of Byte;
function DecodeBase64(Encoded: String):TBytes;
const
Map: array[Char] of Byte = (
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0,
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
var
I6,I8: Cardinal;
P,P1: PChar;
I,Count:Integer;
begin
I := Length(Encoded);
SetLength(result,I div 4 * 3);
P1 := PChar(Result);
Count := 0;
P := PChar(Encoded);
while I>0 do
begin
if I<4 then break;
while(P^ in [#$20,#13,#10]) do begin Inc(P);dec(I); end;
if I<4 then break;
I6 := Map[P^];
Inc(P);
while(P^ in [#$20,#13,#10]) do begin Inc(P);dec(I); end;
if I<3 then break;
I6 := (I6 shl 6) + Map[P^];
Inc(P);
while(P^ in [#$20,#13,#10]) do begin Inc(P);dec(I); end;
if I<2 then break;
if P^ = '=' then Dec(Count);
I6 := (I6 shl 6) + Map[P^];
Inc(P);
while(P^ in [#$20,#13,#10]) do begin Inc(P);dec(I); end;
if I<1 then break;
if P^ = '=' then Dec(Count); I6 := (I6 shl 6) + Map[P^];
Inc(P); P1^ := Chr(I6 shr 16);
Inc(P1);
Inc(Count);
P1^ := Chr((I6 shr 8) and $ff);
Inc(P1);
Inc(Count);
P1^ := Chr(I6 and $ff);
Inc(P1);
Inc(Count);
Dec(I,4);
end;
SetLength(Result, Count);
end;function WriteToFile(FileName: String;Data:PChar;Length:DWORD): DWORD;
var
FFileHandle:THandle;
BytesToWrite,WroteSize:DWORD;
Buffer:PChar;
begin
Result:=0; FFileHandle:=CreateFile(PChar(LocalExpandFileName(FileName)),
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ,
nil,
OPEN_ALWAYS,//CREATE_NEW
FILE_ATTRIBUTE_NORMAL,
0);
if FFileHandle=INVALID_HANDLE_VALUE then
begin
Result:=GetLastError;
Exit;
end;
try
if GetLastError=ERROR_ALREADY_EXISTS then
begin
if SetFilePointer(FFileHandle,0,nil,FILE_END)=INVALID_SET_FILE_POINTER then
begin
Result:=GetLastError;
end
else
SetLastError(0);
end;
Buffer := Data;
BytesToWrite := Length;
while BytesToWrite>0 do
begin
WroteSize:=0;
if Not WriteFile(FFileHandle,Buffer^,BytesToWrite,WroteSize,nil) then
begin
Result:=GetLastError;
Exit;
end;
Buffer:=Pointer(DWORD(Buffer)+WroteSize);
Dec(BytesToWrite,WroteSize);
end;
finally
CloseHandle(FFileHandle);
end;end;var
Bytes :TBytes;
Src: String;
begin
Bytes := DecodeBase64(Src);
WriteToFile('c:\aaa.xls',PChar(Bytes),Length(Bytes));
SetLength(Bytes,0);
Bytes := Nil;
end;