Jak czytać i zapisywać do pliku za pomocą JavaScript?

177

Czy ktoś może podać przykładowy kod do odczytu i zapisu pliku przy użyciu JavaScript?

user4642212
źródło
2
A po co ci to? Może są obejścia.
Ionuț G. Stan
1
pytano już wiele razy
annakata,
1
Znalazłem ten zasób dotyczący przechowywania plików po stronie klienta. html5rocks.com/en/tutorials/offline/storage Z tego, co zebrałem, HTML5 w rzeczywistości pozwala Websights na przechowywanie informacji na lokalnym dysku twardym użytkownika, ale w sposób bardziej przypominający bazę danych. Przeglądarka zarządza przechowywaniem plików i nakłada pewne ograniczenia, aby uniemożliwić World Wide Web ładowanie dysków twardych ludzi po brzegi. Nie są jeszcze całkowicie głupie, ale są modyfikowane, przynajmniej zgodnie z tym artykułem. Przeczytaj szczegóły.
Garrett
2
Użyj Ajax i obsługi PHP do odczytu i zapisu plików. Jeśli chcesz obsłużyć zapisywanie plików po stronie klienta, powinieneś o tym zapomnieć. Wymagałoby to wyłączenia wielu opcji zabezpieczeń na serwerze, co spowodowałoby skrajnie niezabezpieczoną witrynę. Jeśli nie chcesz używać PHP, być może to, co chcesz osiągnąć, możesz osiągnąć, używając plików cookie JavaScript do przechowywania danych na komputerze klienta.
Dan Bray

Odpowiedzi:

64

Dokładnie rzecz biorąc, OP nie stwierdza, że ​​zamierza to zrobić w przeglądarce (jeśli tak, jak stwierdzono, jest to generalnie niemożliwe)

Jednak javascript jako taki pozwala na to; można to zrobić za pomocą javascript po stronie serwera.

Zobacz tę dokumentację dotyczącą klasy pliku Javascript

Edycja : to łącze prowadziło do dokumentów Sun, które zostały teraz przeniesione przez Oracle.

Aby nadążyć za czasem, oto dokumentacja node.js dla klasy FileSystem: http://nodejs.org/docs/latest/api/fs.html

Edycja (2) : Możesz teraz czytać pliki po stronie klienta za pomocą HTML5: http://www.html5rocks.com/en/tutorials/file/dndfiles/

DanSingerman
źródło
3
Czy można również zapisywać pliki lokalne za pomocą HTML5?
Anderson Green
1
Ponadto, w zależności od sytuacji, możesz wykonać wywołanie AJAX do skryptu PHP i w ten sposób zrzucić dane. Było to przydatne w mojej sytuacji, w której chciałem przechowywać niektóre dane wygenerowane po stronie javascript, ale nie miało znaczenia, jak się tam dostały.
Dustin Graham
1
@DustinGraham Właściwie teraz z Chrome API my może faktycznie zapisu plików na stronie klienta poprzez prawo JavaScript?
Pacerier
40

Nie. JavaScript działający po stronie przeglądarki nie ma uprawnień do zapisu na komputerze klienta bez konieczności wyłączenia wielu opcji zabezpieczeń

Gareth
źródło
44
@marcgg: To sprawia, że ​​ta odpowiedź jest niekompletna, a nie błędna. I, nie oszukujmy się, to jest wysoce prawdopodobne, że odpowiedź ta ma obejmować przypadek użycia PO za.
Wyścigi lekkości na orbicie
36
Gdyby OP planował używać javascript poza przeglądarką, jest to na tyle rzadkie, że prawdopodobnie by o tym wspomnieli. Zakładanie przeglądarki nie jest nierozsądne (i na pewno nie jest błędne). +1 (aby zrekompensować -1 marcgg).
Michael Martin-Smucker
2
@LightnessRacesinOrbit Przycisk „przeciwne” nie oznacza, że ​​uważa się, że odpowiedź jest nieprawidłowa. Jego tekst podpowiedzi to This answer is not useful.
Niechlujny
1
@Mike - Nie było tego, kiedy napisano tę odpowiedź, i nadal rozsądnie jest zakładać domyślnie JS po stronie przeglądarki.
Quentin
16

Przyszłość jest tutaj! Propozycje są bliżej ukończenia, koniec z ActiveX, flash lub java. Teraz możemy użyć:

Możesz użyć przeciągnij / upuść, aby pobrać plik do przeglądarki lub prostej kontrolki przesyłania. Gdy użytkownik wybierze plik, możesz go przeczytać w / Javascript: http://www.html5rocks.com/en/tutorials/file/dndfiles/

