服務器端文件處理

若是隻指定文件名而沒有指定文件路徑,則默認會使用系統屬性參數DIR_HOME

image299

跨平臺的文件路徑

若是想要指定跨平臺的文件名,則使用FILE_GET_NAME函數,該函數會將邏輯文件名與邏輯文件路徑轉換成服務器所運行的平臺下的物理文件名與路徑,但邏輯文件名與路徑須要使用FILE事務碼先來定義。

 

FILE_GET_NAME:能將SAP中經過FILE事務碼定義的與操做系統無關(platform-independent)邏輯文件名轉換成與平臺相關的物理文件名。邏輯文件名經過下面的FILE事務碼來配置。

 

列出服務器上的目錄:al11

配置邏輯文件

第一步.創建操做系統的分類:以下面SAP系統已經創建了經常使用的操做系統分類,如DOSUNIXMACWIN幾類操做系統。

image300

第二步.建立操做系統名。此過程須要費用第一步所建立的操做系統分類

image301

第三步.建立邏輯文件路徑。在建立的過程當中,引用了第一步建立的操做系統分類(Syntax group),而不是第二步建立的操做系統,這裏有怪,並且到目前止第二步建立出來的操做系名用在什麼地方。

這一步定義邏輯文件路徑會間接(在運行時)使用到了第四步中定義的邏輯文件名(經過<FILENAME>參數在運行時動態的將第四步邏輯文件名轉換爲實際的物理文件名,<FILENAME>就是在運行時第四步轉換過來的物理文件名

image302

在建立邏輯文件路徑時,須要填寫物理路徑 Physical path,這個物理路徑並非咱們平時講的單純文件路徑,其實它除了前半部分單純的文件路徑外(這裏爲<P=DIR_GLOBAL>),仍是後半部分的文件名(這裏爲<FILENAME>),因此邏輯文件路徑並不僅是定義了單純的文件路徑信息,而是某個文件的完整路徑信息(路徑+文件名)。

在這裏Physical path字段可使用一些預約義的佔位符(如這裏的<P=DIR_GLOBAL><FILENAME>),能夠按F1查看所容許的預約符:

Reserved Word    Replacement Text

<OPSYS>

Operating system in call

<INSTANCE>

R/3 application instance

<SYSID>

R/3 application name in SY-SYSID

<DBSYS>

Database system in SY-DBSYS

<SAPRL>

R/3 release in SY-SAPRL

<HOST>

Host name in SY-HOST

<CLIENT>

Client in SY-MANDT

<LANGUAGE>

Log on language in SY-LANGU

<DATE>

Date in SY-DATUM

<YEAR>

Year in SY-DATUM, 4-character

<SYEAR>

Year in SY-DATUM, 2-character

<MONTH>

Month in SY-DATUM

<DAY>

Day in SY-DATUM

<WEEKDAY>

Day of the week in SY-FDAYW

<TIME>

Time in SY-UZEIT

<STIME>

Hour and minute in SY-UZEIT

<HOUR>

Hour in SY-UZEIT

<MINUTE>

Minute in SY-UZEIT

<SECOND>

Seconds in SY-UZEIT

<PARAM_1>

External parameter 1這個以及下面兩個會使用FILE_GET_NAME函數的PARAMETER_1/2/3參數值來替換

<PARAM_2>

External parameter 2

<PARAM_3>

External parameter 3

   

<P=name>

Name of a profile parameter這個使用的是RZ11事務碼定義的全局參數名

 

(see Report RSPARAM for valid values)

   

<V=name>

Name of a variable這個使用的是就是FILE事務碼中image303選項裏所定義的變量

 

(stored in variable table)

   

<F=name>

Return value of a function module這個會使用「FILENAME_EXIT_+ name 所組成的函數的返回

 

Naming convention for this function module:值來替換這個佔位符。以「FILENAME_EXIT_」打頭的函數爲

 

FILENAME_EXIT_name系統提供的,因此若是要使用自定義函數,則要使用如下兩個佔位

   

<Y=name>

Return value of a function module如下兩個佔位符的用意是爲了上述所預約義的佔位不滿咱們要求

 

Naming convention for this function module:時,咱們能夠自定義這些佔位符,而且這些佔位符的取值來自於我

 

Y_FILENAME_EXIT_name們自定義的函數,這樣能夠知足根據自定義業務邏輯來生成文件名

   

<Z=name>

Return value of a function module

 

Naming convention for this function module:EXIT單詞在SAP裏表示出口的意義,出口在不少地方都是這樣表

 

Z_FILENAME_EXIT_name示的

第四步.建立邏輯文件名。該步建立的邏輯文件名與上一將建立出來的邏輯文件路徑關聯起來

image304

FILE_GET_NAME

使用上面第四步建立的邏輯文件名,服務器所在的操做環境爲UNIX

 

DATA: encoding TYPE filename-fileformat.
DATA: physical_filename TYPE string.
CALL FUNCTION 'FILE_GET_NAME'
 
EXPORTING
*   CLIENT                        = SY-MANDT
    logical_filename             
= 'ARCHIVE_BI_PROTOCOL_DATA_FILE'
*   OPERATING_SYSTEM              = SY-OPSYS
   parameter_1                  
= 'PARAMETER_1'
   parameter_2                  
= 'PARAMETER_2'
   parameter_3                  
= 'PARAMETER_3'
*   USE_PRESENTATION_SERVER       = ' '
*   WITH_FILE_EXTENSION           = ' '
*   USE_BUFFER                    = ' '
*   ELEMINATE_BLANKS              = 'X'
*   INCLUDING_DIR                 = ' '
 
IMPORTING
*   EMERGENCY_FLAG                =
   file_format                  
= encoding
   file_name                    
= physical_filename
* EXCEPTIONS

*   FILE_NOT_FOUND                = 1
*   OTHERS                        = 2
         
.
WRITE: / physical_filename, '  ', encoding.

/usr/sap/D06/SYS/global/PARAMETER_1_PARAMETER_3_20111116_145730_PARAMETER_2.ARCHIV

打開文件OPEN DATASET

OPEN DATASET dset FOR access IN mode [position]
                                     [os_addition]
                                     [error_handling].

Dest目標文件

 

sy-subrc

Description

0

File was opened.

8

Operating system could not open file.

 

每一個Session最多能夠打開100個文件,但具體要看OS

打開方式access

INPUT

以讀取方式打開文件,默認狀況下打開時文件指針指向文件開始的地方,若是文件不存在,則sy-subrc8。若是文件已經打開,文件指針復位到文件的起始位置。

OUTPUT

以寫的方式打開文件(但也容許讀),若是指定的文件已經存在,則內容會被刪除。若是指定的文件不存在,則會建立一個新的文件。

APPENDING

以追加寫的方式打開文件。若是文件已經存在,則文件指針會指向文件內容最後,若是文件不存在,則會建立。若是試着經過READ DATASET讀取使用FOR APPENDING 方式打開的文件,則sy-subrc4

UPDATE

以更新的方式打開文件,默認狀況下打開時文件指針指向文件開始的地方。若是文件不存在,則sy-subrc8

文件指針位置position

... AT POSITION pos ...

位置是按照字節來算的,文件的開始位置爲0,若是置爲-1,則會定位到文件末尾。

 

請注意如下特殊狀況:

一、  在讀取文件時,若是 pos 的值大於了文件的長度,將讀取不到數據。

二、  在寫文件時,若是文件指針指向了文件開始的後面的某個位置上,則從文件開始的地方到指定的 pos 止,都會使用0來填充。

三、  若是是在APPEND模式打開文件,則會忽略到 pos ,仍然從文件的最末開始附加。

四、  若是是修改文件,而且 pos 的值大於了文件的長度,則從文件末到 pos 位置都會設置成0,更新的的內容會從pos向後寫。

 

注,該選項不能與FILTER選項同時使用。

 

因爲文件能夠大於2GB,因此 pos 要使用 P 類型來定義,而不能再使用 I 類型。

文件指定位置可使用SET DATASET來修改。

在對文本文件進行指針定位時,要考慮到文件頭部是否帶有BOM,以及end-of-line marking

打開模式mode

... {BINARY MODE}
  | {TEXT MODE encoding [linefeed] }...

二進制模式BINARY MODE

If you read from or write to a file that is open in binary mode, the data is transferred byte by byte.When writing to a binary file, the binary content of a data object is transferred in unchanged form(使用未轉換形式) into the file. When reading from a binary file, the binary content of the file is transferred in unchanged form into a data object.

字符模式TEXT MODE encoding [linefeed]

If the data type is character-type and flat(若是C類型), trailing blanks are cut off. In the data type string, trailing blanks are not cut off.

If you read from or write to a file that is open in text mode, the data is transferred line by line

 

若是沒有指定行結束尾符linefeed,則默認使用當前服務器所在平臺的行結尾符。

讀取文件時,是以行爲單位一行一行的讀取。

行結尾符能夠經過linefeed專門指定。

Unicode 系統中,只有character-type的數據對象才能用來傳輸Text文件。

Unicode 系統中,必須指定encoding

字符編碼encoding

... ENCODING { DEFAULT
             | {UTF-8 [SKIPPING|WITH BYTE-ORDER MARK]} } ...

l  DEFAULT

Unicode 系統中,默認使用UTF-8編碼

l  UTF-8

可使用CL_ABAP_FILE_UTILITIESCHECK_UTF8方法來文件是不是UTF-8編碼的文件

 

另外,CL_ABAP_FILE_UTILITIESCHECK_FOR_BOM方法能夠用來檢測文件頭部是否帶有字節序,而CREATE_UTF8_FILE_WITH_BOM方法能夠建立一個帶有UTF-8字節序的文件。

 

注:在SAP中,A UTF-16 file can only be opened as a binary file.

 

byte order mark (BOM):字節序,UTF-8BOMEF BB BF

 

l  ... SKIPPING BYTE-ORDER MARK

只容許FOR INPUT or FOR UPDATE時使用,若是有BOM,則在讀取或更新時會忽略掉BOM,即在讀取時文件指針會設置在BOM的後面。若是省略掉該選項,則BOM會看成普通文件內容來處理。

l  ... WITH BYTE-ORDER MARK

該選項只容許在FOR OUTPUT狀況下使用,而且會向文件頭部插入BOM,若是沒有加上該選項,則不會插入。

 

注:BYTE-ORDER MARK 選項不能與AT POSITION pos同時使用。

 

當使用UTF-8讀取一個文件時,推薦使用SKIPPING BYTE-ORDER MARK選項,以防BOM被看成普通文件內容讀取出來;另外,爲了使全部閱讀器均可以讀取SAP建立的UTF-8格式文件,推薦使用WITH BYTE-ORDER MARK選項。

換行符linefeed

... WITH { NATIVE
         | UNIX
         | WINDOWS } LINEFEED ...

 

line end marker:行結束標記

CRLFCarriage-Return Line-Feed ,就是回車(CR, ASCII 13, \r) 換行(LF, ASCII 10, \n)。這兩個ACSII字符不會在屏幕有任何輸出,但在Windows中普遍使用來標識一行的結束。而在Linux/UNIX系統中只有換行符。許多網絡協議,包括HTTP也使用CRLF來表示每一行的結束。CRLF是在計算機終端仍是電傳打印機的時候遺留下來的東西。電傳打字機就像普通打字機同樣工做。在每一行的末端,CR命令讓打印頭回到左邊。LF命令讓紙前進一行。雖然使用捲紙的終端時代已通過去了,可是,CRLF命令依然存在,許多應用程序和網絡協議仍使用這些命令做爲分隔符。

 

若是當指定了linefeed選項後,則全局參數abap/NTfmodeRZ11)會忽略,同時TYPE attr選項不能使用。

