欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Js中FileReader讀取文件內(nèi)容方法詳解(async/await)

 更新時間:2023年11月06日 15:44:32   作者:lee_jp  
這篇文章主要給大家介紹了關(guān)于Js中FileReader讀取文件內(nèi)容(async/await)的相關(guān)資料,FileReader是前端進(jìn)行文件處理的一個重要的Api,特別是在對圖片的處理上,如果你想知道圖片的處理原理,你就永遠(yuǎn)不可能繞過它,需要的朋友可以參考下

要通過FileReader判斷上傳的文件是否為圖片,可以使用FileReader讀取文件內(nèi)容,并判斷文件的MIME類型是否為圖片類型。

以下是一個示例代碼,可以在文件上傳時觸發(fā)change事件,并檢查上傳的文件是否為圖片類型:

<input type="file" id="fileInput" onchange="checkFile(event)">

function checkFile(event) {
  const file = event.target.files[0];
  const reader = new FileReader();
  reader.onload = function() {
    const uint = new Uint8Array(reader.result);
    let bytes = [];
    uint.forEach((byte) => {
      bytes.push(byte.toString(16));
    })
    const hex = bytes.join('').toUpperCase();
    const fileType = getFileType(hex);
    if (fileType !== 'image') {
      alert('Please upload an image file');
      return;
    }
    getImageSize(file);
  }
  reader.readAsArrayBuffer(file);
}

function getFileType(hex) {
  const fileTypes = {
    'FFD8FF': 'image/jpeg',
    '89504E': 'image/png',
    '474946': 'image/gif',
    '424D': 'image/bmp'
  };
  const fileTypeHex = hex.slice(0, 6);
  const fileType = Object.keys(fileTypes).find(key => key === fileTypeHex);
  return fileType ? fileTypes[fileType].split('/')[0] : 'unknown';
}

function getImageSize(file) {
  const img = new Image();
  img.onload = function() {
    const width = img.width;
    const height = img.height;
    console.log('Image size: ', width, ' x ', height);
  }
  img.src = URL.createObjectURL(file);
}

上面的代碼首先使用FileReader讀取上傳的文件,并將文件內(nèi)容轉(zhuǎn)換為Uint8Array類型。然后,它將文件內(nèi)容的前6個字節(jié)轉(zhuǎn)換為十六進(jìn)制字符串,并使用該字符串獲取文件類型。如果文件類型不是圖片,則彈出警告消息并返回。

如果文件類型是圖片,則使用Image對象獲取圖片的寬度和高度。在getImageSize函數(shù)中,我們創(chuàng)建一個Image對象,并將其src屬性設(shè)置為URL.createObjectURL(file)以加載文件內(nèi)容。當(dāng)圖像加載完成時,它將觸發(fā)onload事件處理程序,該處理程序?qū)@取圖像的寬度和高度。

要使用FileReader獲取音頻或視頻文件的時長,需要通過FileReader讀取文件并將其轉(zhuǎn)換為Blob對象,然后將Blob對象傳遞給一個新創(chuàng)建的HTML5音頻或視頻元素。

以下是一個獲取音頻或視頻文件時長的示例代碼:

<input type="file" id="fileInput" onchange="getDuration(event)">
<script>
function getDuration(event) {
  const file = event.target.files[0];
  const reader = new FileReader();
  reader.onload = function() {
    const blob = new Blob([reader.result], { type: file.type });
    const mediaElement = document.createElement(file.type.startsWith('audio') ? 'audio' : 'video');
    mediaElement.onloadedmetadata = function() {
      console.log('Duration:', mediaElement.duration);
    }
    mediaElement.src = URL.createObjectURL(blob);
  }
  reader.readAsArrayBuffer(file);
}
</script>

上面的代碼中,我們首先通過FileReader讀取用戶選擇的文件,并將其轉(zhuǎn)換為Blob對象。我們還創(chuàng)建了一個新的HTML5音頻或視頻元素,具體取決于文件的MIME類型。然后我們?yōu)樵撛氐膐nloadedmetadata事件處理程序設(shè)置一個函數(shù),該函數(shù)在元數(shù)據(jù)加載完成后將打印出元素的duration屬性值,即音頻或視頻文件的時長。

最后,我們將Blob對象的URL分配給mediaElement的src屬性,以便瀏覽器可以加載媒體文件。在元數(shù)據(jù)加載完成后,它將自動調(diào)用onloadedmetadata事件處理程序,我們將在這里獲取音頻或視頻文件的時長。