Thomas Shields
źródło
Linki są teraz zerwane.
Prometeusz
Linki są znowu zepsute, oba są tym samym łączem, ale mają różne znaczenie.
środku
Naprawiono @insidesin
Thomas Shields
14

oto propozycja Mozilli

http://www-archive.mozilla.org/js/js-file-object.html

jest to realizowane za pomocą przełącznika kompilacji w spidermonkey, a także w rozszerzonym skrypcie Adobe. Dodatkowo (myślę) otrzymujesz obiekt File w rozszerzeniach Firefoksa.

rhino ma (raczej podstawową) funkcję readFile https://developer.mozilla.org/en/Rhino_Shell

w przypadku bardziej złożonych operacji na plikach w rhino możesz użyć metod java.io.File.

nie dostaniesz jednak żadnego z tych rzeczy w przeglądarce. Aby uzyskać podobną funkcjonalność w przeglądarce, możesz użyć funkcji bazy danych SQL z HTML5, trwałości po stronie klienta, plików cookie i obiektów pamięci flash.

Breton
źródło
12

Ta funkcja JavaScript prezentuje pełne okno dialogowe „Zapisz jako” dla użytkownika, który uruchamia to za pośrednictwem przeglądarki. Użytkownik naciska OK i plik zostaje zapisany.

Edycja: Poniższy kod działa tylko z przeglądarką IE, ponieważ Firefox i Chrome uznały ten kod za problem z bezpieczeństwem i zablokowały jego działanie.

// content is the data you'll write to file<br/>
// filename is the filename<br/>
// what I did is use iFrame as a buffer, fill it up with text
function save_content_to_file(content, filename)
{
    var dlg = false;
    with(document){
     ir=createElement('iframe');
     ir.id='ifr';
     ir.location='about.blank';
     ir.style.display='none';
     body.appendChild(ir);
      with(getElementById('ifr').contentWindow.document){
           open("text/plain", "replace");
           charset = "utf-8";
           write(content);
           close();
           document.charset = "utf-8";
           dlg = execCommand('SaveAs', false, filename+'.txt');
       }
       body.removeChild(ir);
     }
    return dlg;
}

Wywołaj funkcję:

save_content_to_file("Hello", "C:\\test");
Temp
źródło
1
ir = createElement ('iframe'); - iframe to identyfikator iFrame.
Temp
Czy będzie działać na wszystkich systemach operacyjnych (o ile zostanie wybrana prawidłowa lokalizacja pliku?)
Anderson Green,
4
To dobre rozwiązanie, ale czy działa tylko z IE? Próbowałem IE i FF iz FF to nie działa.
gen
9

