2014-12-22 10 views
16

Bazı javascript mantığı kullanarak küçük bir dizeden büyük bir dizenin oluşturulduğu bir durum varsayalım ve sonra metin dosyası tarayıcıya yüklenmeye zorlanır.Javascript'te oluşturulmuş bir okt akışını yürütmek mümkün mü?

Bu, bu cevapta belirtildiği gibi bir href olarak koyarak, sekizli-stream indir kullanılarak mümkündür:

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(); 
} 

Ama bu çözüm 'metin' gerektirir tamamen indirmek için itti önce oluşturulacak, dolayısıyla tamamen tarayıcı bellekte tutulması gerekecektir.

Metni SADECE MÜŞTERİ SIDE MANTIKI kullanarak oluşturulduğu gibi akıtmak mümkün mü? Örneğin

:

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

bir hizmet işçinin yardımıyla veri https://developer.mozilla.org/ (a [Blob] veri koymak en-US/docs/Web/API/Blob) ve sonra indirme için bir bağlantı oluşturmak için [createObjectURL()] (https://developer.mozilla.org/de/docs/Web/API/URL.createObjectURL) kullanın. . Tarayıcılar muhtemelen diskteki verileri önbelleğe alacaktır ve özellikle büyük bir veri URL'niz olmayacaktır. – Phillip

+0

@Phillip Tüm içeriği bir blob veya zip dosyasına kaydetmek veya indexDb'yi kullanmak istemiyorum, akış şarttır. – DhruvPathak

+1

no. Tüm mevcut tarayıcı teknolojileri, ilk baytları göndermeden önce tüm boyutların bilinmesini gerektirir; node.js gibi sadece daha yeni sunucu tarafı şeyler, http1.1 chunking'i kullanabilir. birçok bağlantı veya arabellek kullanmanız gerekecek. websockets kullanabilirsiniz, ancak bu iki ucunda biraz özelleştirme gerektirecektir. – dandavis

cevap

8

Evet & hayır. Hayır çünkü sadece istemci tarafında javascript ile dosyalara yazmanın bir yolu yoktur. Tür. Bir dosyayı kaydetmek için &'u indirmenizi isteyen bir kullanıcı sorabilirsiniz, ancak bahsettiğiniz gibi, kod, bu indirme işlemi gerçekleşmeden önce tüm dosyayı oluşturmalıdır. Not: "Aktarım" ile, bir dosyaya (bir dosyaya sürekli olarak yazarak) & "SADECE MÜŞTERİ SIDE LOGIC" yazarak, tarayıcıda kastettiğinizi kastediyorum.

Mozilla, istemci tarafı kodunun dosyalarla etkileşime girmesine izin verecek şekilde çalışıyor gibi görünüyor. İşte evet geliyor. Biraz. Yerel makineler dosya sistemi ile etkileşime girebilmenizi sağlayan kendi file system api numaralarına sahipler. Özellikle, write an input stream to a file'u sağlayan bir işlev var. Ancak, birkaç yıldız işareti vardır:

1) tüm sistem kullanımdan kaldırılıyor gibi görünüyor; onlar Dosya üzerinde OS.file geliştiricilerin kullanmasını teşvik Sen XPConnect, sen javascript Mozilla'nın XPCOM (bileşen kütüphanesi) erişim sağlayan bir sistemi kullanmak zorunda I/O

2). Bunu tarayıcıda yapmak istiyorsanız, yalnızca firefox uzantılarının bu bileşenlerle() etkileşimde bulunmak için uygun izinlere sahip olması gibi görünüyor. Bunu tarayıcıda yapmak istemediyseniz, açıkça sadece düğüm kullanabilirsiniz.

Kesinlikle, uygulama sırasında daha fazla komplikasyonun ortaya çıkması zorunludur. Ama bu OS.File sen söyleniyor write to file

temel OS.File.writeAtomic() & gibi fonksiyonlara erişim sağlar nasıl gibi görerek, ileriye en emin yolu gibi görünen, bir yolun büyük değil, ama umarım bu size sağlam bir başlangıç ​​noktası verir. @dandavis'in bahsettiği gibi, tarayıcılar (yani "istemci tarafı mantığı") bu tür bir şeye izin vermeyecek şekilde tasarlanmıştır. Bir web sitesi herhangi bir kullanıcının yerel dosya sistemi ile etkileşimde bulunabilseydi, inanılmaz derecede büyük bir gözetim/güvenlik hatası olurdu.

