로컬의 json 텍스트를 읽어서 파싱할때 가상 에뮬에선 잘 돌아가는데 디바이스에선 에러가 납니다.

1,054 views
Skip to first unread message

DarkAngel

unread,
Oct 10, 2011, 5:25:44 AM10/10/11
to 앱스프레소
안녕하세요~

index.htm 파일이 있는 로컬 폴더에서 json 텍스트 파일을 읽어서 json 파싱하게 했는데, 디버깅으로 돌려보면

안드로이드 가상 에뮬레이터에서는 에러 없지 잘되는데, 갤럭시탭 디바이스를 연결해서 돌려보면 아래와 같은 에러가 나더군요.

["uncaught exception from function successCB: SyntaxError: Unexpected
token ILLEGAL "]

jquery의 parseJSON, JSON.parse, eval 등등 파일 읽을때 인코딩도 EUC-KR등으로 다 해봤는데 디바이
스에서 돌리면 에러가 나더군요.

아래 처럼 파일을 읽어왔습니다.


//로컬 디렉토리 접근
deviceapis.filesystem.resolve(successCB, errorCB, "wgt-package", "r");

file.openStream(successCB, errorCB, "r", "UTF-8");

//successCB 부분
var filestr = fileStream.read(filesize);
var data = $.parseJSON(filestr);

json 내용은 아래의 형태로 이루어져있습니다.

{"obj":[{"type":"image","x":114.0,"y":75.0,"width":210.0,"height":
284.0,"src":"data/page/HDK_PATH_files/PUMP_files/
Ghost.png","id":"image_1"},{"type":"image","x":367.0,"y":
75.0,"width":
210.0,"height":284.0,"src":"data/page/HDK_PATH_files/PUMP_files/
Normal.png","id":"image_2"},{"type":"image","x":621.0,"y":
75.0,"width":
210.0,"height":284.0,"src":"data/page/HDK_PATH_files/PUMP_files/
Alarm.png","id":"image_3"}],"item":
[{"obj":"","grp":"","id":"image_1","type":"image","name":"picture001","titl
e":"","show":
1,"lock":"0","grplist":"","transform-r":[0,0,0],"size":
[0,0,0,114.0,75.0,210.0,284.0],"link":[0,"",0,0]},
{"obj":"","grp":"","id":"image_2","type":"image","name":"picture002","title
":"","show":
1,"lock":"0","grplist":"","transform-r":[0,0,0],"size":
[0,0,0,367.0,75.0,210.0,284.0],"link":[0,"",0,0]},
{"obj":"","grp":"","id":"image_3","type":"image","name":"picture003","title
":"","show":
1,"lock":"0","grplist":"","transform-r":[0,0,0],"size":
[0,0,0,621.0,75.0,210.0,284.0],"link":[0,"",0,0]}],"main":
["","","","",
800,600,"#ffffff","","data/page/
HDK_PATH_files/","PUMP.shape","shape","2011-10-03
18:02:20.365","2011-10-03 18:02:20.365",0],"idx":
[0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0],"convertobj":[],"shape":{"index":
[[0,
[]],[1,[]],[2,[]]],"list":["image_1","image_2","image_3"]}}

존슨

unread,
Oct 10, 2011, 8:11:52 PM10/10/11
to appspr...@googlegroups.com
http://jsonlint.com/ 
등 JSON데이터에 이상은 없는지 확인해 보세요.

DarkAngel

unread,
Oct 10, 2011, 9:20:49 PM10/10/11
to 앱스프레소
json데이터에는 문제 없습니다.


서버를 통해 전송받아서 잘 썼던거고, 안드로이드 sdk의 가상 에뮬레이터에서도 잘 돌아가는데,

갤탭을 연결해서 실제 디바이스에서 디버깅으로 돌려보면 저렇게 에러가 뜨더군요.


저건 json문장중 잘못된 문자열이 있으면 저렇게 에러가 나는걸로 아는데, 같은 데이터를 읽었는데도

유독 디바이스에서 에러가 나는 이유를 모르겠네요.


json 변환 이전에 openstream 으로 데이터가 잘 읽혀오는지 테스트 해봤는데 그 부분까진 문제가 없더군요.

71EH

unread,
Oct 10, 2011, 10:10:37 PM10/10/11
to 앱스프레소
wgt-package는 디렉토라 읽을 수 없습니다.
아마 먼저 wgt-package를 resolve한 후 다시 그 안에 있는 (예를 들어)json.txt를 resolve하셨겠지만
노파심에.. ^^
아래와 같이 코드를 작성하시면 코드를 좀 줄일 수 있을겁니다.
deviceapis.filesystem.resolve(successCB, errorCB, "wgt-package/
json.txt", "r");

에뮬레이터에서 정상적으로 동작하는 (특히나 파일 I/O 관련) 코드는 단말에서도 정상 동작해야 합니다.
(정말 이해하기 어려운 문제군요... ㅡㅡ;)
file에서 읽어들인 json 텍스트를 parsing하기에 앞서 눈으로는 확인해 보셨는지요?
그리고 혹시 다른 단말기에서 테스트해 보실 수 있을까요? (혹시나 갤럭시 탭의 버그? ^^)

DarkAngel

unread,
Oct 10, 2011, 10:45:48 PM10/10/11
to 앱스프레소
네 wgt-package를 바로 읽은건 아니고, 디렉토리를 listFiles 로 돌면서 json 관련 파일들을 읽어오게 해놨습니
다.

json 파싱하기 전에 ax.log로 제대로 들어왔는지도 찍어 봤고요. 이부분까진 에뮬이나 갤탭이나 문제가 없는데

파싱 부분에서 본문의 문제가 생기더군요.


지금 당장 돌려볼 수 있는 디바이스가 갤탭뿐이라 oTL 다른데서 테스트를 못해보고 있네요.


그리고 혹시 listFiles로 디렉토리를 읽어와서 for문으로 돌면서 하위 디렉토리를 또 listFiles로 돌면서

json 관련 파일들을 위와같이 json 으로 파싱하며 읽어오는데, listFiles도 그렇고 openStream도 그렇고

콜백함수가 비동기 이다보니 for문이 다 돌고 나중에 콜백함수들이 전부 실행되서, 끝나는 시점을 알 수 없더군요.

위 행동이 모두 끝난후 바로 이어서 데이터를 화면에 출력하는걸 수행해야 하는데, 이런건 어떻게 처리해야할지

막막하네요 oTL


존슨

unread,
Oct 11, 2011, 8:12:48 PM10/11/11
to appspr...@googlegroups.com
아래 코드는 documents 디랙토리의 파일을 읽어와 데이터를 추출하고 화면에 뿌려주는 예제입니다.

showFileAttributes 가 비동기 콜백이며, clouser 로 감싸 개별 내용을 화면에 뿌려줍니다.
이 펑션에서 json 파싱 등 처리를 하시면 될것 같네요.

json 데이터 파싱은 사용하신 파일들을 첨부해 주시면 테스트 해 보겠습니다.


function initMainPage(){
 
    var documentsDir = null;
   
    var showFileAttributes = function(files){
       
        var content = document.getElementById("content").getElementsByTagName("ul")[0],
            i;
       
        for(var i = 0; i < files.length; i++){
 
            if(files[i].isFile){
               
                (function(targetFile){
                   
                    targetFile.readAsText(function(str) {
   
                        var markup = '<li onclick=editFile("' + targetFile.name + '");>';
                        //console.log("The file content " + str);
                        markup+= '<div class="filename">' + str.substring(0,20) + '...</div>';
                        markup+= '<div class="filedate">' + targetFile.modified + '</div>';
                        markup+= '<a href=javascript:editFile("' + targetFile.name + '"); class="btn"></a>';
                        markup+= '</li>';
                        content.innerHTML+=markup;
                       
                    }, function(e) {
                        //markup+= '<div class="filename">reading file error!</div>';
                        console.log("readAsText Error: " + e.message + " " + targetFile);
                    }, "UTF-8");
 
                }(files[i]));
 
            }
        }
       
        if(i==0){
            document.getElementById("content").innerHTML = '<div class="center-align">NO FILE EXISTS</div>';
        }
 
    };
   
    var errorCallback = function(e){
        console.log('Err: ' + e.message);
    };
 
    deviceapis.filesystem.resolve(function(dir) {
        try{
            documentsDir = dir;
            dir.listFiles(showFileAttributes,errorCallback);
        }catch(e){
            alert(e.message);
        }
    }, function(e) {
        alert(e.message);
    }, 'documents', 'rw');
 
}
Message has been deleted

DarkAngel

unread,
Oct 12, 2011, 2:30:22 AM10/12/11
to 앱스프레소
존슨님 답변 감사합니다.

제가 하려는게 wgt-package 폴더의 하위디렉토리들을 전부 돌면서 json 파일들을 읽어와서 배열 변수에 모두 담은 후

이어서 캔버스로 화면을 그려야 하는데... 하위 디렉토리와 파일들을 읽을때의 콜백 함수가 모두 비동기라서, 위 작업이 모두 끝
나는 시점을 알 수 없더군요.

json 파일을 읽을때마다 화면을 그리는게 아닌, 캐쉬처럼 모두 읽어놓고 화면을 그려야 해서 좀 애매하네요.


(http://dangel.tistory.com/attachment/cfile6.uf@1635383F4E95222927B2BE.
7z)

그리고 제가 사용한 json 파일중 일부입니다. 이미 모바일웹 기반으로는 잘 사용하고 있던거라 파일 자체에는 문제가 없을거라봅니
다.

안드로이드 sdk 의 에뮬에서도 문제가 없는데, 갤탭에서만 오류가 생기는게 참 이상하네요 oTL


감사합니다.


장경석

unread,
Oct 12, 2011, 2:51:38 AM10/12/11
to appspr...@googlegroups.com
안녕하세요
몇일째 json 파싱에 대한 메일을 받아보고 있는데요... 

이래저래 보다보니 파일 파싱하는 함수가 비동기라서 정확한 시점을 잡을 수 없다고 하시는데요

제가 직접 해본건 아니라 정확하지는 않지만, 비동기 함수를 동기식으로 사용하시면 되지 않을까 하네요...

말인 즉슨, 

존슨님이 메일로 보내주신 코드로 예를 들자면
showFileAttributes 함수를 보시면 for 문을 돌면서 각각 파일을 readAsText 하시던데요

showFileAttributes 함수 자체도 비동기지만, for문을 돌면서 행하시는 readAsText 도 비동기라서 끝을 알수 없으실 겁니다.

showFileAttributes 파일에서 for 문을 돌면서 readAsText 하지 마시고, 전역변수로 배열을 하나 선언하시고 파일을 다 담으세요.

그리고 첫번째 파일을 readAsText 하시고, success 콜백 함수에서 2번째 파일을 다시 readAsText,,, 

2번째 파일의 readAsText success 콜백 함수에서 3번째 파일을 readAsText .... 

이런식으로 반복하시다 보면

비동기식 콜백이지만 동기식으로 동작하게 하실 수 있을거 같네요. ㅎㅎ

말이 너무 횡설수설 했는데 ... 잘 해결하시면 좋겠습니다.


2011년 10월 12일 오후 3:30, DarkAngel <futec...@gmail.com>님의 말:

DarkAngel

unread,
Oct 12, 2011, 4:42:38 AM10/12/11
to 앱스프레소
장경석님 답변 감사드립니다.

저도 그런 방법에 대해 생각해보고 그렇게도 해봤었는데, 문제는 listFiles 로 디렉토리를 읽고 for문을 돌면서

그중에 하위 디렉토리가 있으면 또 그 하위 디렉토리를 listFiles 로 읽어서 for문을 돌아야하는데

이 listFiles 의 콜백함수 역시 비동기라 하위 디렉토리를 읽어오는 부분도 끝을 알기가 애매하더군요.


뭔가 다른방식으로 처리하거나, 디렉토리의 파일 리스트를 넘겨받아서 그 리스트에 따라 파일을 읽어오게 하거나 해야 할듯 하네요.

감사드립니다~


그러고보니 이건 사이드 문제였고 본문제는 디바이스에서의 json 파싱 오류인데, 주말에 다른 기기좀 빌려와서 테스트해봐야겠네요
oTL

장경석

unread,
Oct 12, 2011, 5:06:56 AM10/12/11
to appspr...@googlegroups.com
재귀호출 하시면 listFiles 가 비동기라도 가능하실거 같은데요

비동기의 동기화는 번외편이니 ㅋㅋ 

주말에 화이팅 하세요 !!! ㅎㅎㅎ

2011년 10월 12일 오후 5:42, DarkAngel <futec...@gmail.com>님의 말:

존슨

unread,
Oct 13, 2011, 5:41:28 AM10/13/11
to appspr...@googlegroups.com
제 폰(모토롤라 아트릭스) 에서 첨부해 주신 JSON 파일 정상동작 합니다.

ax.util.decodeJSON 매소드를 이용해 디코딩 하였는데, 자세한 문서는 아래 링크 참고하세요.


아래는 테스트 코드입니다.
body onload 에 test()를 호출하세요.


function fileReadAsText(fileName, testType){
   
    var resolveSuccessCallback = function(objFile){
       
        objFile.readAsText(
             function(str){
               
                try{
                    if(testType == 'json'){
                        console.log(fileName + ' ##########################');
                        var o = ax.util.decodeJSON(str);
                       
                        for(var i in o){
                            console.log('json ' + i + ' ' + o[i].toString());
                        }
                       
                    }
                   
                }catch(e){
                    console.log(e.message);
                }
               
             }, function(e){
               console.log('readAsText err: ' + e.message);
             }, "UTF-8"
        );
 
    };
 
    deviceapis.filesystem.resolve(
        resolveSuccessCallback,
        function(e){
            console.log('resolve err: ' + e.message)
        },
        fileName,
        'r'
        ); 
}
 
function test(){
    fileReadAsText('wgt-package/json/PUMP.shape','json');
    fileReadAsText('wgt-package/json/Fan_Centrif_Gray_CW_Right_Dyn.shape','json');
    fileReadAsText('wgt-package/json/Shape_PMP_FAN_R.shape','json');
   
}


아래는 Appspresso Studio "On The Fly" 상의 로그입니다.


11/10/13-18:35:20||/index.html||I||["@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  index.html  @@@@@@@@"]||||
11/10/13-18:35:20||/index.html||I||["wgt-package/json/PUMP.shape ##########################"]||||
11/10/13-18:35:20||/index.html||I||["json obj [object Object],[object Object],[object Object]"]||||
11/10/13-18:35:20||/index.html||I||["json item [object Object],[object Object],[object Object]"]||||
11/10/13-18:35:20||/index.html||I||["json main ,,,,800,600,#ffffff,,data/page/HDK_PATH_files/,PUMP.shape,shape,2011-10-03 18:02:20.365,2011-10-03 18:02:20.365,0"]||||
11/10/13-18:35:20||/index.html||I||["json idx 0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0"]||||
11/10/13-18:35:20||/index.html||I||["json convertobj "]||||
11/10/13-18:35:20||/index.html||I||["json shape [object Object]"]||||
11/10/13-18:35:20||/index.html||I||["wgt-package/json/Shape_PMP_FAN_R.shape ##########################"]||||
11/10/13-18:35:20||/index.html||I||["json obj [object Object],[object Object],[object Object]"]||||
11/10/13-18:35:20||/index.html||I||["json item [object Object],[object Object],[object Object]"]||||
11/10/13-18:35:20||/index.html||I||["json main ,,,,800,600,#ffffff,,data/page/HDK_PATH_files/,Shape_PMP_FAN_R.shape,shape,2011-10-03 18:02:20.394,2011-10-03 18:02:20.394,0"]||||
11/10/13-18:35:20||/index.html||I||["json idx 0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0"]||||
11/10/13-18:35:20||/index.html||I||["json convertobj "]||||
11/10/13-18:35:20||/index.html||I||["json shape [object Object]"]||||
11/10/13-18:35:20||/index.html||I||["wgt-package/json/Fan_Centrif_Gray_CW_Right_Dyn.shape ##########################"]||||
11/10/13-18:35:20||/index.html||I||["json obj [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]"]||||
11/10/13-18:35:20||/index.html||I||["json item [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]"]||||
11/10/13-18:35:20||/index.html||I||["json main ,,,,800,600,#ffffff,,data/page/HDK_PATH_files/,Fan_Centrif_Gray_CW_Right_Dyn.shape,shape,2011-10-04 16:24:28.984,2011-10-04 16:24:32.015,0"]||||
11/10/13-18:35:20||/index.html||I||["json idx 0,0,0,0,0,0,0,4,0,0,0,0,0,0,2"]||||
11/10/13-18:35:20||/index.html||I||["json shape [object Object]"]||||

DarkAngel

unread,
Oct 13, 2011, 6:19:40 AM10/13/11
to 앱스프레소
아 존슨님 답변 감사합니다

말씀해주신 메소드로도 해봤었는데 에러가 나서 이것도 안되는줄 알고 있었는데 존슨님 답변보고 다시 살펴보니
다른곳에 jquery parseJSON 명령이 쓰이고 있어서 계속 에러가 발생했었네요 싸그리 찾아서 바꿔주니 잘되네요 감사합니

jquery parseJSON 으로는 에뮬에선 잘되는데 기기에선 에러가 나는군요
별거 아닌걸로 저처럼 삽질 하시는 분이 없길 바라며 ㅠㅠ

Reply all
Reply to author
Forward
0 new messages