Jeśli używasz JScript (Microsoft's Javascript) do wykonywania lokalnych skryptów za pomocą WSH (NIE w przeglądarce!), Możesz użyć, Scripting.FileSystemObjectaby uzyskać dostęp do systemu plików.

Myślę, że możesz uzyskać dostęp do tego samego obiektu w IE, jeśli wyłączysz wiele ustawień bezpieczeństwa, ale byłby to bardzo, bardzo zły pomysł.

MSDN tutaj

Dana Robinson
źródło
Chciałem to zrobić w htaaplikacji i to rozwiązuje
chiliNUT
8

Obecnie pliki można zapisywać i odczytywać z kontekstu karty / okna przeglądarki za pomocą interfejsów API File , FileWriter i FileSystem , chociaż istnieją zastrzeżenia co do ich użycia (patrz koniec tej odpowiedzi).

Ale żeby odpowiedzieć na twoje pytanie:

Korzystanie z BakedGoods *

Zapisz plik:

bakedGoods.set({
    data: [{key: "testFile", value: "Hello world!", dataFormat: "text/plain"}],
    storageTypes: ["fileSystem"],
    options: {fileSystem:{storageType: Window.PERSISTENT}},
    complete: function(byStorageTypeStoredItemRangeDataObj, byStorageTypeErrorObj){}
});

Czytaj plik:

bakedGoods.get({
        data: ["testFile"],
        storageTypes: ["fileSystem"],
        options: {fileSystem:{storageType: Window.PERSISTENT}},
        complete: function(resultDataObj, byStorageTypeErrorObj){}
});

Korzystanie z nieprzetworzonych interfejsów API File, FileWriter i FileSystem

Zapisz plik:

function onQuotaRequestSuccess(grantedQuota)
{

    function saveFile(directoryEntry)
    {

        function createFileWriter(fileEntry)
        {

            function write(fileWriter)
            {
                var dataBlob = new Blob(["Hello world!"], {type: "text/plain"});
                fileWriter.write(dataBlob);              
            }

            fileEntry.createWriter(write);
        }

        directoryEntry.getFile(
            "testFile", 
            {create: true, exclusive: true},
            createFileWriter
        );
    }

    requestFileSystem(Window.PERSISTENT, grantedQuota, saveFile);
}

var desiredQuota = 1024 * 1024 * 1024;
var quotaManagementObj = navigator.webkitPersistentStorage;
quotaManagementObj.requestQuota(desiredQuota, onQuotaRequestSuccess);

Czytaj plik:

function onQuotaRequestSuccess(grantedQuota)
{

    function getfile(directoryEntry)
    {

        function readFile(fileEntry)
        {

            function read(file)
            {
                var fileReader = new FileReader();

                fileReader.onload = function(){var fileData = fileReader.result};
                fileReader.readAsText(file);             
            }

            fileEntry.file(read);
        }

        directoryEntry.getFile(
            "testFile", 
            {create: false},
            readFile
        );
    }

    requestFileSystem(Window.PERSISTENT, grantedQuota, getFile);
}

var desiredQuota = 1024 * 1024 * 1024;
var quotaManagementObj = navigator.webkitPersistentStorage;
quotaManagementObj.requestQuota(desiredQuota, onQuotaRequestSuccess);

Tylko o co prosiłeś, prawda? Może, może nie. Ostatnie dwa interfejsy API:

  • Są obecnie zaimplementowane tylko w przeglądarkach opartych na Chromium (Chrome i Opera)
  • Zostały usunięte ze ścieżki standardów W3C i od teraz są zastrzeżonymi API
  • W przyszłości może zostać usunięty z przeglądarek implementujących
  • Ogranicz tworzenie plików do piaskownicy (lokalizacji, poza którą pliki nie mogą wywoływać żadnego efektu) na dysku

Ponadto specyfikacja FileSystem nie określa żadnych wytycznych dotyczących wyglądu struktur katalogów na dysku. Na przykład w przeglądarkach opartych na Chromium piaskownica ma wirtualny system plików (struktura katalogów, która niekoniecznie istnieje na dysku w takiej samej formie, jaką ma przy dostępie z poziomu przeglądarki), w którym katalogi i pliki utworzone za pomocą Umieszczane są interfejsy API.

Więc chociaż możesz być w stanie zapisać pliki w systemie za pomocą API, zlokalizowanie plików bez API (no cóż, bez API FileSystem) może być nietrywialną sprawą.

Jeśli możesz poradzić sobie z tymi problemami / ograniczeniami, te interfejsy API są prawie jedynym natywnym sposobem robienia tego, o co prosiłeś.

Jeśli jesteś otwarty na rozwiązania inne niż natywne, Silverlight umożliwia również we / wy plików z konkursu karty / okna za pośrednictwem IsolatedStorage . Jednak kod zarządzany do korzystania z tej funkcji wymagany jest ; rozwiązanie wymagające napisania takiego kodu wykracza poza zakres tego pytania.

Oczywiście rozwiązanie, które korzysta z komplementarnego kodu zarządzanego, pozostawiając tylko Javascript do pisania, mieści się w zakresie tego pytania;):

//Write file to first of either FileSystem or IsolatedStorage
bakedGoods.set({
    data: [{key: "testFile", value: "Hello world!", dataFormat: "text/plain"}],
    storageTypes: ["fileSystem", "silverlight"],
    options: {fileSystem:{storageType: Window.PERSISTENT}},
    complete: function(byStorageTypeStoredItemRangeDataObj, byStorageTypeErrorObj){}
});

* BakedGoods to biblioteka Javascript, która tworzy jednolity interfejs, który może być używany do przeprowadzania typowych operacji przechowywania we wszystkich natywnych i niektórych innych niż natywnych urządzeniach magazynujących. Utrzymuje go ten gość tutaj:).

Kevin
źródło
5

W kontekście przeglądarki Javascript może CZYTAĆ plik określony przez użytkownika. Zobacz blog Erica Bidelmana, aby uzyskać szczegółowe informacje na temat odczytywania plików za pomocą interfejsu API plików. Jednak skrypt Javascript oparty na przeglądarce nie może NAPISAĆ systemu plików komputera lokalnego bez wyłączania niektórych ustawień zabezpieczeń, ponieważ dowolna zmiana lokalnego systemu plików jest traktowana jako zagrożenie bezpieczeństwa dla dowolnej witryny internetowej.