要同步獲取音頻或視頻文件的時長,您可以使用HTML5中的MediaMetadata API。MediaMetadata API是一個新的API,用于獲取媒體文件的元數(shù)據(jù),其中包括媒體文件的時長。

以下是一個使用MediaMetadata API同步獲取音頻或視頻文件時長的示例代碼:

<input type="file" id="fileInput" onchange="getDuration(event)">
<script>
async function getDuration(event) {
  const file = event.target.files[0];
  const reader = new FileReader();
  reader.onload = async function() {
    const blob = new Blob([reader.result], { type: file.type });
    const mediaElement = document.createElement(file.type.startsWith('audio') ? 'audio' : 'video');
    mediaElement.src = URL.createObjectURL(blob);
    await mediaElement.play();
    const metadata = mediaElement.getMetadata();
    console.log('Duration:', metadata.duration);
  }
  reader.readAsArrayBuffer(file);
}
</script>

上面的代碼中,我們首先通過FileReader讀取用戶選擇的文件,并將其轉(zhuǎn)換為Blob對象。我們還創(chuàng)建了一個新的HTML5音頻或視頻元素,具體取決于文件的MIME類型。然后我們將Blob對象的URL分配給mediaElement的src屬性,以便瀏覽器可以加載媒體文件。

在文件加載完成后,我們使用MediaMetadata API中的play()方法開始播放媒體文件。由于該方法返回一個promise,因此我們使用await關(guān)鍵字等待該promise完成。在媒體文件播放期間,MediaMetadata API會自動獲取媒體文件的元數(shù)據(jù),其中包括媒體文件的時長。最后,我們可以使用getMetadata()方法獲取元數(shù)據(jù),并打印出音頻或視頻文件的時長。

請注意,MediaMetadata API目前不受所有瀏覽器的支持,因此在使用它時請務(wù)必檢查瀏覽器兼容性。

要在FileReader獲取完圖片長寬后執(zhí)行后續(xù)語句,您可以將后續(xù)語句放在FileReader的onload事件處理程序中。

onload事件處理程序會在文件讀取完成后立即執(zhí)行,因此您可以在其中獲取圖片的長寬,并執(zhí)行后續(xù)語句。

以下是一個示例代碼:

<input type="file" id="fileInput" onchange="getImageSize(event)">
<script>
function getImageSize(event) {
  const file = event.target.files[0];
  const reader = new FileReader();
  reader.onload = function() {
    const image = new Image();
    image.onload = function() {
      const width = this.width;
      const height = this.height;
      console.log('Image size:', width, height);
      // 執(zhí)行后續(xù)語句
    }
    image.src = reader.result;
  }
  reader.readAsDataURL(file);
}
</script>

上面的代碼中,我們首先通過FileReader讀取用戶選擇的文件,并將其轉(zhuǎn)換為數(shù)據(jù)URL。然后,我們創(chuàng)建了一個新的Image對象,并在其onload事件處理程序中獲取圖像的寬度和高度。最后,我們將數(shù)據(jù)URL分配給圖像對象的src屬性,以便瀏覽器可以加載圖像文件。

當(dāng)圖像加載完成后,onload事件處理程序?qū)?zhí)行,并打印出圖像的寬度和高度。您可以在此處添加后續(xù)語句來執(zhí)行您需要在獲取圖像大小后執(zhí)行的任何操作。

如果您需要在FileReader獲取完圖片長寬后執(zhí)行的后續(xù)語句不在onload事件處理程序內(nèi)部執(zhí)行,而是在onload事件處理程序之后執(zhí)行,您可以將這些后續(xù)語句封裝到一個函數(shù)中,并在onload事件處理程序中調(diào)用該函數(shù),如下所示: 

<input type="file" id="fileInput" onchange="getImageSize(event)">
<script>
function getImageSize(event) {
  const file = event.target.files[0];
  const reader = new FileReader();
  reader.onload = function() {
    const image = new Image();
    image.onload = function() {
      const width = this.width;
      const height = this.height;
      console.log('Image size:', width, height);
      handleImageSize(width, height); // 調(diào)用后續(xù)處理函數(shù)
    }
    image.src = reader.result;
  }
  reader.readAsDataURL(file);
}

function handleImageSize(width, height) {
  // 在這里執(zhí)行需要在獲取圖像大小后執(zhí)行的操作
  console.log('Image size is ready');
}
</script>

