2014-12-22 8 views
16

일부 자바 스크립트 로직을 사용하여 작은 문자열에서 거대한 문자열이 생성 된 다음 브라우저에서 텍스트 파일을 강제로 다운로드하는 경우를 가정 해 보겠습니다.자바 스크립트에서 생성되는 옥텟 스트림을 스트리밍 할 수 있습니까?

이이 답변에서 언급 등의 HREF로 넣어 옥텟 스트림 다운로드 사용 가능하다 :

Create a file in memory for user to download, not through server.

function download(filename, text) { 
    var pom = document.createElement('a'); 
    pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); 
    pom.setAttribute('download', filename); 
    pom.click(); 
} 

그러나이 솔루션은 '텍스트'를 필요로 완전히 다운로드을 추진하기 전에 생성 될, 그러므로 그것은 완전히 브라우저 메모리에 저장해야합니다.

클라이언트 사이드 로직을 사용하여 생성 된 텍스트를 스트리밍 할 수 있습니까? 예를 들어

:

var inputString = "A"; 
var outStr = ""; 
for(var i = 0; i < 10000000 ; i++) 
{ 
    /* concatenate inputString to output on the go */ 
} 
+0

이 질문에 대한 해결책을 찾지 못하면 데이터를 [Blob] (https://developer.mozilla.org/)에 넣는 대신 사용할 수 있습니다. ko-kr/docs/Web/API/Blob)를 다운로드 한 다음 [createObjectURL()] (https://developer.mozilla.org/de/docs/Web/API/URL.createObjectURL)을 사용하여 다운로드 링크를 생성하십시오 . 브라우저는 디스크에 데이터를 캐시 할 가능성이 크며, 특히 큰 데이터 URL을 갖지는 않습니다. – Phillip

+0

@ 필립 모든 내용을 블롭 또는 zip 파일에 저장하거나 indexDb를 사용하지 않으려면 스트리밍이 필요합니다. – DhruvPathak

+1

번. 현재의 모든 브라우저 기술은 첫 번째 바이트를 보내기 전에 전체 크기를 알아야합니다. node.js와 같은 최신 서버 측 항목 만 http1.1 청킹을 사용할 수 있습니다. 당신은 많은 연결이나 버퍼를 사용해야 할 것입니다. 당신은 웹 소켓을 사용할 수 있지만 양쪽 끝에서 약간의 사용자 정의가 필요할 것입니다. – dandavis

답변

8

예 & 없음. 아니요. 클라이언트 쪽 자바 스크립트만으로 파일에 쓸 수있는 방법이 없기 때문입니다. 킨다. 사용자에게 &을 다운로드하라는 메시지를 표시 할 수 있지만 언급 한 바와 같이 코드는 다운로드하기 전에 전체 파일을 생성해야합니다. 참고 : "스트림"에 의해 당신은 파일에 스트림 (파일에 지속적으로 쓰기)을 의미한다고 가정합니다. & "CLIENT SIDE LOGIC ONLY"로 말입니다. 브라우저에서 사용한다고 가정합니다.

Mozilla는 클라이언트 측 코드가 파일과 상호 작용할 수있게하는 것처럼 보입니다. 여기 예가옵니다. 거의. 로컬 컴퓨터의 파일 시스템과 상호 작용할 수있는 자체 컴퓨터가 있습니다 (file system api). 특히 write an input stream to a file을 사용할 수있는 기능이 있습니다. 그러나 몇 가지 별표가 있습니다.

1) 전체 시스템이 더 이상 사용되지 않는 것처럼 보입니다. 개발자는 파일 입출력에 대해 OS.file을 사용하도록 권장합니다.

2) javad에서 Mozilla의 XPCOM (구성 요소 라이브러리)에 액세스 할 수있는 시스템 인 XPConnect을 사용해야합니다. 브라우저에서이 작업을 원한다면 파이어 폭스 확장 기능 만이 해당 컴포넌트 (들)와 상호 작용할 수있는 적절한 권한을 갖고있는 것처럼 보입니다. 브라우저에서이 작업을 원하지 않는다면 노드를 사용할 수 있습니다.

실제로 구현하는 동안 더 많은 합병증이 나타날 수 있습니다. 그러나이 OS.File 당신이 말한되고 그건 write to file

기본 OS.File.writeAtomic() & 같은 기능에 대한 액세스를 제공하는 방법으로보고, 앞으로 가장 확실 경로처럼 보이는, 그것은 경로의 위대한 아니지만, 희망이 당신에게 고체 출발점을 제공합니다. 언급 된대로, 브라우저 (즉, "클라이언트 측 로직")는 이런 종류의 일을 허용하지 않도록 설계되었습니다. 웹 사이트가 모든 사용자의 로컬 파일 시스템과 상호 작용할 수 있다면 엄청난 감시/보안 결함 일 것입니다.

추가 자료 :
Wikipedia on XPConnect
Guide on working with XPCOM in javascript는 - 유용한

4