Mówiąc to, istnieje kilka sposobów obejścia tego w zależności od tego, co próbujesz zrobić:

  1. Jeśli jest to Twoja własna witryna, możesz osadzić aplet Java na stronie internetowej. Jednak odwiedzający musi zainstalować Javę na komputerze lokalnym i zostanie ostrzeżony o zagrożeniu bezpieczeństwa. Gość musi zezwolić na załadowanie apletu. Aplet Java jest jak wykonywalne oprogramowanie, które ma pełny dostęp do komputera lokalnego.

  2. Chrome obsługuje system plików będący częścią lokalnego systemu plików w trybie piaskownicy. Szczegółowe informacje można znaleźć na tej stronie . Zapewnia to prawdopodobnie tymczasowe zapisywanie rzeczy lokalnie. Jednak nie jest to obsługiwane przez inne przeglądarki.

  3. Jeśli nie jesteś ograniczony do przeglądarki, Node.js ma pełny interfejs systemu plików. Zobacz tutaj dokumentację dotyczącą systemu plików . Zwróć uwagę, że Node.js może działać nie tylko na serwerach, ale także na dowolnym komputerze klienckim, w tym Windows. Moduł uruchamiający testy javascript Karma jest oparty na Node.js. Jeśli po prostu lubisz programować w JavaScript na komputerze lokalnym, jest to opcja.

gm2008
źródło
3

Aby utworzyć plik, spróbuj

function makefile(){
  var fso;
  var thefile;

    fso = new ActiveXObject("Scripting.FileSystemObject");
    thefile=fso.CreateTextFile("C:\\tmp\\MyFile.txt",true);

    thefile.close()
    }

Utwórz katalog na dysku C, ponieważ system Windows jest zabezpieczony przed zapisem z Internetu, np. Utwórz folder o nazwie „tmp” na dysku C.

Ifiok Idiang
źródło
2

Będziesz musiał skorzystać z Flasha, Java lub Silverlight. W przypadku Silverlight będziesz patrzeć na izolowany magazyn . Dzięki temu będziesz zapisywać pliki w swoim własnym placu zabaw na dysku użytkownika. Nie pozwoli ci jednak pisać poza placem zabaw.

Cory R. King
źródło
1

Nie możesz tego zrobić w żaden sposób w różnych przeglądarkach. IE ma metody umożliwiające „zaufanym” aplikacjom używanie obiektów ActiveX do odczytu / zapisu plików, ale niestety to wszystko.

Jeśli chcesz zapisać informacje o użytkowniku, najprawdopodobniej będziesz musiał użyć plików cookie.

Philip Reynolds
źródło
4
A co dokładnie stanowi przeszkodę w zostaniu „zaufaną” aplikacją? Dialog potwierdzający?
Breton,
@Philip, nikt nie powiedział, że musi to być cross browser. W przypadku każdej przeglądarki można zastosować inne rozwiązanie.
Pacerier
1

Z testu ReactJS następujący kod pomyślnie zapisuje plik:

import writeJsonFile from 'write-json-file';

const ans = 42;
writeJsonFile('answer.txt', ans);

const json = {"answer": ans};
writeJsonFile('answer_json.txt', json);

Plik jest zapisywany w katalogu zawierającym testy, więc zapis do rzeczywistego pliku JSON „* .json” tworzy pętlę!

Steve Pitchers
źródło
0

Nie można wykonywać operacji we / wy plików po stronie klienta za pomocą javascript, ponieważ stanowiłoby to zagrożenie bezpieczeństwa. Musiałbyś albo zmusić ich do pobrania i uruchomienia exe, albo jeśli plik znajduje się na twoim serwerze, użyj AJAX i języka po stronie serwera, takiego jak PHP, aby wykonać operacje we / wy po stronie serwera

Kliknij opcję Głos za
źródło
1
To nie daje odpowiedzi na pytanie. Aby skrytykować lub poprosić autora o wyjaśnienie, zostaw komentarz pod jego postem.
harpun
@harpun, dokładnie. Usuń tę odpowiedź i przekształć ją w komentarz.
Pacerier
0

Istnieją dwa sposoby odczytu i zapisu pliku przy użyciu JavaScript

  1. Korzystanie z rozszerzeń JavaScript

  2. Korzystanie ze strony internetowej i obiektów Active X.

Grigor IWT
źródło
-1

Oto rozwiązanie do zapisu dla chrome v52 + (użytkownik nadal musi wybrać docelową kowalkę ...)
źródło: StreamSaver.js

<!-- load StreamSaver.js before streams polyfill to detect support -->
<script src="StreamSaver.js"></script>
<script src="https://wzrd.in/standalone/web-streams-polyfill@latest"></script>
const writeStream = streamSaver.createWriteStream('filename.txt')
const encoder = new TextEncoder
let data = 'a'.repeat(1024)
let uint8array = encoder.encode(data + "\n\n")

writeStream.write(uint8array) // must be uInt8array
writeStream.close()

Najlepiej nadaje się do pisania dużych danych generowanych po stronie klienta.
W przeciwnym razie sugeruję użycie FileSaver.js do zapisania Blob / Files

Nieskończony
źródło