在上面的代碼中,我們將后續(xù)語句封裝到名為handleImageSize的函數(shù)中,并在圖像的onload事件處理程序中調(diào)用它。由于onload事件處理程序是異步的,因此可以在圖像加載完成后執(zhí)行后續(xù)語句。

當(dāng)onload事件處理程序完成后,將調(diào)用handleImageSize函數(shù),并在其中執(zhí)行需要在獲取圖像大小后執(zhí)行的操作。在這個例子中,我們只是簡單地在控制臺輸出了一條消息。

請注意,如果您需要在多個onload事件處理程序中執(zhí)行后續(xù)語句,則必須確保它們是按照正確的順序執(zhí)行的。否則可能會導(dǎo)致錯誤的行為。

您也可以使用async/await來處理FileReader獲取圖片長寬的異步操作。

下面是一個示例代碼,使用async/await在獲取圖片大小后執(zhí)行后續(xù)操作:

async function getImageSize(file) {
  const reader = new FileReader();
  reader.readAsDataURL(file);

  await new Promise((resolve, reject) => {
    reader.onload = resolve;
    reader.onerror = reject;
  });

  const image = new Image();
  image.src = reader.result;

  await new Promise((resolve, reject) => {
    image.onload = resolve;
    image.onerror = reject;
  });

  const width = image.width;
  const height = image.height;
  console.log('Image size:', width, height);

  // 執(zhí)行后續(xù)操作
}

在上面的代碼中,我們首先將FileReader對象讀取的數(shù)據(jù)轉(zhuǎn)換為數(shù)據(jù)URL,并使用Promise等待讀取操作完成。然后,我們創(chuàng)建了一個新的Image對象,并使用Promise等待圖像加載完成。最后,我們獲取圖像的寬度和高度,并執(zhí)行需要在獲取圖像大小后執(zhí)行的操作。

請注意,async/await在這里用于等待異步操作完成,并在操作完成后執(zhí)行后續(xù)語句。這個示例代碼中的getImageSize函數(shù)是一個異步函數(shù),可以使用await等待異步操作完成。

如果您需要在多個onload事件處理程序中執(zhí)行后續(xù)語句,則必須使用Promise等待這些異步操作完成,并確保它們是按照正確的順序執(zhí)行的。否則可能會導(dǎo)致錯誤的行為。

您可以使用async/awaitFileReader對象的readAsArrayBuffer方法來獲取文件類型。

下面是一個示例代碼,使用async/await同步獲取文件類型:

async function getFileType(file) {
  const reader = new FileReader();
  reader.readAsArrayBuffer(file.slice(0, 4));

  await new Promise((resolve, reject) => {
    reader.onload = resolve;
    reader.onerror = reject;
  });

  const buffer = reader.result;
  const view = new DataView(buffer);
  const type = view.getUint32(0, false);

  switch(type) {
    case 0x89504E47:
      return 'image/png';
    case 0xFFD8FFE0:
    case 0xFFD8FFE1:
    case 0xFFD8FFE2:
      return 'image/jpeg';
    case 0x47494638:
      return 'image/gif';
    case 0x49443303:
      return 'audio/mp3';
    case 0x57415645:
      return 'audio/wav';
    case 0x4D546864:
      return 'audio/midi';
    case 0x666F6D73:
      return 'video/quicktime';
    case 0x3026B275:
      return 'video/wmv';
    case 0x464C5601:
      return 'video/flv';
    default:
      return 'unknown';
  }
}

在上面的代碼中,我們使用FileReader對象的readAsArrayBuffer方法讀取文件的前4個字節(jié),并使用DataView對象讀取文件類型。然后,我們使用switch語句判斷文件類型,并返回對應(yīng)的 MIME 類型。

請注意,await用于等待異步操作完成,并在操作完成后執(zhí)行后續(xù)語句。getFileType函數(shù)是一個異步函數(shù),可以使用await等待異步操作完成。

最后,我們可以在需要獲取文件類型的地方調(diào)用該函數(shù),如下所示:

const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', async function() {
  const file = fileInput.files[0];
  const fileType = await getFileType(file);
  console.log('File type:', fileType);
  // 執(zhí)行后續(xù)操作
});

 在上面的代碼中,我們監(jiān)聽文件選擇器的change事件,并在事件處理程序中調(diào)用getFileType函數(shù),等待獲取文件類型,并執(zhí)行需要在獲取文件類型后執(zhí)行的后續(xù)操作。

您可以使用async/awaitFileReader對象的readAsDataURL方法來判斷是否是圖片,并獲取圖片的寬高。