若是沒有指定該選項,則line end marker依賴於平臺:

一、The line end marker for Unix is "LF".

二、  The line end marker for MS Windows is "CRLF".然而,若是是在MS Windows操做系統下,則全局屬性參數abap/NTfmode能夠決定使用"LF"仍是"CRLF",若是該參數的值爲"b",則使用"LF";若是爲"t"或者初始值,則使用"CRLF"。另外abap/NTfmode能夠覆蓋TYPE attr選項。若是在沒有使用linefeed選項,又沒有使用TYPE attr選項時,打開一個文件時會搜索第一行的line end marker ("LF" or "CRLF"),並用做整個文件中,若是沒有找到,則會使用abap/NTfmode設置的值。

 

若是使用了WITH NATIVE|SMART|UNIX|WINDOWS LINEFEED選項,這些設置還可使用SET DATASET語句來修改這些設置,若是沒有使用,則line end marker不能使用SET DATASET語句來修改line end marker

 

能夠經過GET DATASET語句獲取當前正在使用的line end marker

 

l  WITH NATIVE LINEFEED

根據當前服務器所在的操做系統來決定。i.e. "LF" for Unix OS390 or OS400, and "CRLF" for MS Windows.

l  WITH UNIX LINEFEED

固定使用The line end marker is set to "LF",即文件的每行(一個TRANSFER ...TO ...語句就表示向文件寫一行)都會以0A」結尾

