-
[Flex] 대용량 파일 전송공부방/Flex 2012. 7. 18. 18:06
Flex에서 소켓을 통한 파일 전송은 100메가 용량만 신뢰성을 보장한다는 내용의 글을 본적이 있다.
현재 진행하고 있는 프로젝트에서 대용량의 파일 전송이 요구되어 이를 위해 대용량의 파일을 100메가로 분할 하여 전송하는 방법을 사용하여 문제를 해결 하였다.아직 잘 다듬어 지진 않았지만 테스트를 위해 사용한 내용을 정리한다.1. 먼저 파일 브라우저에서 여러개의 파일을 선택하기 위한 부분 구현이다.public var _numCurrentUpload:Number = 0; // 파일 인덱스public var filePosion:uint = 0; // 분할하여 전송중인 파일의 포지션public var currentFileSize:uint = 0; // 전체 파일중 전송 된 파일의 용량public var currentFileTotalSize:uint = 0; // 파일 크기 외에 파일 이름등이 포함된 크기의 용량public var _refUploadFile:FileStream; // 파일 리스트 사용을 위한 파일 레퍼런스public var _refUploadFiles:File; // 업로드 할 파일public var _arrUploadFiles:Array; // 업로드할 파일 리스트// 파일 브라우저에 비디오 파일을 위한 필터를 적용 및 멀티 파일 브라우저 적용public function addFiles():void {var _refFilter:FileFilter = new FileFilter("Video(*.flv, *.mp4 , *.3gp)", "*.flv;*.mp4;*.3gp");_refUploadFiles = new File();_refUploadFiles.addEventListener(FileListEvent.SELECT_MULTIPLE, onSelectFile);_refUploadFiles.browseForOpenMultiple("Select Files", [_refFilter]);}// 파일 브라우저에서 파일 선택 시 호출 (파일 리스트에 선택한 파일들을 등록한다)public function onSelectFile(event:FileListEvent):void{var arrFoundList:Array = new Array();for (var i:Number = 0; i < _arrUploadFiles.length; i++) {for (var j:Number = 0; j < event.files.length; j++) {if (_arrUploadFiles[i].name == event.files[j].name) {arrFoundList.push(event.files[j].name);event.files.splice(j, 1);j--;}}}if (event.files.length >= 1) {for (var k:Number = 0; k < event.files.length; k++) {var flag:Boolean = new Boolean(true);_arrUploadFiles.push({name:event.files[k].name,size:formatFileSize(event.files[k].size),file:event.files[k],flag:flag});}listFiles.dataProvider = _arrUploadFiles;listFiles.selectedIndex = _arrUploadFiles.length - 1;}if (arrFoundList.length >= 1) {Alert.show("The file(s): \n\n• " + arrFoundList.join("\n• ") + "\n\n...are already on the upload list. Please change the filename(s) or pick a different file.", "File(s) already on list");}}// 파일 목록에 추가된 파일 삭제public function removeFiles():void {var arrSelected:Array = listFiles.selectedIndices;if (arrSelected.length >= 1) {for (var i:Number = 0; i < arrSelected.length; i++) {_arrUploadFiles[Number(arrSelected[i])] = null;}for (var j:Number = 0; j < _arrUploadFiles.length; j++) {if (_arrUploadFiles[j] == null) {_arrUploadFiles.splice(j, 1);j--;if(_numCurrentUpload > 0){_numCurrentUpload--;}}}listFiles.dataProvider = _arrUploadFiles;listFiles.selectedIndex = 0;}trace(_numCurrentUpload);}// 추가된 파일의 용량 표시public function formatFileSize(numSize:Number):String {var strReturn:String;numSize = Number(numSize / 1000);strReturn = String(numSize.toFixed(1) + " KB");if (numSize > 1000) {numSize = numSize / 1000;strReturn = String(numSize.toFixed(1) + " MB");if (numSize > 1000) {numSize = numSize / 1000;strReturn = String(numSize.toFixed(1) + " GB");}}return strReturn;}2. 전송 버튼 클릭 시 파일 전송//전송 버튼 클릭 시 파일 리스트에 있는 파일 들 전송public function startUpload(booIsFirst:Boolean):void{if (_arrUploadFiles.length > 0 && _arrUploadFiles.length > _numCurrentUpload ) {if(_arrUploadFiles[_numCurrentUpload].flag){_refUploadFile = new FileStream();_refUploadFile.open(_arrUploadFiles[_numCurrentUpload].file ,FileMode.READ);sendCurrentFile(true);}}}// 파일 리스트의 현재 파일 전송 (반복문을 돌면서 리스트에 있는 파일들을 하나씩 전송)public function sendCurrentFile(boolean:Boolean):void{var temp:ByteArray = new ByteArray();if(boolean){if(filePosion == 0){if(_arrUploadFiles[_numCurrentUpload].file.size > maxLength){_refUploadFile.readBytes(temp, 0, maxLength);filePosion = filePosion + maxLength;}else{_refUploadFile.readBytes(temp, 0, _refUploadFile.bytesAvailable);}sendFile(temp,_arrUploadFiles[_numCurrentUpload].file, firstFlag);}else{if(_refUploadFile.bytesAvailable > maxLength){_refUploadFile.position = filePosion;_refUploadFile.readBytes(temp, 0, maxLength);filePosion = filePosion + maxLength;}else{_refUploadFile.position = filePosion;_refUploadFile.readBytes(temp, 0, _refUploadFile.bytesAvailable);}sendFIle(temp,_arrUploadFiles[_numCurrentUpload].file, firstFlag);}}else{trace();}}3. 소켓을 통한 파일 전송 부분
// 비디오 파일 전송
public function sendFile(dt:ByteArray, uploadFile:File, firstFlag:Boolean):void{
if(m_socket.connected == true)
{
var data:ByteArray = new ByteArray(); //Data 정보 담는 배열
var tempData:ByteArray = new ByteArray(); // 임시 배열
m_socket.writeMultiByte("xxx","ASCII"); // 1 . 소켓에 플래그 저장 (3byte)
tempData.writeUTFBytes(uploadFile.name);
data.writeUnsignedInt(tempData.length); // 파일이름 크기 갱신
data.writeBytes(tempData, 0, tempData.length); // 파일 이름 갱신
tempData.clear();
data.writeUnsignedInt(uploadFile.size); // 현재 데이터 크기 저장(4바이트)
data.writeBytes(dt, 0, dt.bytesAvailable); // 소켓에 데이터 저장
m_socket.writeUnsignedInt(data.length); // 소켓에 데이터 크기 저장
m_socket.writeUnsignedInt(McsCMD.CMD_SND_MOV); // 소켓에 커맨드 저장 (4byte)
m_socket.writeBytes(data, 0 , data.length); // 소켓에 데이터 저장
if (firstFlag){
v_filemanager.currentFileTotalSize = getFileSize(uploadFile.size ,m_socket.bytesPending, dt.length); v_filemanager.firstFlag = false;
}
v_filemanager.currentFileSize = v_filemanager.currentFileSize + m_socket.bytesPending;
m_socket.flush();
}else{
Alert.show("대상에 연결되어있지 않습니다.", "확인");
}
}
'공부방 > Flex' 카테고리의 다른 글
[Flex] Custom AIR updater interface using ApplicationUpdater (0) 2012.07.20 [Flex] ApplicationUpdater 클래스로 Adobe AIR 자동 업데이트 (0) 2012.07.20 Communicating between Flash Player and Adobe AIR with sockets (0) 2012.07.13 [Flex] Combobox 텍스트 입력 자동 완성 (0) 2012.04.09 [Flex] Object의 Key와 값을 동적으로 적용하기 (0) 2012.03.28