下面是一個示例代碼,使用async/await判斷是否是圖片,并獲取圖片的寬高:

async function getImageWidthAndHeight(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();

    reader.onload = async function(e) {
      const image = new Image();
      image.src = e.target.result;

      image.onload = function() {
        resolve({ width: this.width, height: this.height });
      };
      image.onerror = reject;
    };

    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}

在上面的代碼中,我們使用FileReader對象的readAsDataURL方法將文件讀取為一個data:URL,并使用Image對象的onload事件獲取圖片的寬高。如果讀取文件或加載圖片時出現(xiàn)錯誤,則使用onerror事件返回錯誤。

請注意,await用于等待異步操作完成,并在操作完成后執(zhí)行后續(xù)語句。getImageWidthAndHeight函數(shù)是一個異步函數(shù),可以使用await等待異步操作完成。

最后,我們可以在需要獲取圖片寬高的地方調(diào)用該函數(shù),如下所示:

const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', async function() {
  const file = fileInput.files[0];
  const fileType = await getFileType(file);
  if (fileType.startsWith('image/')) {
    const { width, height } = await getImageWidthAndHeight(file);
    console.log('Image width:', width, 'height:', height);
    // 執(zhí)行后續(xù)操作
  } else {
    console.log('Not an image file');
  }
});

 在上面的代碼中,我們先使用getFileType函數(shù)判斷文件是否為圖片,如果是圖片,則使用getImageWidthAndHeight函數(shù)獲取圖片的寬高,并執(zhí)行需要在獲取圖片寬高后執(zhí)行的后續(xù)操作。如果不是圖片,則打印錯誤信息。

可以使用JavaScript中的數(shù)學(xué)運(yùn)算和字符串操作來將時長從小數(shù)形式轉(zhuǎn)換為時分秒形式。下面是一種實(shí)現(xiàn)方法:

// 定義時長為134.73913秒
const durationInSeconds = 134.73913;

// 計算小時、分鐘和秒數(shù)
const hours = Math.floor(durationInSeconds / 3600);
const minutes = Math.floor((durationInSeconds - (hours * 3600)) / 60);
const seconds = Math.floor(durationInSeconds - (hours * 3600) - (minutes * 60));

// 格式化輸出
const formattedDuration = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
console.log(formattedDuration); // 輸出 00:02:14

 這段代碼首先將時長定義為134.73913秒。然后使用數(shù)學(xué)運(yùn)算計算出時、分、秒數(shù)。最后使用字符串操作將時、分、秒數(shù)格式化成時分秒形式,并輸出到控制臺。輸出結(jié)果為 00:02:14,表示時長為2分14秒。

使用 FileReader 和 async/await 可以異步讀取文件并獲取文件類型。下面是一個例子:

async function getFileType(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = function() {
      const arr = (new Uint8Array(reader.result)).subarray(0, 4);
      let header = '';
      for(let i = 0; i < arr.length; i++) {
        header += arr[i].toString(16);
      }
      switch (header) {
        case '89504e47':
          resolve('image/png');
          break;
        case '47494638':
          resolve('image/gif');
          break;
        case 'ffd8ffe0':
        case 'ffd8ffe1':
        case 'ffd8ffe2':
          resolve('image/jpeg');
          break;
        default:
          resolve('unknown');
          break;
      }
    };
    reader.readAsArrayBuffer(file);
  });
}

這段代碼定義了一個 getFileType 函數(shù),接受一個 File 對象作為參數(shù),并返回一個 Promise 對象。在函數(shù)內(nèi)部,我們創(chuàng)建了一個 FileReader 對象,并設(shè)置了它的 onload 事件處理程序,以便在文件讀取完成后獲取文件類型。我們使用 Uint8Array 數(shù)組讀取文件的前4個字節(jié),將其轉(zhuǎn)換為16進(jìn)制字符串,并根據(jù)特定的字節(jié)碼匹配文件類型。最后,我們使用 Promise 的 resolve 方法返回文件類型。

使用該函數(shù)的例子:

async function test() {
  const file = new File(['test'], 'test.png', {type: 'image/png'});
  const fileType = await getFileType(file);
  console.log(fileType); // 輸出 'image/png'
}
test();

 在這個例子中,我們創(chuàng)建了一個假的 File 對象,將其類型設(shè)置為 'image/png',并將其作為參數(shù)傳遞給 getFileType 函數(shù)。通過 await 關(guān)鍵字等待函數(shù)的結(jié)果,獲取文件類型,并輸出到控制臺。輸出結(jié)果為 'image/png',表示文件的類型為 PNG 圖像。