l  WITH WINDOWS LINEFEED

固定使用The line end marker is set to "CRLF",即文件的每行(一個TRANSFER ...TO ...語句就表示向文件寫一行)都會以「0D0A」結尾。

操做系統選項os_addition

... [TYPE attr]
    [FILTER opcom] ... .

TYPE

沒有實質上的用處

FILTER

將輸入輸出流過濾。opcom爲服務器相應的所在操做系統的命令串。

 

一般狀況下,咱們是從標準的STDOUTSTDIN管道讀取或寫入數據,若是我要對數據進行壓縮之類的動做,則能夠加上過濾器。

 

注:不能與AT POSITION FOR UPDATE選項同時使用。

 

下面在Unix系統中,對數據輸入時進行壓縮,在輸出時進行解壓操做:

DATA file TYPE string VALUE `/usr/test.Z`.
OPEN DATASET file FOR OUTPUT IN BINARY MODE
                      FILTER
'compress'.
...
CLOSE DATASET file.

OPEN DATASET file FOR INPUT IN BINARY MODE
                      FILTER
'uncompress'.
...
CLOSE DATASET file.

出錯處理error_handling

... [MESSAGE msg]
    [IGNORING CONVERSION ERRORS]
    [REPLACEMENT CHARACTER rc] ... .

