Что нового

[Данные, строки] Как прочесть строку, сохранив символ перехода на новую строку?

BaRsupillamy

Новичок
Сообщения
58
Репутация
0
Есть у меня файл. Это сертификат открытого ключа. Его надо скопировать, пропустив через чтение файла. Т.е. не просто копировать файл, а открыть, прочитать и записать. Причём построчно читать - это обязательное условие.
Так вот в этом файле символы перевода строки чередуются непонятным образом. То появляется 0х0А(@LF), то 0х0D(@CR). Я читаю файл с помощью FileReadLine(). Как написано в хелпе, она автоматом удаляет конец строки. Потом я дописываю @CR, пишу файл. Файлы старый и новый сравниваю. как текстовые с помощью ALT+C в Тотал Командере, он показывает что они одинаковые. А при побайтном сравнении у меня кое-где отличаются файлы. В исходнике кое-где @LF, а я записал на его месте @CR. Ну и соответственно, если я дописываю в конце строки @LF, то при побайтном сравнении в исходнике остались @CR, ая на их место вписал @LF. И в итоге сертификат не соответствует исходному, хотя и очень похож, кое каких данных в нём не видно.
Помогите придумать, как узнавать, какой символ в конце строки стоял и восстанавливать его.
Пока пытаюсь прочитать файл, открыв его с флагом 16 - Принудительно использовать бинарный режим, но и здесь как то мало что получается.
Спасибо.

Вот почитал, сейчас попробую StringSplit'ом разбить...

Сам для себя тут попишу, чтобы мысли упорядочить. Просто на самом деле работаю с другим файлом, внутри которого есть сертификат, и мне его надо вытащить. Я это сделал посчитав посимвольно, где он начинается и где заканчивается.
Если файл разбить через @CRLF, то получаем 38 строк - вот из этих 38 я точно знаю, где находятся нужные мне данные - со 112 символа 17 строки и до предпоследней строки без последнего символа (файлы разные и количество строк бывает разным).
Если файл разбить через @LF, то получим 21 строку.
Если файл разбить через @CR, то получим 18 строк.
 
Автор
B

BaRsupillamy

Новичок
Сообщения
58
Репутация
0
FileReadLine убирает символ перевода, поэтому не получилось...
а я уж расстроился, думал, что всё так простоЮ, а я затупил... надо, по-моему, всё таки разбивать на массив и дописывать в конец тот символ, которым разбивал...
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
BaRsupillamy [?]
FileReadLine убирает символ перевода, поэтому не получилось
Да, лучше сразу читать весь файл, и использовать StringSplit для разделения строк в массив.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
BaRsupillamy,
Может, как-то так? У меня MD5 обоих файлов совпадает.
Код:
#include <Array.au3>

$sFile = @ScriptDir & '\test.txt'
$sText = ''
$sFileNew = @ScriptDir & '\1_test.txt'

For $i = 1 To 100
	For $j = 1 To 10
		$sText &= Chr(Random(97, 122, 1))
	Next
	$iRandom = Random(1, 3, 1)
	Switch $iRandom
		Case 1
			$sText &= @CR
		Case 2
			$sText &= @LF
		Case 3
			$sText &= @CRLF
	EndSwitch
Next
If Random(0, 1, 1) Then
	ConsoleWrite(111 & @LF)
	$sText = StringRegExpReplace($sText, '[\r\n]{1,}$', '')
EndIf
$hFile = FileOpen($sFile, 2)
FileWrite($hFile, $sText)
FileClose($hFile)
$sText = ''
;-------
$sTemp = FileRead($sFile)
$aTemp = StringRegExp($sTemp, '([\r\n]{1,2})', 3)
$sTemp = StringRegExpReplace($sTemp, '[\r\n]{1,2}', '|')
$sTemp = StringRegExpReplace($sTemp, '\|+$', '')
$aSplit = StringSplit($sTemp, '|')
$iUb = UBound($aTemp)
Dim $aCRLF[$aSplit[0] + 1][3] = [[$aSplit[0]]]
For $i = 1 To $aCRLF[0][0]
	$aCRLF[$i][0] = $aSplit[$i]
	If $i <= $iUb Then
		$aCRLF[$i][1] = $aTemp[$i - 1]
		;это можно убрать:
		;========================
		If $aTemp[$i - 1] == @CR Then
			$aCRLF[$i][2] = '@CR'
		ElseIf $aTemp[$i - 1] == @LF Then
			$aCRLF[$i][2] = '@LF'
		ElseIf $aTemp[$i - 1] == @CRLF Then
			$aCRLF[$i][2] = '@CRLF'
		EndIf
		;========================
	EndIf
Next
_ArrayDisplay($aCRLF)
For $i = 1 To $aCRLF[0][0]
	$sText &= $aCRLF[$i][0] & $aCRLF[$i][1]
Next

$hFile = FileOpen($sFileNew, 2)
FileWrite($hFile, $sText)
FileClose($hFile)
 
Автор
B

BaRsupillamy

Новичок
Сообщения
58
Репутация
0
угу :smile: красиво написано, как я понимаю, работает... хотя кое чего не понимаю в вашем коде...
фокус в том, как понял, символы могут встретиться среди строки...
конечный результат у меня вышел таким
Код:
#include <Array.au3>
#include <File.au3>

$sFile = @ScriptDir & "\1.cer"
$sEndFile = @ScriptDir & "\2.cer"

$hStartFileOpen = FileOpen($sFile, 0)
$hEndFileOpen = FileOpen($sEndFile, 2)

$sLine = FileRead($hStartFileOpen)

$StringCount = 1

$aData0 = StringSplit($sLine, @CRLF)
$aData1 = StringSplit($sLine, @CR)
For $j = 1 To $aData1[0]
;~ 	ConsoleWrite("StringCount = " & $StringCount & @CRLF)
	$aData2 = StringSplit($aData1[$j], @LF)
	For $l = 1 To $aData2[0]
		If $l = $aData2[0] Then
			$End = @CR
		Else
			$End = @LF
		EndIf
		If $StringCount = 17 Then
			$sLine = StringMid($aData2[$l], 112)
			FileWrite($hEndFileOpen, $sLine & $End)
		EndIf
		If $StringCount > 17 And $StringCount < $aData0[0]-1 Then
			FileWrite($hEndFileOpen, $aData2[$l] & $End)
		EndIf
		If $StringCount = $aData0[0]-1 Then
			$sLine = StringLeft($aData2[$l], StringLen($aData2[$l])-1)
			FileWrite($hEndFileOpen, $sLine)
		EndIf
		$StringCount += 1
	Next
Next

;~ _ArrayDisplay($aData)

FileClose($hStartFileOpen)
FileClose($hEndFileOpen)


как умел, так написал :smile: в итоге всё получилось, тотал коммандер к моей радости написал, что файлы одинаковы...а раньше открывал окно сравнения и показывал одинаковый текст... я сразу и не мог понять, почему не работают сертификаты, пока в AkelPad внизу не увидел, что в оригинальном файле стоит Mac, а в моём Win... потом почитал про разные знаки переноса и стал разбираться, как оно так получается...
 
Верх