可以通過文件的擴(kuò)展名或者文件頭信息(即文件的開頭幾個字節(jié))來判斷文件類型。下面是一個簡單的判斷圖片、視頻和音頻文件類型的例子:

function getFileType(file) {
  // 獲取文件名和擴(kuò)展名
  const fileName = file.name;
  const extension = fileName.slice((fileName.lastIndexOf('.') - 1 >>> 0) + 2).toLowerCase();
  
  // 根據(jù)擴(kuò)展名判斷文件類型
  switch (extension) {
    case 'jpg':
    case 'jpeg':
    case 'png':
    case 'gif':
    case 'bmp':
      return 'image';
    case 'mp4':
    case 'avi':
    case 'wmv':
    case 'mov':
    case 'flv':
      return 'video';
    case 'mp3':
    case 'wav':
    case 'ogg':
      return 'audio';
    default:
      return 'unknown';
  }
}

在這個例子中,我們定義了一個 getFileType 函數(shù),接受一個 File 對象作為參數(shù),并返回一個字符串,表示文件的類型。在函數(shù)內(nèi)部,我們先通過文件名獲取文件的擴(kuò)展名,并將其轉(zhuǎn)換為小寫字母。然后根據(jù)擴(kuò)展名判斷文件類型,返回對應(yīng)的字符串。如果擴(kuò)展名無法識別,返回 'unknown'。

注意,這種方式只是簡單的根據(jù)擴(kuò)展名來判斷文件類型,有些文件可能沒有擴(kuò)展名,或者擴(kuò)展名被篡改,此時就無法正確判斷文件類型。為了更準(zhǔn)確地判斷文件類型,我們可以通過讀取文件頭信息來獲取更詳細(xì)的信息。前面提到的 getFileType 函數(shù)可以改寫成異步函數(shù),并通過 FileReader 對象讀取文件頭信息來判斷文件類型,示例代碼如下:

async function getFileType(file) {
  const reader = new FileReader();
  reader.readAsArrayBuffer(file.slice(0, 4));
  return new Promise(resolve => {
    reader.onload = () => {
      const buffer = reader.result;
      const uint8Array = new Uint8Array(buffer);
      let header = '';
      for (let i = 0; i < uint8Array.length; i++) {
        header += uint8Array[i].toString(16);
      }
      switch (header) {
        case '89504e47':
          resolve('image/png');
          break;
        case '47494638':
          resolve('image/gif');
          break;
        case 'ffd8ffe0':
        case 'ffd8ffe1':
        case 'ffd8ffe2':
          resolve('image/jpeg');
          break;
        case '494433':
          resolve('audio/mp3');
          break;
        case '524946':
          resolve('audio/wav');
          break;
        case '4f676753':
          resolve('audio/ogg');
          break;
        case '66747970':
          resolve('video/mp4');
          break;
        case '774d5634':
          resolve('video/webm');
          break;
        case '00018':
          resolve('video/mov');
          break;
        default:
          resolve('unknown');
          break;
      }
    };
  });
}

 在這個例子中,我們定義了一個異步函數(shù) getFileType,接受一個 File 對象作為參數(shù),并返回一個 Promise 對象,最終返回一個字符串,表示文件的類型。在函數(shù)內(nèi)部,我們先創(chuàng)建一個 FileReader 對象,并通過 readAsArrayBuffer 方法讀取文件的前四個字節(jié)(也就是文件頭信息)。然后在 onload 回調(diào)函數(shù)中,將讀取的字節(jié)轉(zhuǎn)換為 16 進(jìn)制字符串,并根據(jù)不同的字符串值判斷文件類型,返回對應(yīng)的 MIME 類型。如果無法識別文件類型,返回 'unknown'。

注意,這種方式雖然可以更準(zhǔn)確地判斷文件類型,但也有一些局限性。不同的文件格式可能有不同的文件頭信息,如果要判斷所有的文件類型,需要處理大量的情況,代碼會比較復(fù)雜。而且有些文件頭信息也可能被篡改,此時也無法正確判斷文件類型。所以在實(shí)際應(yīng)用中,需要根據(jù)具體的需求和情況來選擇合適的方式來判斷文件類型。

總結(jié)

到此這篇關(guān)于Js中FileReader讀取文件內(nèi)容方法的文章就介紹到這了,更多相關(guān)Js FileReader讀取文件內(nèi)容方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論