該選項容許你接收操做系統的消息,壓制異常信息,以及定義出錯時未知字符的替換字符。不能轉換的字符會默認會使用「#」替換,除非使用REPLACEMENT CHARACTER指定。

 

DATA mess TYPE string.
OPEN DATASET `` FOR INPUT IN BINARY MODE MESSAGE mess.
IF sy-subrc = 8.
 
WRITE: / mess.
ENDIF.

No such file or directory

寫文件TRANSFER

TRANSFER dobj TO dset [LENGTH len]
                      [NO END OF LINE].

 

DATA: file TYPE string VALUE `flights.dat`,
      wa  
TYPE spfli.
FIELD-SYMBOLS <fs_hex> TYPE x
.
OPEN DATASET file FOR OUTPUT IN BINARY MODE.
SELECT *
      
FROM
spfli
      
INTO wa.

 
ASSIGN wa TO <fs_hex> CASTING.
 
"寫進去的是二進制,打開文件看到的會是亂碼

 
TRANSFER <fs_hex> TO file.
ENDSELECT
.
CLOSE DATASET file.

LENGTH選項:

決定了多少個字符或多少個字節將被寫入到文件中。若是len的值大於了dobj數據對象所存儲的字符或字節數時,則使用十六進制0或者空格來替換缺失的字節或字符(至因而字節仍是字符則依賴於文件打開模式)

 