이 할 수있는 방법이 있다는 것을되지 않을 수도 있습니다,하지만 그것은 크롬 전용 파일 시스템 API에 의존한다. 샌드 박스 화 된 파일 시스템에 임시 파일을 만들고 쓰고 작업이 완료되면 일반 파일 시스템에 복사합니다. 이렇게하면 전체 파일을 메모리에 저장할 필요가 없습니다.크롬 API의 비동기 버전은 현재 W3C에서 표준화를 고려하고 있지 않지만 (웹 작업자를 사용하는) 동기 버전이 있습니다. 브라우저 지원이 문제라면,이 대답은 당신을위한 것이 아닙니다.

API는 다음과 같이 작동합니다. 먼저 브라우저에서 requestFileSystem() 함수를 가져옵니다. 우리가 액세스 할 수 있는지 이제

var fileSystem; //This will store the fileSystem for later access 
var fileSize = 1024*1024 //Our maximum file system size. 
function errorHandler(e) { 
    console.log('Error: ' + e.name); 
} 
window.requestFileSystem(window.TEMPORARY, fileSize, function (fs) { fileSystem = fs; }, errorHandler); 

:

window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; 

다음, 우리가 요청하는 임시 파일 시스템 (우리는 사용자의 허가를 요청하지 않아도 이런 식으로) : 현재 "웹킷"에 의해 접두사

var fileOptions = { 
    create: true, //If the file is not found, create it 
    exclusive: false //Don't throw an error if the file doesn't exist 
}; 

가 여기에 우리가 존재하지 않는 경우 파일을 만들 수 있습니다 getFile() 함수를 호출 파일 시스템은 파일을 만들 수있는 시간입니다. 콜백 내부에서 파일에 쓸 새로운 fileWriter을 만들 수 있습니다. 그러면 fileWriter이 파일의 끝으로 이동하고 추가 할 새 텍스트 blob을 만듭니다.

fileSystem.root.getFile(fileName, fileOptions, function(fileEntry) { 
    fileEntry.createWriter(function(fileWriter) { 
     fileWriter.seek(fileWriter.length); 
     var blob = new Blob([STRING_TO_WRITE], {type: 'text/plain'}); 
     fileWriter.write(blob); 
    }, errorHandler); 
}); 

이 API는 일반 사용자 파일 시스템에 저장하지 않습니다. 대신 특수 샌드 박스 폴더에 저장합니다. 이 파일을 사용자의 파일 시스템에 저장하려면 filesystem: 링크를 만들 수 있습니다. 사용자가 클릭하면 저장하라는 메시지가 표시됩니다. 저장 한 후에는 임시 파일을 제거 할 수 있습니다.

var save = function() { 
    var download = document.querySelector("a[download]"); 
    if (!fileSystem) { return; } 
    fileSystem.root.getFile(fileName, {create: false, exclusive: true}, function(fileEntry) { 
    download.href = fileEntry.toURL(); 
    }, errorHandler); 
} 

파일의 다운로드를 강제로 다운로드 속성을 가진 링크를 사용 :

이 기능은 fileEntrytoURL() 기능을 사용하여 filesystem 링크를 생성합니다. 희망이 당신이 원하는 것을 달성 http://plnkr.co/edit/q6ihXWEXSOtutbEy1b5G?p=preview

: 여기

<a download></a> 

이를 보여줍니다 plunker이다. 파일에 계속 추가 할 수는 있지만 메모리에 저장되지는 ​​않지만 사용자가 파일 시스템에 저장할 때까지는 샌드 박스가있는 파일 시스템에 저장됩니다.

새로운 동기식 웹 작업자 API를 사용하려는 경우 자세한 내용은 HTML5rocks article 또는 this one을 참조하십시오.

2

임시 모래 상자 파일을 사용하여 청크를 추가하는 방법은 @quantumwannabe describes입니다.

그러나 (플래그 뒤에) 현재 사용할 수 있지만 크롬의 다음 버전에서 사용할 수있는 새로운 방법이 여기에 (52)

그리고 내가 할 곳 @ KeenanLidral - 포터 잘못된 답변입니다 .그리고 지금은 직접 파일 시스템에 대한 스트림 작성하는 방법이 있기 때문에 불필요한 단계를
대답 @quantumwannabe :이 진수 스트림 헤더를 보내는 서버이고 덩어리를 다운로드하는 브라우저에 지시하는 것처럼 StreamSaver.js

그것은 역할을 서비스 종사자의 도움을받는 데이터

const writeStream = streamSaver.createWriteStream('filename.txt') 
const encoder = new TextEncoder 
let data = 'a'.repeat(1024) // Writing some stuff triggers the save dialog to show 
let uint8array = encoder.encode(data + "\n\n") 

writeStream.write(uint8array) // Write some data when you got some 
writeStream.close() // End the saving 
+1

github 링크 만 사용하는 대신 해당 라이브러리의 작동 방식에 대한 설명과 사용하는 API에 대한 특정 코드를 게시하십시오. – Bergi

+0

@Endless'ReadableStream'은 크롬, 크롬 50에서 사용할 수 있습니다. – guest271314

관련 문제