<!doctypehtml><html lang=en><meta charset=utf-8><meta content=width=device-width,initial-scale=1 name=viewport><style>@keyframes unsupported-appear{0%,to{visibility:hidden}}@keyframes hold-visibility{0%,to{visibility:visible}}@keyframes loading-progress-before{0%{transform:translate(-50%)}to{transform:translate(100vw) translate(-50%)}}@keyframes equalizer-morph{0%{transform:scaleY(1)}25%{transform:scaleY(.3)}50%{transform:scaleY(.7)}75%{transform:scaleY(.15)}}.overflow-hidden{overflow:hidden}*,::after,::before{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}:focus{outline:1px solid #3740ff}.w-force-focus{outline:0!important}div,form,li,ol,ul{margin:0;padding:0}input,q{hyphens:none}code,input,q{-moz-hyphens:none;-webkit-hyphens:none}:not([href])[id]::before{content:" ";display:block;height:calc(64px + 1.5rem);margin-top:calc(-64px - 1.5rem);pointer-events:none;visibility:hidden}:root{--flow-space:1em}body,html{font:400 12px/1.5 Segoe UI,system-ui,-apple-system,sans-serif;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;text-rendering:optimizeSpeed;margin:0;overflow-wrap:break-word;padding:0;word-wrap:break-word}@media (min-width:241px){body,html{font:400 14px/1.5 Segoe UI,system-ui,-apple-system,sans-serif}}@media (min-width:321px){body,html{font:400 16px/1.5 Segoe UI,system-ui,-apple-system,sans-serif}}h1,h2,h3{color:#202124;margin:0;overflow:visible}h3,h4{font:500 13.5px/1.4814814815 "Google Sans",sans-serif}h4{margin:0;overflow:visible;margin-top:24px;margin-bottom:6px;color:#5f6368}h1{font:500 38px/1.3157894737 "Google Sans",sans-serif;letter-spacing:-.5px;margin-top:0;margin-bottom:9px}@media (min-width:241px){h1{font:500 49px/1.3265306122 "Google Sans",sans-serif;letter-spacing:-.5px;margin-top:0;margin-bottom:10px}}@media (min-width:321px){h1{font:500 56px/1.3214285714 "Google Sans",sans-serif;letter-spacing:-.5px;margin-top:0;margin-bottom:11px}}h2{font:400 18px/1.3333333333 "Google Sans",sans-serif;margin-top:48px;margin-bottom:24px}@media (min-width:241px){h2{font:400 21px/1.3333333333 "Google Sans",sans-serif;margin-top:56px;margin-bottom:28px}}@media (min-width:321px){h2{font:400 24px/1.3333333333 "Google Sans",sans-serif;margin-top:64px;margin-bottom:32px}}h3{margin-top:36px;margin-bottom:12px}@media (min-width:241px){h3{font:500 16px/1.375 "Google Sans",sans-serif;margin-top:42px;margin-bottom:14px}}@media (min-width:321px){h3{font:500 20px/1.2 "Google Sans",sans-serif;margin-top:48px;margin-bottom:16px}}@media (min-width:241px){h4{font:500 16px/.9375 "Google Sans",sans-serif;margin-top:28px;margin-bottom:7px}}@media (min-width:321px){h4{font:500 19px/1.0526315789 "Google Sans",sans-serif;margin-top:32px;margin-bottom:10px}}p{font:400 13.5px/1.5555555556 Segoe UI,system-ui,-apple-system,sans-serif;margin-top:27px;margin-bottom:27px}@media (min-width:241px){p{font:400 15px/1.8666666667 Segoe UI,system-ui,-apple-system,sans-serif;margin-top:31.5px;margin-bottom:31.5px}}@media (min-width:321px){p{font:400 18px/1.7777777778 Segoe UI,system-ui,-apple-system,sans-serif;margin-top:36px;margin-bottom:36px}}h1+*,h1+[class],h2+*,h2+[class],h3+*,h3+[class],h4+*,h4+[class]{margin-top:0}cite,em{font-style:italic}strong{font-weight:500}main{padding-bottom:64px}@media print{main{padding-bottom:0}}img{-ms-interpolation-mode:bicubic;display:inline-block;height:auto;max-width:100%;vertical-align:middle}input[type=email],input[type=text]{border:1px solid #dadce0;font:inherit;font-size:inherit;padding:14px 8px;width:100%}input[type=email]:focus,input[type=text]:focus{border-color:#3740ff;outline:0}input[type=radio]{-moz-appearance:none;-webkit-appearance:none;appearance:none;border:2px solid #dadce0;border-radius:50%;cursor:pointer;flex-shrink:0;height:24px;margin:2px;width:24px}input[type=radio]:checked{background-clip:content-box;background-color:#3740ff;border:2px solid #3740ff;padding:4px}a{color:#3740ff;text-decoration:none}a:active,a:focus,a:hover{text-decoration:underline}a:active,a:focus{outline:1px solid #3740ff}.w-post-content :link,.w-post-content :visited,.w-post-content a{text-decoration:underline}.w-post-content :link:active,.w-post-content :link:focus,.w-post-content :link:hover,.w-post-content :visited:active,.w-post-content :visited:focus,.w-post-content :visited:hover,.w-post-content a:active,.w-post-content a:focus,.w-post-content a:hover{text-decoration:none}p :link:active,p :visited:active,p a:active{background-color:rgba(55,64,255,.16)}a code{color:#3740ff}ol:not([class]),ul:not([class]){list-style:none;margin:32px 0;position:relative}ol:not([class]){counter-reset:ol-step-counter;padding-left:32px}ol:not([class])>li{counter-increment:ol-step-counter}ol:not([class])>li::before,ul:not([class])>li::before{background:#5f6368;border-radius:50%;color:#fff;left:0;position:absolute}ol:not([class])>li::before{-ms-flex-align:center;-ms-flex-negative:0;-ms-flex-pack:center;-webkit-box-align:center;-webkit-box-pack:center;align-items:center;content:counter(ol-step-counter);display:-ms-inline-flexbox;display:-webkit-inline-box;display:inline-flex;flex-shrink:0;font-size:.75em;height:20px;justify-content:center;margin:6px 0 0;width:20px}ul:not([class]){padding-left:24px}ol:not([class])>li,ul:not([class])>li{font-size:1.125rem;line-height:1.778rem;margin-bottom:8px}ul:not([class])>li::before{content:"";height:8px;margin:12px 0 0;width:8px}li>ol:not([class]),li>ul:not([class]),ol:not([class])>li>p,ul:not([class])>li>p{margin:8px 0}ol:not([class])>li>p:first-child,table ol:not([class]):first-child,table ul:not([class]):first-child,ul:not([class])>li>p:first-child{margin-top:0}ol:not([class])>li>p:last-child,table ol:not([class]):last-child,table ul:not([class]):last-child,ul:not([class])>li>p:last-child{margin-bottom:0}select{-moz-appearance:none;-webkit-appearance:none;appearance:none;background-color:#fff;background-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M7 10L12 15L17 10H7Z' fill='%235F6368'/%3E%3C/svg%3E%0A");background-position:right .5em top 50%;background-repeat:no-repeat;background-size:1.5em;border-radius:1px;border:1px solid #dadce0;box-sizing:border-box;color:inherit;display:block;font-family:inherit;font-size:1em;line-height:1.5;margin:0;max-width:100%;padding:.6em 3em .5em .8em}select::-ms-expand{display:none}select:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}select:hover{border-color:#9aa0a6}select option,table code{font-weight:400}.w-select--borderless{border-color:transparent}.w-select--borderless:hover{border-color:transparent;background-color:#f1f3f4}table{border-collapse:collapse;font-size:inherit;margin:0;min-width:512px;width:100%}table code{background:0 0;border:0;font-size:.9em;line-height:1.7em;margin:0;padding:0}table ol:not([class]),table ul:not([class]){margin:24px 0;padding-left:40px}table ol:not([class]) li,table ul:not([class]) li{font-size:inherit;line-height:inherit}table ul:not([class]) li::before{margin:8px 0 0}table ol:not([class]) li::before{margin:2px 0 0}code{margin:0 .25em;padding:.125em .25em}code,pre{background:#f7f7f7;border:1px solid #dadce0;color:#202124;font:1rem/1.5em SFMono-Regular,Consolas,"Liberation Mono",Menlo,monospace;hyphens:none;tab-size:2;text-align:left;word-spacing:normal}:not(pre)>code{white-space:pre-wrap}pre,pre[class*=language-]{margin:32px -24px;border-width:1px 0;overflow:auto;padding:16px;white-space:pre;scrollbar-color:#80868b transparent;scrollbar-width:thin}pre::-webkit-scrollbar,pre[class*=language-]::-webkit-scrollbar{height:10px;width:10px}pre::-webkit-scrollbar-thumb,pre[class*=language-]::-webkit-scrollbar-thumb{background:#80868b;background-clip:padding-box;border:2.5px solid transparent;border-radius:5px}pre::-webkit-scrollbar-thumb:hover,pre[class*=language-]::-webkit-scrollbar-thumb:hover{background-color:#62676c}pre::-webkit-scrollbar-thumb:active,pre[class*=language-]::-webkit-scrollbar-thumb:active{background-color:#4a4e51}pre::-webkit-scrollbar-track,pre[class*=language-]::-webkit-scrollbar-track{background:0 0}@media (min-width:481px){pre,pre[class*=language-]{margin:32px -32px}}@media (min-width:865px){pre,pre[class*=language-]{margin:32px 0;border-width:1px}}pre code,pre[class*=language-] code{font-size:1em;line-height:1.5em;margin:0;padding:0}pre code{background:0 0;border:0}h1 code,h2 code,h3 code,h4 code{background:0 0;border:0;color:inherit;font-size:inherit;font-style:inherit;margin:0;padding:0;white-space:normal}cite code,figcaption code{font-size:.9em}.token.comment{color:#696969}.token.attr-value,.token.punctuation,.token.string{color:#183691}.token.property,.token.tag{color:#385d34}.token.boolean,.token.number{color:#007aa2}.token.attr-name,.token.attr-value .punctuation:first-child,.token.important,.token.keyword{color:#9f1c59}.token.operator,.token.url{color:#a71d5d}.highlight-line-active,.highlight-line-active *{color:#202124!important;font-weight:500}.highlight-line-active{background-color:#fff59d}video{max-width:100%}@font-face{font-family:"Google Sans";font-style:normal;font-weight:400;font-display:optional;src:local("Google Sans Regular"),local("GoogleSans-Regular"),url(/fonts/google-sans/regular/cyrillic.woff2) format("woff2");unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:"Google Sans";font-style:normal;font-weight:400;font-display:optional;src:local("Google Sans Regular"),local("GoogleSans-Regular"),url(/fonts/google-sans/regular/greek.woff2) format("woff2");unicode-range:U+0370-03FF}@font-face{font-family:"Google Sans";font-style:normal;font-weight:400;font-display:optional;src:local("Google Sans Regular"),local("GoogleSans-Regular"),url(/fonts/google-sans/regular/vietnamese.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:"Google Sans";font-style:normal;font-weight:400;font-display:optional;src:local("Google Sans Regular"),local("GoogleSans-Regular"),url(/fonts/google-sans/regular/latin-ext.woff2) format("woff2");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:"Google Sans";font-style:normal;font-weight:400;font-display:optional;src:local("Google Sans Regular"),local("GoogleSans-Regular"),url(/fonts/google-sans/regular/latin.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:"Google Sans";font-style:normal;font-weight:500;font-display:optional;src:local("Google Sans Medium"),local("GoogleSans-Medium"),url(/fonts/google-sans/bold/cyrillic.woff2) format("woff2");unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:"Google Sans";font-style:normal;font-weight:500;font-display:optional;src:local("Google Sans Medium"),local("GoogleSans-Medium"),url(/fonts/google-sans/bold/greek.woff2) format("woff2");unicode-range:U+0370-03FF}@font-face{font-family:"Google Sans";font-style:normal;font-weight:500;font-display:optional;src:local("Google Sans Medium"),local("GoogleSans-Medium"),url(/fonts/google-sans/bold/vietnamese.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:"Google Sans";font-style:normal;font-weight:500;font-display:optional;src:local("Google Sans Medium"),local("GoogleSans-Medium"),url(/fonts/google-sans/bold/latin-ext.woff2) format("woff2");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:"Google Sans";font-style:normal;font-weight:500;font-display:optional;src:local("Google Sans Medium"),local("GoogleSans-Medium"),url(/fonts/google-sans/bold/latin.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:"Material Icons";font-style:normal;font-weight:400;src:url(/fonts/material-icons/regular.woff2) format("woff2")}.flow>*+*{margin-top:var(--flow-space)}.w-toc__content{scrollbar-color:#9aa0a6 transparent;scrollbar-width:thin}.w-toc__content::-webkit-scrollbar{height:6px;width:6px}.w-toc__content::-webkit-scrollbar-thumb{background:#9aa0a6;background-clip:padding-box;border:1.5px solid transparent;border-radius:3px}.w-toc__content::-webkit-scrollbar-thumb:hover{background-color:#798189}.w-toc__content::-webkit-scrollbar-thumb:active{background-color:#61686e}.w-toc__content::-webkit-scrollbar-track{background:0 0}.w-visually-hidden{clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);clip-path:inset(1px);display:block;height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}:root{--list-separator:"·";--list-separator-gap:0.5rem}.w-actions{align-items:flex-end;bottom:24px;display:flex;flex-direction:column;position:fixed;right:24px;z-index:100}@media print{.w-actions{display:none}}.w-actions>*{margin-top:20px}.w-actions__fab{align-items:center;background-color:#3740ff;border:0;border-radius:50%;box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);color:#fff;cursor:pointer;display:inline-flex;font-family:Segoe UI,system-ui,-apple-system,sans-serif;font-size:.875em;font-weight:600;height:56px;letter-spacing:1px;overflow:hidden;padding:0;position:relative;text-indent:-9999px;text-overflow:initial;text-transform:uppercase;width:56px}@media (min-width:1264px){.w-actions__fab{border-radius:28px;padding:0 24px 0 52px;text-indent:0;width:auto}}.w-actions__fab:active,.w-actions__fab:hover{background-color:#3740ff}.w-actions__fab:active{box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}.w-actions__fab:active,.w-actions__fab:focus,.w-actions__fab:hover{outline:0;text-decoration:none}.w-actions__fab::before{background-size:24px 24px;content:"";height:24px;left:16px;position:absolute;top:16px;width:24px}.w-actions__fab::after{bottom:0;content:"";left:0;pointer-events:none;position:absolute;right:0;top:0;transition:background-color .2s,border .2s;z-index:1}.w-actions__fab:hover::after{background-color:rgba(255,255,255,.08)}.w-actions__fab:focus::after{background-color:rgba(255,255,255,.24)}.w-actions__fab:active::after{background-color:rgba(255,255,255,.32)}.w-actions__fab--share::before{background-image:url(/images/icons/share_white.svg)}.w-actions__fab--subscribe{background-color:#fff;color:#3740ff}.w-actions__fab--subscribe:active,.w-actions__fab--subscribe:hover{background-color:#fff}.w-actions__fab--subscribe::before{background-image:url(/images/icons/subscribe.svg)}.w-actions__fab--subscribe:hover::after{background-color:rgba(55,64,255,.04)}.w-actions__fab--subscribe:focus::after{background-color:rgba(55,64,255,.12)}.w-actions__fab--subscribe:active::after{background-color:rgba(55,64,255,.16)}:root{--app-bar-height:64px}.w-article-header{margin:0 0 48px;padding-top:40px}@media (min-width:865px){.w-article-header{margin:0 0 64px;padding-top:56px}}@media print{.w-article-header{margin:0;padding-top:0}}.w-article-header__headline{font-size:27px;font-weight:400;line-height:33px;margin:0 auto 11px}@media (min-width:241px){.w-article-header__headline{font-size:31px;line-height:38px}}@media (min-width:321px){.w-article-header__headline{font-size:36px;line-height:44px}}@media (min-width:865px){.w-article-header__headline{font-size:44px;line-height:52px}}.w-article-header__subhead{font-family:"Google Sans",sans-serif;font-size:16px;line-height:28px;margin:12px auto}@media (min-width:241px){.w-article-header__subhead{font-size:18px;line-height:32px;margin:16px auto}}.w-article-navigation{background-color:#dadce0;display:flex;flex-direction:column;padding:1px 0}@media (min-width:481px){.w-article-navigation{flex-direction:row}}@media print{.w-article-navigation{display:none}}.w-article-navigation__link{align-items:center;background-color:#fff;color:#202124;display:flex;font-family:"Google Sans",sans-serif;position:relative}.w-article-navigation__link:active,.w-article-navigation__link:focus,.w-article-navigation__link:hover{background-color:#fff;outline:0;text-decoration:none}.w-article-navigation__link::before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font:24px/1 "Material Icons";font-feature-settings:"liga";text-rendering:optimizeSpeed;text-transform:none;word-wrap:normal}.w-article-navigation__link::after{bottom:0;content:"";left:0;pointer-events:none;position:absolute;right:0;top:0;transition:background-color .2s,border .2s;z-index:1}.w-article-navigation__link:hover::after{background-color:rgba(32,33,36,.04)}.w-article-navigation__link:focus::after{background-color:rgba(32,33,36,.12)}.w-article-navigation__link:active::after{background-color:rgba(32,33,36,.16)}.w-article-navigation__link--back{flex-basis:33.3%;margin:0 0 1px;padding:32px 32px 32px 80px}@media (min-width:481px){.w-article-navigation__link--back{margin:0 1px 0 0}}.w-article-navigation__link--back::before,.w-aside::after{content:"arrow_back";left:32px;position:absolute}.w-article-navigation__link--single{flex:1;margin:0}@media (min-width:481px){.w-article-navigation__link--single{margin:0}}.w-article-navigation code{background:0 0;border:0;color:inherit;padding:0}.w-aside{font-family:Segoe UI,system-ui,-apple-system,sans-serif;font-size:13.5px;line-height:21px;margin:48px 0 32px;padding:24px 0 0 48px;position:relative}@media (min-width:241px){.w-aside{font-size:15px;line-height:28px}}@media (min-width:321px){.w-aside{font-size:18px;line-height:32px}}.w-aside strong{font-weight:700}.w-aside::after{content:"";height:2px;left:0;right:0;top:0}.w-aside::before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font:24px/1 "Material Icons";font-feature-settings:"liga";text-rendering:optimizeSpeed;text-transform:none;word-wrap:normal;float:left;margin:4px 0 0 -48px}.w-aside--note{color:#3740ff}.w-aside--note::after{background-color:#3740ff}.w-aside--note::before{content:"star"}.w-aside--warning{color:#eb0f00}.w-aside--warning::after{background-color:#eb0f00}.w-aside--warning::before{content:"warning"}.w-aside a,.w-aside code,.w-aside p{color:inherit}.w-aside code{white-space:pre-wrap}.w-aside pre,.w-aside pre code{font-size:.889em;line-height:1.5;white-space:pre}.w-aside a,.w-banner a{text-decoration:underline}.w-aside p{font-family:inherit;letter-spacing:normal;margin:0}.w-aside p+p{margin-top:8px}.w-aside p,.w-aside ul li{font-size:inherit;line-height:inherit}.w-authors{display:flex;flex-wrap:wrap;gap:32px}.w-author{display:flex;padding:8px}.w-author__image{background-color:#dadce0;border-radius:50%;border:2px solid #fff;flex-shrink:0;height:64px;margin:0 12px 0 0;min-width:64px;object-fit:cover;overflow:hidden;width:64px}.w-author__name,.w-author__published{display:block;font-size:14px;font-style:normal}.w-author__name{color:#202124}.w-author__name-link{display:inline-block;color:inherit}.w-author__name-link:focus,.w-author__name-link:hover{text-decoration:none}.w-post-content .w-author__name-link{text-decoration:none}.w-post-content .w-author__name-link:focus,.w-post-content .w-author__name-link:hover{text-decoration:underline}.w-author__published{color:#5f6368}.w-author__separator{padding:0 4px}.w-author__link,web-event-schedule{display:block}.w-author__link-list{display:flex;flex-wrap:wrap;list-style:none;overflow:hidden;margin-top:9px}.w-author__link-listitem{font-size:14px;display:flex}.w-author__link-listitem+.w-author__link-listitem::before{content:"·";display:block;margin:0 4px}.w-author__link:focus{box-shadow:inset 0 0 0 1px #3740ff;outline:0}.w-banner{display:none;font-size:.889rem}@media (min-width:481px){.w-banner{display:block;padding:24px 32px}}@media (min-width:865px){.w-banner{padding:24px 64px}}.w-banner--info{background:#c8e6c9}.w-breadcrumbs,.w-breadcrumbs__crumb{align-items:center;display:flex;min-width:0}.w-breadcrumbs{margin:0;padding:0}.w-breadcrumbs__crumb{font-size:.875rem}.w-breadcrumbs__icon{width:1.1rem;height:1.1rem;fill:#5f6368}.w-breadcrumbs__crumb:not(:last-of-type){flex-shrink:0}.w-breadcrumbs__crumb:last-of-type>a{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.w-breadcrumbs__link{color:#5f6368;padding:0 8px}.w-breadcrumbs__link--left-justify{margin-left:-8px}.w-button{-webkit-tap-highlight-color:transparent;align-items:center;background:0 0;border:0;border-radius:3px;color:#3740ff;cursor:pointer;display:inline-flex;font:500 .875rem/2.25rem Segoe UI,system-ui,-apple-system,sans-serif;height:56px;justify-content:center;letter-spacing:1px;outline:0;padding:0 16px;text-decoration:none;text-transform:uppercase;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;text-rendering:optimizeSpeed;overflow:hidden;position:relative;transition:background-color .2s,box-shadow .2s;vertical-align:middle;white-space:nowrap}.w-button::-moz-focus-inner{border:0}@media (hover:hover){.w-button:focus,.w-button:hover{background:#fff;box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);outline:0;text-decoration:none}}.w-button:active{background:#fff;box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);outline:0;text-decoration:none}.w-button:focus{outline:1px solid rgba(55,64,255,.8);outline-offset:-3px}.w-button[disabled]{background:#dadce0;box-shadow:none;color:rgba(0,0,0,.26);cursor:default;pointer-events:none}.w-button::after{bottom:0;content:"";left:0;pointer-events:none;position:absolute;right:0;top:0;transition:background-color .2s,border .2s;z-index:1}@media (hover:hover){.w-button:hover::after{background-color:rgba(55,64,255,.04)}.w-button:focus::after{background-color:rgba(55,64,255,.12)}}.w-button:active::after{background-color:rgba(55,64,255,.16)}.w-button--primary,.w-button--primary:active,.w-button--primary:focus,.w-button--primary:hover{background-color:#3740ff;color:#fff}@media (hover:hover){.w-button--primary:hover::after{background-color:rgba(255,255,255,.08)}.w-button--primary:focus::after{background-color:rgba(255,255,255,.24)}}.w-button--primary:active::after{background-color:rgba(255,255,255,.32)}.w-button--primary:focus{outline:1px solid rgba(255,255,255,.8)}.w-button--secondary,.w-button--secondary:active,.w-button--secondary:focus,.w-button--secondary:hover{background-color:#fff;border:1px solid #dadce0;color:#202124}@media (hover:hover){.w-button--secondary:hover::after{background-color:rgba(0,0,0,.04)}.w-button--secondary:focus::after{background-color:rgba(0,0,0,.08)}}.w-button--secondary:active::after{background-color:rgba(0,0,0,.1)}.w-button--secondary:focus{outline:1px solid rgba(32,33,36,.6)}.w-button--icon,.w-button--svg{-webkit-tap-highlight-color:transparent;align-items:center;background:0 0;border:0;border-radius:3px;cursor:pointer;display:inline-flex;font:500 .875rem/2.25rem Segoe UI,system-ui,-apple-system,sans-serif;height:56px;justify-content:center;letter-spacing:1px;outline:0;position:relative;text-decoration:none;text-transform:uppercase;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;text-rendering:optimizeSpeed;color:#5f6368;height:3rem;overflow:unset;padding:0;transition:background .2s ease,color .2s ease;width:3rem}@media (hover:hover){.w-button--icon:focus,.w-button--icon:hover,.w-button--svg:focus,.w-button--svg:hover{background:#f1f3f4;color:#202124}}.w-button--icon:active,.w-button--svg:active{background:#e8eaed}.w-button--icon:focus,.w-button--svg:focus{box-shadow:0 0 0 1px #3740ff;outline:0}.w-button--round{border-radius:50%}.w-button--icon::before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font:24px/1 "Material Icons";font-feature-settings:"liga";text-rendering:optimizeSpeed;text-transform:none;word-wrap:normal;content:attr(data-icon);display:inline-block;height:24px;speak:never;width:24px;margin:0}.button{appearance:none;border:0;background:0 0;padding:0}.w-chips{display:flex;flex-flow:row wrap}.w-chip,.w-post-content .w-chip{background-color:transparent;border:1px solid rgba(32,33,36,.16);border-radius:20px;box-sizing:border-box;color:#202124;display:block;font:inherit;font-size:14px;height:32px;line-height:30px;margin:0 8px 12px 0;overflow:hidden;padding:0 12px;text-decoration:none;transition:background-color .2s,border .2s}.w-chip:active,.w-chip:focus,.w-chip:hover,.w-post-content .w-chip:active,.w-post-content .w-chip:focus,.w-post-content .w-chip:hover{outline:0;text-decoration:none}.w-chip:hover,.w-post-content .w-chip:hover{background-color:rgba(32,33,36,.04);border:1px solid rgba(32,33,36,.2)}.w-chip:focus,.w-post-content .w-chip:focus{background-color:rgba(32,33,36,.12);border:1px solid rgba(32,33,36,.28)}.w-chip:active,.w-post-content .w-chip:active{box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}.w-chip.w-chip__active,.w-chip:active,.w-post-content .w-chip.w-chip__active,.w-post-content .w-chip:active{background-color:rgba(0,0,0,.16);border:1px solid rgba(32,33,36,.43)}.w-callout__header{padding-bottom:1rem}.w-callout__lockup{font:500 13.5px/1.4814814815 "Google Sans",sans-serif;margin-top:36px;margin-bottom:12px;display:inline-flex;margin:0 0 .75rem!important}@media (min-width:241px){.w-callout__lockup{font:500 16px/1.375 "Google Sans",sans-serif;margin-top:42px;margin-bottom:14px}}@media (min-width:321px){.w-callout__lockup{font:500 20px/1.2 "Google Sans",sans-serif;margin-top:48px;margin-bottom:16px}}.w-callout__lockup::before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font:24px/1 "Material Icons";font-feature-settings:"liga";text-rendering:optimizeSpeed;text-transform:none;word-wrap:normal;display:inline-block;font-size:20px;margin:0 8px 0 0}.w-callout__blurb{margin:0}.w-details{border:1px solid #dadce0;border-width:1px 0;margin:36px 0;padding:18px 0;position:relative}.w-details+.w-details{border-top:0;margin-top:-36px}.w-details__summary{-webkit-tap-highlight-color:transparent;cursor:pointer;font:inherit;list-style:none}.w-details__summary::marker{display:none}.w-details__summary:focus{outline:0}@media (hover:hover){.w-details__summary:focus .w-details__header::after,.w-details__summary:hover .w-details__header::after{background:#e7e8ff}}.w-details__summary:focus .w-details__header::after{box-shadow:0 0 0 1px #3740ff}.w-details__summary:active .w-details__header::after{background:#c3c6ff}.w-details__header{color:#3740ff;margin:0;padding:.75rem 40px .75rem 0;position:relative}.w-details__header::after{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font:24px/1 "Material Icons";font-feature-settings:"liga";text-rendering:optimizeSpeed;text-transform:none;word-wrap:normal;border-radius:50%;content:"expand_more";cursor:pointer;font-size:24px;padding:2px;position:absolute;right:1px;speak:never;top:50%;transform:translateY(-50%);transition:background .2s;visibility:visible}@media (min-width:321px){.w-details__header{padding:1.125em 48px 1.125em 0}.w-details__header::after{padding:.25em}}.w-details[open] .w-details__header::after{transform:rotate(180deg) translateY(50%)}.w-details__header:only-child{line-height:1.5rem;padding:.375rem 40px .375rem 0}h2.w-details__header:only-child{line-height:1.3333em;padding:.75rem 40px .75rem 0}.w-details>p:first-of-type{margin-top:0}.drawer-default__contents{background:#fff;display:flex;flex-direction:column;height:100vh;width:268px;max-width:90vw}.drawer-default__header{align-items:center;display:flex;padding:16px;border-bottom:1px solid #dadce0}.drawer-default__hide{height:2.75rem;margin:0 10px 0 -6px;width:2.75rem;color:#5f6368}.drawer-default__link{border-bottom:1px solid #dadce0;color:#5f6368;font-size:14px;font-weight:500;padding:16px 24px}.drawer-default__link[active]{-webkit-box-shadow:0 -2px 0 #3740ff inset;box-shadow:0 -2px 0 #3740ff inset}.drawer-default__link:active,.drawer-default__link:focus,.drawer-default__link:hover{text-decoration:none;outline:0}.drawer-default__link:hover{background-color:rgba(32,33,36,.04)}.drawer-default__link:focus{background-color:rgba(32,33,36,.12)}.drawer-default__link:active{background-color:rgba(32,33,36,.16)}.w-footer{border-top:1px solid #dadce0}@media print{.w-footer{display:none}}.w-footer__license{padding-top:32px;width:100%}.w-footer__license p{font-size:.75rem;margin:0;max-width:960px}.w-footer__linkboxes{background:#fff;display:block;font:400 14px/16px Segoe UI,system-ui,-apple-system,sans-serif}.w-footer__linkboxes-list{display:block;list-style:none;padding:24px 0}@media (min-width:865px){.w-footer__linkboxes-list{display:flex;padding:24px 12px 0}}.w-footer__linkbox{flex-grow:1;padding:0 16px 24px}@media (min-width:865px){.w-footer__linkbox{flex:1;margin:0}}.w-footer__linkbox:last-of-type{padding:0 16px}.w-footer__linkbox-heading{font:500 14px/16px Segoe UI,system-ui,-apple-system,sans-serif;margin:0 0 8px}.w-footer__linkbox-list{list-style-type:none;padding:0}.w-footer__linkbox-item{margin:0}.w-footer__linkbox-link{color:#202124;display:block;padding:16px 0}.w-footer__linkbox-link:focus,.w-footer__linkbox-link:hover,.w-footer__utility-link:focus,.w-footer__utility-link:hover{color:#3740ff;text-decoration:none}.w-footer__utility{background:#fff;display:block}.w-footer__utility-nav{border-top:1px solid #ddd;display:block;font:400 14px/16px Segoe UI,system-ui,-apple-system,sans-serif;margin:0 16px;padding:24px 0}@media (min-width:865px){.w-footer__utility-nav{align-items:center;display:flex;flex-wrap:wrap;margin:0 24px}}.w-footer__utility-list{display:block;list-style:none;padding:0}@media (min-width:865px){.w-footer__utility-list{align-items:center;display:flex;flex:1;flex-wrap:wrap}}.w-footer__utility-item{margin:0}@media (min-width:865px){.w-footer__utility-item{margin-right:40px}}.w-footer__utility-link{color:#202124;display:block;padding:16px 0}.w-footer__utility-logo-link{display:block;line-height:1;margin-right:40px}.w-footer__utility-logo{margin:-2px 0 16px;max-width:185px}@media (min-width:865px){.w-footer__utility-logo{margin:-2px 0 0}}.header-default{position:fixed;top:0}.header-default [data-open-drawer-button]{margin:0 8px 0 -8px}@media (min-width:865px){.header-default [data-open-drawer-button]{display:none}}.header-default__middle{align-items:center;display:flex;flex:1;height:100%;overflow:hidden;position:relative}.header-default__links{display:none;flex:1;height:100%;line-height:20px;min-width:50%;padding-left:48px}@media (min-width:865px){.header-default__links{display:flex}}.header-default__link{align-items:center;color:#202124;display:flex;font-weight:500;margin:0;padding:0 16px;position:relative}.header-default__link[active]{box-shadow:0 -2px 0 #3740ff inset}@media (min-width:1264px){.header-default__link{padding:0 24px}}.header-default__link:active,.header-default__link:focus,.header-default__link:hover{outline:0;text-decoration:none}.header-default__link:hover{background-color:rgba(32,33,36,.04)}.header-default__link:focus{background-color:rgba(32,33,36,.12)}.header-default__link:active{background-color:rgba(32,33,36,.16)}.header-default web-search{flex:1}@media (min-width:865px){.header-default web-search .web-search__input-wrapper{max-width:calc(200% - 16px*2);min-width:calc(200% - 16px*2);transform:translateX(calc(50% - 200px + 16px));transition:var(--web-search-animation-time) transform;width:calc(200% - 16px*2);display:flex}.header-default web-search .web-search__close-btn,.header-default web-search .web-search__open-btn{display:none}.header-default web-search[expanded] .web-search__input-wrapper{transform:translate(calc(-50% + 16px))}}.header-default .web-search-popout{border-top:1px solid #ddd;box-shadow:0 1px 2px 0 rgba(60,64,67,.3),0 2px 6px 2px rgba(60,64,67,.15);left:0;padding:16px 0;position:absolute;top:55px;width:calc(100% - 45px)}@media (min-width:865px){.header-default .web-search-popout{left:calc(16px*2);width:calc(100% - 16px*2)}}web-header.web-header--has-expanded-search .header-default__logo-link,web-header.web-header--has-expanded-search web-profile-switcher-container,web-table-of-contents,web-table-of-contents-button[opened]{display:none}@media (min-width:865px){web-header.web-header--has-expanded-search .header-default__logo-link{display:inline}}web-header.web-header--has-expanded-search .header-default__middle{overflow:visible}@media (min-width:865px){web-header.web-header--has-expanded-search web-profile-switcher-container{display:flex}}.header-default~main{margin-top:64px}.icon{fill:currentColor}.w-screenshot{border:1px solid #dadce0;padding:4px;box-sizing:content-box;margin-left:-5px}.w-screenshot--filled{background-color:#f8f9fa;padding:16px;max-width:calc(100% - 32px);margin-left:0}.w-screenshot+.w-screenshot,.w-screenshot--filled+.w-screenshot--filled{margin-top:32px}.w-figure{margin:32px 0;text-align:center}.w-figcaption{font-size:.875em;line-height:1.5em;margin:16px 0 0}.w-layout-container--narrow{box-sizing:content-box;margin:0 auto;overflow:visible;padding:24px}@media (min-width:481px){.w-layout-container--narrow{padding:32px}}.w-layout-container--narrow{max-width:800px}:root{--grid-min:150px;--grid-max:.5fr;--grid-gap:24px}web-livestream-container{background-color:#fff;display:flex;margin:auto;max-width:1600px}@media (min-width:865px){web-livestream-container{border-left:1px solid #dadce0;border-right:1px solid #dadce0}}web-subscribe:not(:defined){display:flex;justify-content:center;width:100%}.w-subscribe__error{color:#eb0f00}@media (min-width:865px){main.w-toc-open>*{width:calc(100% - 268px)}main.w-toc-open>* .w-actions{right:calc(24px + 268px)}}web-table-of-contents h2{line-height:32px}web-table-of-contents .w-scroll-spy__active{position:relative;display:inline-block}web-table-of-contents .w-scroll-spy__active::before{content:"";display:inline-block;border-left:3px solid #3740ff;margin-left:-24px;padding-left:21px;height:100%;position:absolute;top:0;left:0}web-table-of-contents[opened]{background-color:#fff;border-bottom:1px solid #dadce0;border-top:1px solid #dadce0;display:block;padding:24px 0;top:63px;width:100%;z-index:100}@media (min-width:481px){web-table-of-contents[opened]{padding-top:32px}}@media (min-width:865px){web-table-of-contents[opened]{border-bottom:0;border-left:1px solid #dadce0;border-top:0;height:calc(100% - 64px);position:fixed;right:0;width:268px}}.w-toc__button--open{background-color:#fff;border:1px solid #dadce0;height:40px;overflow:hidden;padding:8px}web-table-of-contents-button{display:flex;height:0;justify-content:flex-end;margin-bottom:-24px;margin-right:24px;padding-top:24px;top:64px;z-index:1}@media (min-width:481px){web-table-of-contents-button{margin-bottom:-32px;padding-top:32px}}@media (min-width:865px){web-table-of-contents-button{max-height:none;position:sticky}}@media print{web-table-of-contents-button{display:none}}.w-toc__content{height:calc(100% - 24px);overflow-y:auto;padding:0 24px}@media (min-width:481px){.w-toc__content{height:calc(100% - 32px)}}.w-toc__content a{display:inline-block}.w-toc__header{margin-bottom:12px;margin-top:12px}.w-toc__header--link{font-family:"Google Sans",sans-serif;font-size:1.2rem;font-weight:500}@media (min-width:865px){.w-toc__header--link{color:#202124}.w-toc__header--link.w-scroll-spy__active,.w-toc__header--link:hover{color:#3740ff}}.w-toc__label{display:flex;height:40px;justify-content:space-between;padding:0 24px}.w-toc__label>*{font-size:.9rem;height:40px;line-height:40px;vertical-align:middle}.w-toc__list ul{margin:0;padding:0}.w-toc__list ul li::before{content:none}.w-toc__list ul li a{font-size:1rem}@media (min-width:865px){.w-toc__list ul li a{color:#202124}.w-toc__list ul li a.w-scroll-spy__active,.w-toc__list ul li a:hover{color:#3740ff}}.w-toc__list ol{padding-left:0}.w-toc__list ol a{padding-left:32px}.w-headline-link{color:transparent;display:none;font-weight:500;margin-left:4px}@media (min-width:481px){.w-headline-link{display:inline}}.w-headline-link:focus,:hover>.w-headline-link{color:#5f6368;display:inline}.w-tooltip{background:#000;border-radius:3px;color:#fff;font:500 12px/1 Segoe UI,system-ui,-apple-system,sans-serif;left:50%;letter-spacing:.3px;opacity:0;padding:6px 8px;pointer-events:none;position:absolute;text-transform:none;top:calc(100% + 3px);transform:scale(.85) translateX(-50%);transform-origin:top left;transition:opacity 75ms,transform 0s 75ms,visibility 0s 75ms;visibility:hidden;white-space:nowrap;z-index:1}.w-tooltip--left{left:0;transform:scale(.85)}.w-tooltip--right{left:100%;transform:translateX(-100%) scale(.85);transform-origin:top right}@media (hover:hover){:hover>.w-tooltip{opacity:.77;transform:scale(1) translateX(-50%);transition:opacity .15s .3s,transform .15s .3s,visibility 0s;visibility:visible}:hover>.w-tooltip--left{transform:scale(1)}:hover>.w-tooltip--right{transform:translateX(-100%) scale(1)}}:active>.w-tooltip,:focus .w-tooltip{opacity:.77;transform:scale(1) translateX(-50%);transition:opacity .15s .3s,transform .15s .3s,visibility 0s;visibility:visible}:active>.w-tooltip{transition:opacity .15s .5s,transform .15s .5s,visibility 0s}:active>.w-tooltip--left,:focus .w-tooltip--left{transform:scale(1)}:active>.w-tooltip--right,:focus .w-tooltip--right{transform:translateX(-100%) scale(1)}web-audio-fab{border-radius:50%;bottom:12px;box-shadow:0 8px 12px 6px rgba(60,64,67,.15),0 4px 4px rgba(60,64,67,.3);display:block;height:56px;opacity:0;pointer-events:none;position:fixed;right:12px;transition:opacity .2s cubic-bezier(.4,0,.2,1);width:56px;z-index:1}web-audio-fab[showing]{opacity:1;pointer-events:auto}web-copy-code{display:block;position:relative}web-copy-code:active .web-copy-code__button,web-copy-code:focus .web-copy-code__button,web-copy-code:hover .web-copy-code__button{opacity:1}web-copy-code .web-copy-code__button{color:#202124;height:48px;margin:8px;opacity:0;position:absolute;right:0;width:48px}web-copy-code .web-copy-code__button::before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font:24px/1 "Material Icons";font-feature-settings:"liga";text-rendering:optimizeSpeed;text-transform:none;word-wrap:normal;content:"content_copy"}web-copy-code .web-copy-code__button:focus,web-copy-code .web-copy-code__button:hover{background-color:rgba(63,196,255,.2);opacity:1}web-copy-code .web-copy-code__button:active{background-color:rgba(63,196,255,.4);opacity:1}web-copy-code pre{min-height:64px}web-header{align-items:center;background:#fff;box-shadow:0 1px 2px 0 rgba(60,64,67,.3),0 2px 6px 2px rgba(60,64,67,.15);color:#202124;contain:layout;display:flex;font-size:14px;height:64px;padding:0 24px;width:100%;z-index:200}@media print{web-header{display:none}}web-navigation-drawer{display:block;height:100%;left:0;pointer-events:none;position:fixed;top:0;width:100%;z-index:300}web-navigation-drawer [data-drawer-container]{box-shadow:2px 0 12px rgba(0,0,0,.4);position:relative;transform:translateX(-110%);width:fit-content}@media (min-width:1264px){web-navigation-drawer[type=standard]{align-self:flex-start;position:sticky;pointer-events:auto;top:0;width:auto}web-navigation-drawer[type=standard] [data-drawer-container]{box-shadow:none;transform:none}web-navigation-drawer[type=standard] [data-drawer-close-button]{visibility:hidden}}web-navigation-drawer::before{content:"";display:block;position:absolute;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,.4);opacity:0;transition:opacity .2s cubic-bezier(.4,0,.2,1)}web-navigation-drawer[open]{pointer-events:auto;visibility:visible}web-navigation-drawer[open]::before{opacity:1}web-navigation-drawer[open] [data-drawer-container]{transform:none}web-navigation-drawer[animating] [data-drawer-container],web-navigation-drawer[open][animating] [data-drawer-container]{transition:transform .2s cubic-bezier(.4,0,.2,1)}.youtube{padding-top:56.25%;position:relative;width:100%;border-radius:8px;overflow:hidden}lite-youtube{height:100%;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:100%}web-codelab{display:flex;flex-flow:column;padding:16px}@media (min-width:865px){web-codelab{flex-flow:row}}web-codelab .web-codelab__glitch{min-height:160px}.w-event-carousel__day{color:#3c4043;font-family:"Google Sans",sans-serif;font-size:14px;font-weight:500;margin-right:16px}.w-event-carousel__day:last-child{margin-right:0}.w-event-carousel__day.w-event-carousel__pending{opacity:.6}.w-event-carousel__thumbnail{margin-bottom:8px;background-color:#e8eaed;border-radius:3px;overflow:hidden;width:178px;height:110px}.w-event-carousel__thumbnail>img{height:100%;object-fit:cover}.w-event-schedule__video{align-self:center;font-weight:500;z-index:1}web-progress-bar{background-color:#fff;visibility:hidden;z-index:1}.guide-landing-page{position:relative}.w-post-breadcrumbs{padding:0 0 32px}@media (min-width:865px){.w-post-breadcrumbs{padding:0 0 44px}}.w-post-content{margin-bottom:64px}@media (min-width:481px){.w-post-content{margin-bottom:160px}}.w-post-github-link{color:#5f6368;font-size:.875em}:root{--course-content-margin:24px}summary::-webkit-details-marker{display:none}.w-text--center{text-align:center!important}.w-display--flex{display:flex}.w-justify-content--center{justify-content:center}.w-mb--non{margin-bottom:0!important}.w-mb--sm{margin-bottom:8px!important}.w-mt--sm{margin-top:8px!important}.w-mr--sm{margin-right:8px!important}.w-pt--sm{padding-top:8px!important}.w-mb--l{margin-bottom:32px!important}.w-mt--l{margin-top:32px!important}.w-mt--xl{margin-top:56px!important}.hidden,[hidden]{display:none!important}:not(body).unresolved,web-tabs.unresolved>:not(.w-tabs-default){display:none}web-tabs.unresolved{padding-top:50px;display:block}web-event-time.unresolved{min-height:120px;display:block}</style><link as=font crossorigin href=/fonts/material-icons/regular.woff2 rel=preload><link as=font crossorigin href=/fonts/google-sans/regular/latin.woff2 rel=preload><link as=font crossorigin href=/fonts/google-sans/bold/latin.woff2 rel=preload><meta content=#fff name=theme-color><title>
   Read files in JavaScript
  </title><meta content="How to select files, read file metadata and content, and monitor read progress. "name=description><link href=https://web.dev/read-files/ rel=canonical><meta content="Read files in JavaScript"itemprop=name><meta content="How to select files, read file metadata and content, and monitor read progress. "itemprop=description><meta content=https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/vU99HKzIf5EUPnzGVPf1.png?auto=format&fit=max&w=1200&fm=auto itemprop=image><meta content=en_US property=og:locale><meta content=article property=og:type><meta content=https://web.dev/read-files/ property=og:url><meta content=web.dev property=og:site_name><meta content="Read files in JavaScript"property=og:title><meta content="How to select files, read file metadata and content, and monitor read progress. "property=og:description><meta content=https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/vU99HKzIf5EUPnzGVPf1.png?auto=format&fit=max&w=1200&fm=auto property=og:image><meta property=og:image:alt><meta content=storage property=tag><meta content=summary_large_image name=twitter:card><meta content="Read files in JavaScript"name=twitter:title><meta content="How to select files, read file metadata and content, and monitor read progress. "name=twitter:description><meta content=https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/vU99HKzIf5EUPnzGVPf1.png?auto=format&fit=max&w=1200&fm=auto name=twitter:image><link data-title="web.dev feed"href=/feed.xml rel=alternate type=application/atom+xml><link href=/manifest.webmanifest rel=manifest><link rel="shortcut icon"href=/images/favicon.ico><link href=/images/favicon-32x32.png rel=icon sizes=32x32 type=image/png><link href=/images/favicon-16x16.png rel=icon sizes=16x16 type=image/png><link href=/images/apple-touch-icon.png rel=apple-touch-icon sizes=180x180><link color=#0054ff href=/images/safari-pinned-tab.svg rel=mask-icon><script>window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)},ga.l=+new Date,ga("create","UA-126406676-2"),ga("set","transport","beacon"),ga("set","anonymizeIp",!0),ga("set","page",window.location.pathname),ga("set","dimension5","4"),ga("send","pageview");</script><script>function loadScript(e,t){const d=document.createElement("script");if(d.src=e,t&&(d.type=t),"module"===t){d.async=!1;const t=document.createElement("link");t.rel="modulepreload",t.href=e,document.head.append(t),window.addEventListener("DOMContentLoaded",(()=>{document.head.append(d)}))}else document.head.append(d)}loadScript("/js/app.js?v=c4d27698","module"),loadScript("/js/content.js?v=69921f5a","module"),loadScript("https://www.google-analytics.com/analytics.js",null);</script><body class=unresolved><web-snackbar-container> </web-snackbar-container><web-header class=header-default role=navigation> <button aria-label="Open menu"class="w-button--round w-button--svg"data-open-drawer-button><svg viewbox="0 0 24 24"aria-label=menu class=icon height=24 role=img width=24 xmlns=http://www.w3.org/2000/svg><path d="M0 0h24v24H0z"fill=none></path><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path></svg> <span class="w-tooltip w-tooltip--left"> Open menu </span></button> <a class="gc-analytics-event header-default__logo-link"data-category="Site-Wide Custom Events"data-label="Site logo"href=/> <img alt=web.dev class=header-default__logo height=23 src=/images/lockup.svg width=125> </a> <div class=header-default__middle><div class=header-default__links><a class="gc-analytics-event header-default__link"data-category="Site-Wide Custom Events"data-label="Tab: Learn"href=/learn/> Learn </a><a class="gc-analytics-event header-default__link"data-category="Site-Wide Custom Events"data-label="Tab: Measure"href=/measure/> Measure </a><a class="gc-analytics-event header-default__link"data-category="Site-Wide Custom Events"data-label="Tab: Blog"href=/blog/> Blog </a><a class="gc-analytics-event header-default__link"data-category="Site-Wide Custom Events"data-label="Tab: About"href=/about/> About </a></div><web-search i18n='{"search":{"en":"Search"},"open_search":{"en":"Open search"},"all_articles":{"en":"All articles"},"close_search":{"en":"Close search"}}'results-id=search-main-results> </web-search><web-search-results id=search-main-results> </web-search-results></div> <web-profile-switcher-container> </web-profile-switcher-container> </web-header><web-navigation-drawer class=drawer-default type=modal> <nav data-drawer-container><div class=drawer-default__contents><div class=drawer-default__header><button class="w-button--round w-button--svg drawer-default__hide"aria-label=Close data-drawer-close-button><svg viewbox="0 0 24 24"aria-label=close class=icon height=24 role=img width=24 xmlns=http://www.w3.org/2000/svg><path d="M0 0h24v24H0z"fill=none></path><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></svg> <span class=w-tooltip> Close </span></button><a data-category="Site-Wide Custom Events"data-label="Site logo"class=gc-analytics-event href=/> <img alt=web.dev class=drawer-default__logo height=30 src=/images/lockup.svg width=125> </a></div><a class="gc-analytics-event drawer-default__link"data-category="Site-Wide Custom Events"data-label="SideNav: Learn"href=/learn/> Learn </a><a class="gc-analytics-event drawer-default__link"data-category="Site-Wide Custom Events"data-label="SideNav: Measure"href=/measure/> Measure </a><a class="gc-analytics-event drawer-default__link"data-category="Site-Wide Custom Events"data-label="SideNav: Blog"href=/blog/> Blog </a><a class="gc-analytics-event drawer-default__link"data-category="Site-Wide Custom Events"data-label="SideNav: About"href=/about/> About </a></div></nav> </web-navigation-drawer><main><div id=content><div class="w-banner w-banner--info"role=banner>The countdown to Chrome Dev Summit 2021 is on! Visit <a href=https://goo.gle/cds2021> goo.gle/cds2021 </a> and request an invite to participate in workshops, learning lounges and office hours.</div><div class=guide-landing-page><web-table-of-contents> <h2 class=w-toc__header><a class=w-toc__header--link href=#read-files-in-javascript> Read files in JavaScript </a></h2> <div class=w-toc__list><ul><li><a href=#the-modern-file-system-access-api> The modern File System Access API </a><li><a href=#working-with-files-the-classic-way> Working with files, the classic way </a><li><a href=#select> Select files </a> <ol><li><a href=#select-input> HTML input element </a><li><a href=#select-dnd> Custom drag-and-drop </a><li><a href=#directories> What about directories? </a></ol><li><a href=#read-metadata> Read file metadata </a><li><a href=#read-content> Read a file's content </a> <ol><li><a href=#monitor-progress> Monitor the progress of a file read </a></ol></ul></div> </web-table-of-contents><web-table-of-contents-button> </web-table-of-contents-button><div class=w-actions><share-action authors="@kaycebasques | @petele | @tomayac"class="gc-analytics-event w-actions__fab w-actions__fab--share"data-action=click data-category=web.dev data-icon=share data-label=share role=button tabindex=0> <span> Share </span> </share-action><a class="gc-analytics-event w-actions__fab w-actions__fab--subscribe"data-action=click data-category=web.dev data-label=view-subscribe href=/newsletter/> <span> subscribe </span> </a></div><div class="w-layout-container--narrow w-post-content"><header class=w-article-header><div class=w-post-breadcrumbs><ul class=w-breadcrumbs><li class=w-breadcrumbs__crumb><a class="gc-analytics-event w-breadcrumbs__link w-breadcrumbs__link--left-justify"data-label="post, home breadcrumb"data-action=click data-category=web.dev href=/> Home </a></li><svg viewbox="0 0 24 24"aria-hidden=true class=w-breadcrumbs__icon height=24 width=24 xmlns=http://www.w3.org/2000/svg><path d="M0 0h24v24H0V0z"fill=none></path><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"></path></svg><li class=w-breadcrumbs__crumb><a class="gc-analytics-event w-breadcrumbs__link"data-label="post, path breadcrumb"data-action=click data-category=web.dev href=/blog> All articles </a></ul></div><h1 class=w-article-header__headline id=read-files-in-javascript>Read files in JavaScript</h1><p class="w-article-header__subhead w-mb--non">How to select files, read file metadata and content, and monitor read progress.<div class=w-author__published><time> Jun 18, 2010 </time><span class=w-author__separator> • </span> Updated <time> Mar 29, 2021 </time></div><div class="w-authors w-mt--xl w-pt--sm"><div class=w-author><a href=/authors/kaycebasques/> <img alt="Kayce Basques"sizes="(min-width: 64px) 64px, calc(100vw - 48px)"srcset="https://web-dev.imgix.net/image/admin/7GdPR4YDRHSS6llepBOd.jpg?fit=crop&h=64&w=64&auto=format&dpr=1&q=75, https://web-dev.imgix.net/image/admin/7GdPR4YDRHSS6llepBOd.jpg?fit=crop&h=64&w=64&auto=format&dpr=2&q=50 2x, https://web-dev.imgix.net/image/admin/7GdPR4YDRHSS6llepBOd.jpg?fit=crop&h=64&w=64&auto=format&dpr=3&q=35 3x, https://web-dev.imgix.net/image/admin/7GdPR4YDRHSS6llepBOd.jpg?fit=crop&h=64&w=64&auto=format&dpr=4&q=23 4x, https://web-dev.imgix.net/image/admin/7GdPR4YDRHSS6llepBOd.jpg?fit=crop&h=64&w=64&auto=format&dpr=5&q=20 5x"class=w-author__image decoding=async height=64 loading=lazy src=https://web-dev.imgix.net/image/admin/7GdPR4YDRHSS6llepBOd.jpg?auto=format&fit=crop&h=64&w=64 width=64> </a><div style="display: flex; flex-direction: column; justify-content: center;"class=w-author__info><cite class=w-author__name> <a class=w-author__name-link href=/authors/kaycebasques/> Kayce Basques </a> </cite><ul class=w-author__link-list><li class=w-author__link-listitem><a class=w-author__link href=https://twitter.com/kaycebasques> Twitter </a><li class=w-author__link-listitem><a class=w-author__link href=https://github.com/kaycebasques> GitHub </a><li class=w-author__link-listitem><a class=w-author__link href=https://glitch.com/@kaycebasques> Glitch </a><li class=w-author__link-listitem><a class=w-author__link href=https://kayce.basqu.es/> Blog </a></ul></div></div><div class=w-author><a href=/authors/petelepage/> <img alt="Pete LePage"sizes="(min-width: 64px) 64px, calc(100vw - 48px)"srcset="https://web-dev.imgix.net/image/0g2WvpbGRGdVs0aAPc6ObG7gkud2/3rFbsLsMMk1VveHfBRSu.jpg?fit=crop&h=64&w=64&auto=format&dpr=1&q=75, https://web-dev.imgix.net/image/0g2WvpbGRGdVs0aAPc6ObG7gkud2/3rFbsLsMMk1VveHfBRSu.jpg?fit=crop&h=64&w=64&auto=format&dpr=2&q=50 2x, https://web-dev.imgix.net/image/0g2WvpbGRGdVs0aAPc6ObG7gkud2/3rFbsLsMMk1VveHfBRSu.jpg?fit=crop&h=64&w=64&auto=format&dpr=3&q=35 3x, https://web-dev.imgix.net/image/0g2WvpbGRGdVs0aAPc6ObG7gkud2/3rFbsLsMMk1VveHfBRSu.jpg?fit=crop&h=64&w=64&auto=format&dpr=4&q=23 4x, https://web-dev.imgix.net/image/0g2WvpbGRGdVs0aAPc6ObG7gkud2/3rFbsLsMMk1VveHfBRSu.jpg?fit=crop&h=64&w=64&auto=format&dpr=5&q=20 5x"class=w-author__image decoding=async height=64 loading=lazy src=https://web-dev.imgix.net/image/0g2WvpbGRGdVs0aAPc6ObG7gkud2/3rFbsLsMMk1VveHfBRSu.jpg?auto=format&fit=crop&h=64&w=64 width=64> </a><div style="display: flex; flex-direction: column; justify-content: center;"class=w-author__info><cite class=w-author__name> <a class=w-author__name-link href=/authors/petelepage/> Pete LePage </a> </cite><ul class=w-author__link-list><li class=w-author__link-listitem><a class=w-author__link href=https://twitter.com/petele> Twitter </a><li class=w-author__link-listitem><a class=w-author__link href=https://github.com/petele> GitHub </a><li class=w-author__link-listitem><a class=w-author__link href=https://glitch.com/@petele> Glitch </a><li class=w-author__link-listitem><a class=w-author__link href=https://petelepage.com> Blog </a></ul></div></div><div class=w-author><a href=/authors/thomassteiner/> <img alt="Thomas Steiner"sizes="(min-width: 64px) 64px, calc(100vw - 48px)"srcset="https://web-dev.imgix.net/image/admin/8PLpVmFef6mj72MVWeiN.jpg?fit=crop&h=64&w=64&auto=format&dpr=1&q=75, https://web-dev.imgix.net/image/admin/8PLpVmFef6mj72MVWeiN.jpg?fit=crop&h=64&w=64&auto=format&dpr=2&q=50 2x, https://web-dev.imgix.net/image/admin/8PLpVmFef6mj72MVWeiN.jpg?fit=crop&h=64&w=64&auto=format&dpr=3&q=35 3x, https://web-dev.imgix.net/image/admin/8PLpVmFef6mj72MVWeiN.jpg?fit=crop&h=64&w=64&auto=format&dpr=4&q=23 4x, https://web-dev.imgix.net/image/admin/8PLpVmFef6mj72MVWeiN.jpg?fit=crop&h=64&w=64&auto=format&dpr=5&q=20 5x"class=w-author__image decoding=async height=64 loading=lazy src=https://web-dev.imgix.net/image/admin/8PLpVmFef6mj72MVWeiN.jpg?auto=format&fit=crop&h=64&w=64 width=64> </a><div style="display: flex; flex-direction: column; justify-content: center;"class=w-author__info><cite class=w-author__name> <a class=w-author__name-link href=/authors/thomassteiner/> Thomas Steiner </a> </cite><ul class=w-author__link-list><li class=w-author__link-listitem><a class=w-author__link href=https://twitter.com/tomayac> Twitter </a><li class=w-author__link-listitem><a class=w-author__link href=https://github.com/tomayac> GitHub </a><li class=w-author__link-listitem><a class=w-author__link href=https://glitch.com/@tomayac> Glitch </a><li class=w-author__link-listitem><a class=w-author__link href=https://blog.tomayac.com/> Blog </a></ul></div></div></div></header><p>Being able to select and interact with files on the user's local device is one of the most commonly used features of the web. It allows users to select files and upload them to a server, for example, uploading photos, or submitting tax documents, etc. But, it also allows sites to read and manipulate them without ever having to transfer the data across the network.<h2 id=the-modern-file-system-access-api>The modern File System Access API <a class=w-headline-link href=#the-modern-file-system-access-api> # </a></h2><p>The File System Access API provides an easy way to both read and write to files and directories on the user's local system. It's currently available in most Chromium-derived browsers like Chrome or Edge. To learn more about it, see the <a href=/file-system-access/> File System Access API </a> article.<p>Since the File System Access API is not compatible with all browsers yet, check out <a href=https://github.com/GoogleChromeLabs/browser-fs-access rel=noopener> browser-fs-access </a> , a helper library that uses the new API wherever it is available, but falls back to legacy approaches when it is not.<h2 id=working-with-files-the-classic-way>Working with files, the classic way <a class=w-headline-link href=#working-with-files-the-classic-way> # </a></h2><p>This guide shows you how to:<ul><li>Select files <ul><li><a href=#select-input> Using the HTML input element </a><li><a href=#select-dnd> Using a drag-and-drop zone </a></ul><li><a href=#read-metadata> Read file metadata </a><li><a href=#read-content> Read a file's content </a></ul><h2 id=select>Select files <a class=w-headline-link href=#select> # </a></h2><h3 id=select-input>HTML input element <a class=w-headline-link href=#select-input> # </a></h3><p>The easiest way to allow users to select files is using the <a href=https://developer.mozilla.org/docs/Web/HTML/Element/input/file rel=noopener> <code>
         &LTinput type="file">
        </code> </a> element, which is supported in every major browser. When clicked, it lets a user select a file, or multiple files if the <a href=https://developer.mozilla.org/docs/Web/HTML/Element/input/file#Additional_attributes rel=noopener> <code>
         multiple
        </code> </a> attribute is included, using their operating system's built-in file selection UI. When the user finishes selecting a file or files, the element's <code>
        change
       </code> event is fired. You can access the list of files from <code>
        event.target.files
       </code> , which is a <a href=https://developer.mozilla.org/docs/Web/API/FileList rel=noopener> <code>
         FileList
        </code> </a> object. Each item in the <code>
        FileList
       </code> is a <a href=https://developer.mozilla.org/docs/Web/API/File rel=noopener> <code>
         File
        </code> </a> object.</p><web-copy-code> <pre class=language-html><code class=language-html><span class="token comment">&LT!-- The `multiple` attribute lets users select multiple files. --></span><br><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>file<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>file-selector<span class="token punctuation">"</span></span> <span class="token attr-name">multiple</span><span class="token punctuation">></span></span><br><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"><br>  <span class="token keyword">const</span> fileSelector <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'file-selector'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br>  fileSelector<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'change'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br>    <span class="token keyword">const</span> fileList <span class="token operator">=</span> event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>files<span class="token punctuation">;</span><br>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>fileList<span class="token punctuation">)</span><span class="token punctuation">;</span><br>  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&LT/</span>script</span><span class="token punctuation">></span></span></code></pre> </web-copy-code><div class="w-aside w-aside--note"><p>Check if the <a href=/file-system-access/#ask-the-user-to-pick-a-file-to-read> <code>
          window.showOpenFilePicker()
         </code> </a> method is a viable alternative for your use case, since it also gives you a file handle so you can possibly write back to the file, apart from reading. This method can be <a href=https://github.com/GoogleChromeLabs/browser-fs-access#opening-files rel=noopener> polyfilled </a> .</div><p>This example lets a user select multiple files using their operating system's built-in file selection UI and then logs each selected file to the console.<div style="height: 480px; width: 100%;"class=glitch-embed-wrap><iframe allow="camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi"style="height: 100%; width: 100%; border: 0;"title="input-type-file on Glitch"loading=lazy src=https://glitch.com/embed/#!/embed/input-type-file?attributionHidden=true&sidebarCollapsed=true&previewSize=100></iframe></div><h4 id=accept>Limit the types of files user can select <a class=w-headline-link href=#accept> # </a></h4><p>In some cases, you may want to limit the types of files users can select. For example, an image editing app should only accept images, not text files. To do that, you can add an <a href=https://developer.mozilla.org/docs/Web/HTML/Element/input/file#Additional_attributes rel=noopener> <code>
         accept
        </code> </a> attribute to the input element to specify which files are accepted.</p><web-copy-code> <pre class=language-html><code class=language-html><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>file<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>file-selector<span class="token punctuation">"</span></span> <span class="token attr-name">accept</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>.jpg, .jpeg, .png<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></code></pre> </web-copy-code><h3 id=select-dnd>Custom drag-and-drop <a class=w-headline-link href=#select-dnd> # </a></h3><p>In some browsers, the <code>
        &LTinput type="file">
       </code> element is also a drop target, allowing users to drag-and-drop files into your app. But, the drop target is small, and can be hard to use. Instead, once you've provided the core functionality using an <code>
        &LTinput type="file">
       </code> element, you can provide a large, custom drag-and-drop surface.<div class="w-aside w-aside--note"><p>Check if the <a href=/file-system-access/#drag-and-drop-integration> <code>
          DataTransferItem.getAsFileSystemHandle()
         </code> </a> method is a viable alternative for your use case, since it also gives you a file handle so you can possibly write back to the file, apart from reading.</div><h4 id=choose-drop-zone>Choose your drop zone <a class=w-headline-link href=#choose-drop-zone> # </a></h4><p>Your drop surface will depend on the design of your application. You may only want part of the window to be a drop surface, or potentially the entire window.<figure class=w-figure><img alt="A screenshot of Squoosh, an image compression web app."class="w-screenshot w-screenshot--filled"sizes="(min-width: 800px) 800px, calc(100vw - 48px)"srcset="https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=200 200w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=228 228w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=260 260w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=296 296w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=338 338w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=385 385w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=439 439w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=500 500w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=571 571w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=650 650w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=741 741w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=845 845w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=964 964w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format&w=1600 1600w"decoding=async height=589 loading=lazy src=https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xX8UXdqkLmZXu3Ad1Z2q.png?auto=format width=800><figcaption class=w-figcaption>Squoosh makes the entire window a drop zone.</figcaption></figure><p>Squoosh allows the user to drag-and-drop an image anywhere into the window, and clicking <strong> select an image </strong> invokes the <code>
        &LTinput type="file">
       </code> element. Whatever you choose as your drop zone, make sure it's clear to the user that they can drag-and-drop files onto that surface.<h4 id=define-drop-zone>Define the drop zone <a class=w-headline-link href=#define-drop-zone> # </a></h4><p>To enable an element to be a drag-and-drop zone, you'll need to listen for two events, <a href=https://developer.mozilla.org/docs/Web/API/Document/dragover_event rel=noopener> <code>
         dragover
        </code> </a> and <a href=https://developer.mozilla.org/docs/Web/API/Document/drop_event rel=noopener> <code>
         drop
        </code> </a> . The <code>
        dragover
       </code> event updates the browser UI to visually indicate that the drag-and-drop action is creating a copy of the file. The <code>
        drop
       </code> event is fired after the user has dropped the files onto the surface. Similar to the input element, you can access the list of files from <code>
        event.dataTransfer.files
       </code> , which is a <a href=https://developer.mozilla.org/docs/Web/API/FileList rel=noopener> <code>
         FileList
        </code> </a> object. Each item in the <code>
        FileList
       </code> is a <a href=https://developer.mozilla.org/docs/Web/API/File rel=noopener> <code>
         File
        </code> </a> object.</p><web-copy-code> <pre class=language-js><code class=language-js><span class="token keyword">const</span> dropArea <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'drop-area'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><br>dropArea<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragover'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br>  event<span class="token punctuation">.</span><span class="token function">stopPropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br>  event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br>  <span class="token comment">// Style the drag-and-drop as a "copy file" operation.</span><br>  event<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span>dropEffect <span class="token operator">=</span> <span class="token string">'copy'</span><span class="token punctuation">;</span><br><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><br>dropArea<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'drop'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br>  event<span class="token punctuation">.</span><span class="token function">stopPropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br>  event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br>  <span class="token keyword">const</span> fileList <span class="token operator">=</span> event<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span>files<span class="token punctuation">;</span><br>  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>fileList<span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre> </web-copy-code><p><a href=https://developer.mozilla.org/docs/Web/API/Event/stopPropagation rel=noopener> <code>
         event.stopPropagation()
        </code> </a> and <a href=https://developer.mozilla.org/docs/Web/API/Event/preventDefault rel=noopener> <code>
         event.preventDefault()
        </code> </a> stop the browser's default behavior from happening, and allow your code to run instead. Without them, the browser would otherwise navigate away from your page and open the files the user dropped into the browser window.<p>Check out <a href=https://custom-drag-and-drop.glitch.me/ rel=noopener> Custom drag-and-drop </a> for a live demonstration.<h3 id=directories>What about directories? <a class=w-headline-link href=#directories> # </a></h3><p>Unfortunately, today there isn't a good way to get access to a directory.<p>The <a href=https://developer.mozilla.org/docs/Web/API/HTMLInputElement/webkitdirectory rel=noopener> <code>
         webkitdirectory
        </code> </a> attribute on the <code>
        &LTinput type="file">
       </code> element allows the user to choose a directory or directories. It is supported in some Chromium-based browsers, and possibly desktop Safari, but has <a href=https://caniuse.com/#search=webkitdirectory rel=noopener> conflicting </a> reports of browser compatibility.<div class="w-aside w-aside--note"><p>Check if the <a href=/file-system-access/#opening-a-directory-and-enumerating-its-contents> <code>
          window.showDirectoryPicker()
         </code> </a> method is a viable alternative for your use case, since it also gives you a directory handle so you can possibly write back to the directory, apart from reading. This method can be <a href=https://github.com/GoogleChromeLabs/browser-fs-access#opening-directories rel=noopener> polyfilled </a> .</div><p>If drag-and-drop is enabled, a user may try to drag a directory into the drop zone. When the drop event is fired, it will include a <code>
        File
       </code> object for the directory, but will be unable to access any of the files within the directory.<h2 id=read-metadata>Read file metadata <a class=w-headline-link href=#read-metadata> # </a></h2><p>The <a href=https://developer.mozilla.org/docs/Web/API/File rel=noopener> <code>
         File
        </code> </a> object contains a number of metadata properties about the file. Most browsers provide the file name, the size of the file, and the MIME type, though depending on the platform, different browsers may provide different, or additional information.</p><web-copy-code> <pre class=language-js><code class=language-js><span class="token keyword">function</span> <span class="token function">getMetadataForFileList</span><span class="token punctuation">(</span><span class="token parameter">fileList</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> file <span class="token keyword">of</span> fileList<span class="token punctuation">)</span> <span class="token punctuation">{</span><br>    <span class="token comment">// Not supported in Safari for iOS.</span><br>    <span class="token keyword">const</span> name <span class="token operator">=</span> file<span class="token punctuation">.</span>name <span class="token operator">?</span> file<span class="token punctuation">.</span>name <span class="token operator">:</span> <span class="token string">'NOT SUPPORTED'</span><span class="token punctuation">;</span><br>    <span class="token comment">// Not supported in Firefox for Android or Opera for Android.</span><br>    <span class="token keyword">const</span> type <span class="token operator">=</span> file<span class="token punctuation">.</span>type <span class="token operator">?</span> file<span class="token punctuation">.</span>type <span class="token operator">:</span> <span class="token string">'NOT SUPPORTED'</span><span class="token punctuation">;</span><br>    <span class="token comment">// Unknown cross-browser support.</span><br>    <span class="token keyword">const</span> size <span class="token operator">=</span> file<span class="token punctuation">.</span>size <span class="token operator">?</span> file<span class="token punctuation">.</span>size <span class="token operator">:</span> <span class="token string">'NOT SUPPORTED'</span><span class="token punctuation">;</span><br>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">{</span>file<span class="token punctuation">,</span> name<span class="token punctuation">,</span> type<span class="token punctuation">,</span> size<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br>  <span class="token punctuation">}</span><br><span class="token punctuation">}</span></code></pre> </web-copy-code><p>You can see this in action in the <a href=https://input-type-file.glitch.me/ rel=noopener> <code>
         input-type-file
        </code> </a> Glitch demo.<h2 id=read-content>Read a file's content <a class=w-headline-link href=#read-content> # </a></h2><p>To read a file, use <a href=https://developer.mozilla.org/docs/Web/API/FileReader rel=noopener> <code>
         FileReader
        </code> </a> , which enables you to read the content of a <code>
        File
       </code> object into memory. You can instruct <code>
        FileReader
       </code> to read a file as an <a href=https://developer.mozilla.org/docs/Web/API/FileReader/readAsArrayBuffer rel=noopener> array buffer </a> , a <a href=https://developer.mozilla.org/docs/Web/API/FileReader/readAsDataURL rel=noopener> data URL </a> , or <a href=https://developer.mozilla.org/docs/Web/API/FileReader/readAsText rel=noopener> text </a> .</p><web-copy-code> <pre class=language-js><code class=language-js><span class="token keyword">function</span> <span class="token function">readImage</span><span class="token punctuation">(</span><span class="token parameter">file</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br>  <span class="token comment">// Check if the file is an image.</span><br>  <span class="token keyword">if</span> <span class="token punctuation">(</span>file<span class="token punctuation">.</span>type <span class="token operator">&&</span> <span class="token operator">!</span>file<span class="token punctuation">.</span>type<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span><span class="token string">'image/'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'File is not an image.'</span><span class="token punctuation">,</span> file<span class="token punctuation">.</span>type<span class="token punctuation">,</span> file<span class="token punctuation">)</span><span class="token punctuation">;</span><br>    <span class="token keyword">return</span><span class="token punctuation">;</span><br>  <span class="token punctuation">}</span><br><br>  <span class="token keyword">const</span> reader <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FileReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br>  reader<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br>    img<span class="token punctuation">.</span>src <span class="token operator">=</span> event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>result<span class="token punctuation">;</span><br>  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br>  reader<span class="token punctuation">.</span><span class="token function">readAsDataURL</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token punctuation">}</span></code></pre> </web-copy-code><p>The example above reads a <code>
        File
       </code> provided by the user, then converts it to a data URL, and uses that data URL to display the image in an <code>
        img
       </code> element. Check out the <a href=https://read-image-file.glitch.me/ rel=noopener> <code>
         read-image-file
        </code> </a> Glitch to see how to verify that the user has selected an image file.<div style="height: 480px; width: 100%;"class=glitch-embed-wrap><iframe allow="camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi"style="height: 100%; width: 100%; border: 0;"title="read-image-file on Glitch"loading=lazy src=https://glitch.com/embed/#!/embed/read-image-file?attributionHidden=true&sidebarCollapsed=true&previewSize=100></iframe></div><h3 id=monitor-progress>Monitor the progress of a file read <a class=w-headline-link href=#monitor-progress> # </a></h3><p>When reading large files, it may be helpful to provide some UX to indicate how far the read has progressed. For that, use the <a href=https://developer.mozilla.org/docs/Web/API/FileReader/progress_event rel=noopener> <code>
         progress
        </code> </a> event provided by <code>
        FileReader
       </code> . The <code>
        progress
       </code> event provides two properties, <code>
        loaded
       </code> , the amount read, and <code>
        total
       </code> , the total amount to read.</p><web-copy-code> <pre class=language-js><code class=language-js><span class=highlight-line><span class="token keyword">function</span> <span class="token function">readFile</span><span class="token punctuation">(</span><span class="token parameter">file</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class=highlight-line>  <span class="token keyword">const</span> reader <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FileReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><br><span class=highlight-line>  reader<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span></span><br><span class=highlight-line>    <span class="token keyword">const</span> result <span class="token operator">=</span> event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>result<span class="token punctuation">;</span></span><br><span class=highlight-line>    <span class="token comment">// Do something with result</span></span><br><span class=highlight-line>  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><br><span class=highlight-line></span><br><mark class="highlight-line highlight-line-active">  reader<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'progress'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span></mark><br><mark class="highlight-line highlight-line-active">    <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>loaded <span class="token operator">&&</span> event<span class="token punctuation">.</span>total<span class="token punctuation">)</span> <span class="token punctuation">{</span></mark><br><mark class="highlight-line highlight-line-active">      <span class="token keyword">const</span> percent <span class="token operator">=</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>loaded <span class="token operator">/</span> event<span class="token punctuation">.</span>total<span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">100</span><span class="token punctuation">;</span></mark><br><mark class="highlight-line highlight-line-active">      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token string template-punctuation">`</span><span class="token string">Progress: </span><span class="token interpolation"><span class="token punctuation interpolation-punctuation">${</span>Math<span class="token punctuation">.</span><span class="token function">round</span><span class="token punctuation">(</span>percent<span class="token punctuation">)</span><span class="token punctuation interpolation-punctuation">}</span></span><span class="token string template-punctuation">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></mark><br><mark class="highlight-line highlight-line-active">    <span class="token punctuation">}</span></mark><br><mark class="highlight-line highlight-line-active">  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></mark><br><span class=highlight-line>  reader<span class="token punctuation">.</span><span class="token function">readAsDataURL</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span></span><br><span class=highlight-line><span class="token punctuation">}</span></span></code></pre> </web-copy-code><p>Hero image by Vincent Botta from <a href=https://unsplash.com/photos/bv_rJXpNU9I rel=noopener> Unsplash </a><div class=w-chips><a class=w-chip href=/tags/storage/> Storage </a></div><div class="w-mb--l w-mt--l w-post-github-link"><span class=w-mr--sm> Last updated: <time> Mar 29, 2021 </time> </span><a href=https://github.com/GoogleChrome/web.dev/blob/master/src/site/content/en/blog/read-files/index.md> Improve article </a></div></div><nav class=w-article-navigation><a class="gc-analytics-event w-article-navigation__link w-article-navigation__link--back w-article-navigation__link--single"data-label="navigation, go back"data-action=click data-category=web.dev href=/blog> Return to all articles </a></nav></div></div></main><footer class=w-footer><nav class=w-footer__linkboxes><ul class=w-footer__linkboxes-list><li class=w-footer__linkbox><h3 class=w-footer__linkbox-heading>Contribute</h3> <ul class=w-footer__linkbox-list><li class=w-footer__linkbox-item><a data-category="Site-Wide Custom Events"data-label="Footer Link (index 1)"class=w-footer__linkbox-link href=https://github.com/GoogleChrome/web.dev/issues/new?assignees=&labels=bug&template=bug_report.md&title=> File a bug </a><li class=w-footer__linkbox-item><a data-category="Site-Wide Custom Events"data-label="Footer Link (index 2)"class=w-footer__linkbox-link href=https://github.com/googlechrome/web.dev> View source </a></ul><li class=w-footer__linkbox><h3 class=w-footer__linkbox-heading>Related content</h3> <ul class=w-footer__linkbox-list><li class=w-footer__linkbox-item><a data-category="Site-Wide Custom Events"data-label="Footer Link (index 1)"class=w-footer__linkbox-link href=https://blog.chromium.org/> Chrome updates </a><li class=w-footer__linkbox-item><a data-category="Site-Wide Custom Events"data-label="Footer Link (index 2)"class=w-footer__linkbox-link href=https://developers.google.com/web/> Web Fundamentals </a><li class=w-footer__linkbox-item><a data-category="Site-Wide Custom Events"data-label="Footer Link (index 3)"class=w-footer__linkbox-link href=https://developers.google.com/web/showcase/> Case studies </a><li class=w-footer__linkbox-item><a data-label="Footer Link (index 5)"class=w-footer__linkbox-link data-category=Podcasts href=/podcasts/> Podcasts </a><li class=w-footer__linkbox-item><a data-label="Footer Link (index 6)"class=w-footer__linkbox-link data-category=Shows href=/shows/> Shows </a></ul><li class=w-footer__linkbox><h3 class=w-footer__linkbox-heading>Connect</h3> <ul class=w-footer__linkbox-list><li class=w-footer__linkbox-item><a data-category="Site-Wide Custom Events"data-label="Footer Link (index 1)"class=w-footer__linkbox-link href=https://www.twitter.com/ChromiumDev> Twitter </a><li class=w-footer__linkbox-item><a data-category="Site-Wide Custom Events"data-label="Footer Link (index 2)"class=w-footer__linkbox-link href=https://www.youtube.com/user/ChromeDevelopers> YouTube </a></ul></ul></nav><div class=w-footer__utility><nav class=w-footer__utility-nav><a data-category="Site-Wide Custom Events"data-label="Footer Google Developers Link"class=w-footer__utility-logo-link href=https://developers.google.com/> <img alt="Google Developers"class=w-footer__utility-logo height=33 loading=lazy src=/images/lockup-color.png width=185> </a><ul class=w-footer__utility-list><li class=w-footer__utility-item><a data-category="Site-Wide Custom Events"data-label="Footer Chrome Link"class=w-footer__utility-link href=https://developer.chrome.com/> Chrome </a><li class=w-footer__utility-item><a data-category="Site-Wide Custom Events"data-label="Footer Firebase Link"class=w-footer__utility-link href=https://firebase.google.com/> Firebase </a><li class=w-footer__utility-item><a data-category="Site-Wide Custom Events"data-label="Footer Google Cloud Platform Link"class=w-footer__utility-link href=https://cloud.google.com/> Google Cloud Platform </a><li class=w-footer__utility-item><a data-category="Site-Wide Custom Events"data-label="Footer All products Link"class=w-footer__utility-link href=https://developers.google.com/products> All products </a></ul><web-language-select current=en> </web-language-select></nav><nav class=w-footer__utility-nav><ul class=w-footer__utility-list><li class=w-footer__utility-item><a data-category="Site-Wide Custom Events"data-label="Footer Terms and Privacy link"class=w-footer__utility-link href=https://policies.google.com/> Terms & Privacy </a><li class=w-footer__utility-item><a data-category="Site-Wide Custom Events"data-label="Footer Community Guidelines link"class=w-footer__utility-link href=/community-guidelines/> Community Guidelines </a></ul><div class=w-footer__license><p>Except as otherwise noted, the content of this page is licensed under the <a href=https://creativecommons.org/licenses/by/4.0/> Creative Commons Attribution 4.0 License </a> , and code samples are licensed under the <a href=https://www.apache.org/licenses/LICENSE-2.0> Apache 2.0 License </a> . For details, see the <a href=https://developers.google.com/terms/site-policies> Google Developers Site Policies </a> .</div></nav></div></footer>