NO END OF LINE選項:

用來控制是否在以文本模式寫入文件時,在每次傳輸完後是否加上換行符。

若是是使用文本模式打開並寫入文件時,默認就會在每次傳輸完成後加上換行符。

讀取READ DATASET

READ DATASET dset INTO dobj [MAXIMUMLENGTH mlen][[ACTUAL] LENGTH alen]

 

若是沒有指定MAXIMUM LENGTH或者指定的爲負數,則每次讀取多少數據依賴於OPEN DATASET語句所採用的打開模式:若是是以文本模式打開,則每次讀取一行數據,若是是以BIN模式打開,則儘量多的數據並能填滿dobj,若是指定了MAXIMUM LENGTH則每次讀取mlen個字符(或字節)。

 

 

sy-subrc

Meaning

0

Data was read without reaching end of file.讀到了數據而且沒有達到文件尾

4

Data was read and the end of the file was reached or there was an attempt to read after the end of the file.讀到了數據且到達了文件尾,或者達到文件尾後再試着讀取

 

DATA: file TYPE string VALUE `flights.dat`,
      wa  
TYPE spfli.
FIELD-SYMBOLS <hex_container> TYPE x
.
OPEN DATASET file FOR INPUT IN BINARY MODE.
ASSIGN wa TO <hex_container> CASTING.
DO.
 
"因爲沒有使用MAXIMUM LENGTH選項,因此每次讀取的最大字節數
 
"<hex_container>所佔字節數決定

 
READ DATASET file INTO <hex_container>.
 
IF sy-subrc = 0.
   
WRITE: / wa-carrid,
             wa
-connid,
             wa
-countryfr,
             wa
-cityfrom,
             wa
-cityto,
             wa
-fltime,
             wa
-distance.
 
ELSE.
   
EXIT.
 
ENDIF.
ENDDO
.
CLOSE DATASET file.

 

修改上面程序,每次讀取時指定所讀取的最大字節數:

DATA: file TYPE string VALUE `flights.dat`,
     
"緩衝器,用來每次讀取的碼流
      hex_container
TYPE x LENGTH 1000,
      len
TYPE i.
FIELD-SYMBOLS <spfli> TYPE spfli.
"獲取<spfli>所佔內存的字節數,即爲spfli結構類型所佔內存大小
DESCRIBE FIELD <spfli> LENGTH len IN BYTE MODE.
OPEN DATASET file FOR INPUT IN BINARY MODE.
"spfli類型的視圖來看待(操做)緩衝器
ASSIGN hex_container TO <spfli> CASTING.
DO.
 
"每次讀取指定的長度:len
 
READ DATASET file INTO hex_container MAXIMUM LENGTH len.
 
IF sy-subrc = 0.
   
"將讀取的二進數據以spfli結構類型的視圖展現
   
WRITE: / <spfli>-carrid,
             <spfli>
-connid,
             <spfli>
-countryfr,
             <spfli>
-cityfrom,
             <spfli>
-cityto,
             <spfli>
-fltime,
             <spfli>
-distance.
 
ELSE.
   
EXIT.
 
ENDIF.
ENDDO.
CLOSE DATASET file.

 

關閉文件 CLOSE DATASET

CLOSE DATASET dset.

刪除文件 DELETE DATASET

DELETE DATASET dset.

獲取打開文件屬性GET DATASET

相關文章
相關標籤/搜索