Ek kaynaklar:
Wikipedia on XPConnect
Guide on working with XPCOM in javascript - kullanışlı

4

bunu yapmanın bir yolu var olduğunu olmayabilir, ama bir Chrome yalnızca Dosya Sistemi API dayanır. Korumalı bir dosya sisteminde geçici bir dosya oluşturup yazacağız ve işimiz bittikten sonra normal dosya sistemine kopyalayacağız. Bu şekilde, tüm dosyayı belleğe kaydetmeniz gerekmez.Chrome API'sinin senkronize olmayan sürümü şu anda W3C tarafından standartlaştırma için dikkate alınmıyor, ancak senkronize olan (web çalışanlarını kullanan) verison. Tarayıcı desteği bir endişe ise, o zaman bu cevap sizin için değildir.

API bu gibi çalışır: Öncelikle tarayıcıdan requestFileSystem() fonksiyonunu olsun. Biz erişimi olduğunu Şimdi

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; 

Sonra, talep geçici dosya sistemi (biz kullanıcı izin istemek gerekmez bu şekilde): Şu anda "webkit" öneki

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 
}; 

Burada biz yoksa bir dosya oluşturabilirsiniz getFile() fonksiyonunu çağırır: dosya sistemine bir dosya oluşturmak zamanıdır. Geri aramada, dosyaya yazmak için yeni bir fileWriter oluşturabilirsiniz. fileWriter daha sonra dosyanın sonuna taşınır ve buna eklemek için yeni bir metin bloğu oluştururuz.

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); 
}); 

Bu API'nın normal, kullanıcı dosya sistemine kaydedilmediğini unutmayın. Bunun yerine, özel bir korumalı klasöre kaydeder. Kullanıcının dosya sistemine kaydetmek istiyorsanız, bir filesystem: bağlantısı oluşturabilirsiniz. Kullanıcı tıkladığında, onları kaydetmesini isteyecektir. Kaydettikten sonra, geçici dosyayı kaldırabilirsiniz.

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); 
} 

dosyanın indirilmesini zorlar indirme özelliği olan bir bağlantı kullanma:

Bu fonksiyon fileEntry 'ın toURL() işlevini kullanarak filesystem bağlantı oluşturur. Umarım bu istediğini yapar http://plnkr.co/edit/q6ihXWEXSOtutbEy1b5G?p=preview

: Burada

<a download></a> 

bu gösteren bir plunker olduğunu. Dosyaya sürekli olarak ekleyebilir, bellekte saklanmayacaktır, ancak kullanıcı normal dosya sistemine kaydedinceye kadar korumalı dosya sisteminde olacaktır.

Daha fazla bilgi için, daha yeni, eşzamanlı Web Çalışanı API'sini kullanmak isterseniz, bu HTML5rocks article veya this one'a bakın.

2

Yolları eklemek için geçici sanal dosya kullanarak @quantumwannabe describes yolunu öneririm.

Ama (bir bayrak arkasında) bugün kullanılabilir ancak krom sonraki sürümünde etkin olacak yeni bir yol yoktur burada (52)

Ve yapacaktır nereye @ KeenanLidral-Porter yanlış cevap olduğunu .Ve şimdi doğrudan dosya sistemine akışı yazmak için bir yolu olmadığından bir gereksiz adım
cevap @quantumwannabe: orada sekizli-stream başlığını gönderen bir sunucu ve parçalarını indirmek için tarayıcı söyler sanki StreamSaver.js

O davranır Bu soruya doğru bir çözüm bulamazsanız, bu bir alternatif olabilir

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

Lütfen kütüphanenin nasıl çalıştığına ve belki de yalnızca bir github bağlantısı yerine kullandığı API (ler) için özel bir kodun nasıl çalıştığına dair bir açıklama gönderin. – Bergi

+0

@Revesiz "ReadableStream", kromda kullanılabilir, krom 50 – guest271314

İlgili konular