【发布时间】:2015-11-03 06:57:58
【问题描述】:
美好的一天。下面是一个 Powerbuilder 脚本,用于检查文件编码并从文件中获取数据。一旦数据被分配给一个字符串变量(ls_encoding),它将被传递给对象函数of_TabDelimited()(这个函数的脚本也显示在下面),以替换用制表符分隔的管道。
在对象函数of_TabDelimited() 中,应用程序挂起,我无法弄清楚PB 挂起的原因。传递的数据约为 2,800 行。但是如果数据不是更大的行(例如 100 行),则函数 of_TabDelimited() 工作正常。我在of_TabDelimited() 中找不到任何处理限制,因为它只在循环内执行循环和替换功能。
任何人都可以帮助我找到并纠正错误吗?感谢任何帮助。
//Get the data from the file
ll_FileNum = FileOpen(ls_sourcepath, StreamMode!, Read!, LockWrite!, Replace!)
ll_FileLength = FileLength(ls_sourcepath)
eRet = FileEncoding(ls_sourcepath)
IF NOT ISNULL(ll_FileLength) OR ll_FileLength > 0 THEN
IF eRet = EncodingANSI! THEN
ll_bytes = FileReadEx(ll_FileNum, lbl_data)
ls_Encoding = String(lbl_data, EncodingUTF8!)
FileClose(ll_FileNum)
END IF
ELSEIF ISNULL(ll_FileLength) OR ll_FileLength = 0 THEN
lb_Return = FALSE
END IF
Integer li_start, li_end
//Convert the data to TabDelimited
ls_Return = of_TabDelimited(ls_Encoding) //Application hang-up on this function.
IF NOT ISNULL(ls_Return) OR LEN(ls_Return) > 0 THEN
//Parse To Table
END IF
Function : of_TabDelimited
Return Type : String
Argument Type : as_encoding
Long ll_start=1
String ls_old, ls_new
ls_old = "|"
ls_new = "~t"
// Find the first occurrence of old_str.
ll_start = POS(as_encoding, ls_old, ll_start)
// Only enter the loop if you find old_str.
DO WHILE ll_Start > 0
// Replace old_str with new_str.
as_encoding = Replace(as_encoding, ll_start, Len(ls_old), ls_new)
// Find the next occurrence of old_str.
ll_start = POS(as_encoding, ls_old, ll_start + Len(ls_new))
LOOP
RETURN as_encoding
以下是我在应用程序中添加并测试的新功能。看来这个脚本运行良好,可以处理大量行。基本上,这个脚本取自 PFC 的函数 of_GlobalReplace(),取自对象 n_cst_string。甚至 of_TabDelimited() 中的脚本也取自 of_GlobalReplace(),但不同之处在于变量 ls_old 和 ls_new 中 len() 的计算。
String ls_Source, ls_Old, ls_New
Long ll_Start, ll_Oldlen, ll_Newlen
ls_Old = "|"
ls_New = "~t"
//Script taken from n_cst_string - of_GlobalReplace
//Get the string lenghts
ll_OldLen = Len(ls_Old)
ll_NewLen = Len(ls_New)
//Search for the first occurrence of as_Old
ll_Start = Pos(as_source, ls_Old)
Do While ll_Start > 0
// replace as_Old with as_New
as_Source = Replace(as_Source, ll_Start, ll_OldLen, ls_New)
// find the next occurrence of as_Old
ll_Start = Pos(as_source, ls_Old, (ll_Start + ll_NewLen))
Loop
Return as_Source
【问题讨论】:
-
您的文件有多大?有很多列吗?最大行长是多少?
-
Seki,文件大小为 254KB,其中包含 2,800 行,如果在 Excel 中复制数据,则该列直到 V 列。没有固定的最大行长度,但到目前为止,我正在使用 1,500 行/行来计算文件。
-
我认为这可能与使用
long而不是unsigned long来存储在处理大文件时可能变成负值的位置有关,但是1)Pos()确实返回long值和 2) 即使是签名的long也将允许处理 2GB 文件,这似乎不是你的情况。 -
作为旁注,您应该在循环之外计算两个字符串
ls_old和ls_new的len(),因为我很确定 PB 没有推断出它是一个常数值。它应该会提高一点性能。 -
替换功能与 PFC 的 of_GlobalReplace() 中的功能非常匹配,所以我怀疑你是可靠的。有可能这是性能问题吗?为了测试,在循环中我会使用时间戳和 ll_start 的值执行 FileOpen / FileWrite / FileClose。如果它在移动,你会看到它。如果它停止了,您会看到它在文件中的卡住位置。 (顺便说一句,PB 是什么版本?)
标签: powerbuilder powerbuilder-pfc