after reading a file as text i can't remake a file from it

58 Views Asked by At

i have a file a image/png file i need to read it with the FileReader api and then make a file or blob from the text the problem here is when i try to make a file the data seems to be corrupted i tried to read the data as text after reading the file as dataURL and there is difference i need a way to make the text from the FileReader.readAsText match the one from decoded dataURL by atob

let inp = document.querySelector("input")

async function read(file,type) { 
    let reader = new FileReader
    reader[type](file)

    return new Promise((res) => { 
        reader.addEventListener("load",_ => { 
            res(reader.result)
        })
    })
}

function decodeDataUrl(dataurl) { 
   return atob(dataurl.split(',')[1])
}

inp.addEventListener("input",async _ => { 
    let [file] = inp.files

    let dataURL = await read(file,"readAsDataURL")
    let text = decodeDataUrl(dataURL)
    console.log({text,length: text.length});

    text = await read(file,"readAsText")
    console.log({text,length: text.length});
})
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input type="file">
</body>
</html>

and here is a screenshot after testing the code with fileenter image description here

notes:

  1. i don't want any library or framework for that so no jquery
  2. don't present another way for dealing with files or blob best than that i know i can use another ways to manage files data better than read it as text by FileReader.readAsText but i don't have control over this point
  3. don't mind my bad english
1

There are 1 best solutions below

2
traktor On

Answer 1 - using readFileAsText

const binaryString = await read(file, "latin1");

where bytes from the file are inserted in binaryString as 8 bit character codes.

binaryString can be converted to a base64 encoded string using

const base64String = btoa(binaryString);

Answer 2 - using formData

This is best covered in formData method examples on MDN:

  1. Using formData.set

    formData.set("userpic", myFileInput.files[0], "chris.jpg");
    
  2. To upload multiple files using the same named form field, use the formData.append method instead.