g | x | w | all
Bytes Lang Time Link
194Swift 6250301T223849ZmacOSist
082Tcl170128T015206Zsergiol
051Pyth210318T184406ZCitty
009Zsh C4190813T052043ZGammaFun
056Red200509T073456ZHotelFol
020PowerShell 6+ for Windows200509T060850Zmazzy
060BATCH File170127T214830ZAdmBorkB
180C++17 gcc190817T190013ZG. Sliep
033Batch File190613T020610ZBDM
105SmileBASIC 3180501T232531Zsnail_
110SmileBASIC170127T212339Z12Me21
020J170128T010558Zmiles
031Röda170307T182357Zfergusq
012Vim170127T224508ZDJMcMayh
037Ruby170127T213616Zanna328p
013Bash + coreutils170127T212310ZRiker
277C#170201T103452ZMika
014SH Linux/Unix170128T055106ZAbel Tom
8462PHP170128T024037ZCave Joh
021PowerShell170127T212924ZAdmBorkB
049Groovy170130T144201ZMagic Oc
036R170129T232849ZBillywob
nan170128T034701ZBrad Gil
035Batch170127T220135ZNeil
142Java 7170128T024518ZPoke
052Scala170129T031939ZAria Ax
048MATLAB / Octave170127T212108ZSuever
054Python170127T213017Zovs
114Node.js using walk170128T030936ZPatrick
035Mathematica170127T213523ZGreg Mar

Swift 6, 194 bytes

import Foundation
let f=FileManager.default
print(try{f.contentsOfDirectory}()(f.currentDirectoryPath).map{(try{f.attributesOfItem}()($0)[.size]as!Int,$0)}.sorted(by:<)[0].1)

Try it on SwiftFiddle! (yes, it works on SwiftFiddle)

Ungolfed

// Foundation import for access to FileManager
import Foundation

// save bytes when calling methods on the FileManager
// (this stuff is bridged from Objective-C, so things can
// get VERY wordy)
let f = FileManager.default

print(
  // get the contents of the current directory
  // (wrap it in a closure first to deal away with
  // argument labels)
  try {f.contentsOfDirectory}()(f.currentDirectoryPath).map {
    // a tuple of the file size and its name, **in that order**
    (try {f.attributesOfItem}()($0)[.size] as! Int, $0)
  // sort the tuples, get the first one, and extract the
  // filename
  // - the `<` operator on 2-tuples prioritizes the first
  //   element and falls back to the second
  // - since tuples can't conform to Comparable, we have to
  //   provide the operator ourselves (it's declared as a
  //   global for tuples)
  }.sorted(by: <)[0].1
)
```

Tcl, 82 bytes

set s Inf
lmap f [glob *] {if [set m [file si $f]]<$s {set n $f
set s $m}}
puts $n

Try it online!

Pyth, 51 bytes

.ml$open(b,"rb").read()$$__import__("os").listdir()

I feel like Pyth might not be the best tool for the job here...

Try it online!

Zsh -C4, 9 bytes

Leading/trailing symbols are allowed, as long as it's clear which file has been chosen.

The following prints the file name, preceded by $0:1: file exists: and followed by a newline, to stderr:

>*(oL[1])

Try it online! Try it online! Try it online!


I used to have just *(oL[1]) and rely on Zsh printing "command not found", but if the file matches the name of a builtin or executable, this would break. Additionally, the previous echo methods would break if the smallest file was -e or - or similar (interpreted as a flag to echo). This new method works for all file names and is still very short.

Red, 56 bytes

first sort/compare read %. func[a b][(size? a)< size? b]

PowerShell 6+ for Windows, 20 bytes

ls|sort l* -t 1|% n*

Try it online!

Unrolled:

ls|sort length -top 1|% Name

See also AdmBorkBork's answer.

BATCH File, 77 72 63 60 bytes

@FOR /F tokens^=* %%G IN ('dir/o-s/b')DO @SET[=%%G
@ECHO %[%

There's no direct equivalent of head or tail in BATCH, at least to my knowledge, so here's a kludgy work-around. (with much assistance from @Neil - thanks!)

The dir command, with /o-s to sort in descending file size, and /b to output only the file names. We loop through those with FOR /F, setting the variable [ to the file name each time. Finally, we output just the last one with ECHO %[%.

Saved 9 more bytes thanks to Neil and thanks to guarantees that no directories are present.
Saved 3 bytes thanks to HackingAddict1337.

C++17 (gcc), 180 bytes

#include<filesystem>
using namespace std::filesystem;auto f(){std::error_code e;path r;size_t m=-1,s;for(auto&p:directory_iterator(".")){s=file_size(p,e);if(s<m)m=s,r=p;}return r;}

Try it online!

Requires a recent standard library that implements std::filesystem.

Batch File, 33 bytes

Batch files are moderately competitive this time, oddly enough.

@dir/os/b>..\q&set/pa=<..\q&"%a%.

Output

enter image description here


Find a way to stop the creation of q prior to dir/os/b being run and you'll save a maximum of 6 bytes by not needing to put the output file in a separate directory.

@dir/os/b>q&set/pa=<q&"%a%

Will always output q as the smallest file (unless tied for another 0 byte file) as it is created as an empty file before dir/b/os gathers a list of files.

SmileBASIC 3, 105 bytes (competing?)

Beats 12Me21's answer but still suffers from inability to load DAT files (which feels very cruel to be disqualifying considering the circumstances.)

DIM F$[0],T[0]FILES"TXT:",F$FOR I=0TO LEN(F$)-1F$[I][0]="TXT:
PUSH T,LEN(LOAD(F$[I]))NEXT
SORT T,F$?F$[0]

The shorter version above is annoying and prompts you on every file to load, but it does work. For two bytes more you can suppress the prompt; change line 2 to this:

PUSH T,LEN(LOAD(F$[I],0))NEXT

SmileBASIC, 110 bytes

DIM F$[0]FILES"TXT:",F$FOR I=0TO LEN(F$)-1F$[I][0]="TXT:
S=LEN(LOAD(F$[I],0))IF!Z||S<Z THEN Z=S:B=I
NEXT?F$[B]

Only looks at TXT: files, since DAT: files cannot be loaded unless you already know their size, making it impossible to load a random one.

J, 21 20 bytes

>{.,(/:2&{"1)1!:0'*'

Saved a byte thanks to @Conor.

Explanation

>{.,(/:2&{"1)1!:0'*'
                 '*' Glob all files in current directory
             1!:0    Table of file metadata in that directory
       2&{"1         Get the file size of each
     /:              Sort the files by that
   ,                 Flatten
 {.                  Get the first value
>                    Unbox

Röda, 32 31 bytes

{ls""|sort key=fileLength|pull}

It's an anonymous function that sorts the files in the current directory by file length and selects then the first file with pull.

Use it like this: main{ {ls""|sort key=fileLength|pull} }

Vim 12 bytes

!!ls -Sa
Gd{

Try it online!

Explanation:

!! is the filter command. It pipes the contents of the current line to an arbitrary system command, and sends the output back into the buffer. It's useful for using external tools for things that bash is better at than vim, for example !!rev to reverse the current line, or !Gxxd to hexdump the buffer. In our case, the buffer is empty so it's equivalent to :r!ls, which just feeds the output of the command into the current line.

Now the cursor is on line 1, and we want to delete every line but the last one. The naïve approach is

G       " Go to the last line
 k      " Go up one line
  d     " Delete:
   gg   "   Everything up to the first line

But we can do better. Like I explained in this tip, the { can usually (but not always) be equivalent to gg. Here, it's even better. Because the motion is character-based, not line-based like gg is, we don't have to go up a line first, leaving us with

Gd{

Ruby, 61 40 38 37 bytes

Thanks G B and Value Ink

p Dir[?*,".*"].min_by{|x|File.size x}

Bash + coreutils, 13 bytes

ls -Sar|sed q

Explanation:

ls -Sar|sed q
ls            # list files
   -S         # sorted, biggest first
     a        # show hidden files
      r       # reversed (smallest first)
       |sed q # q is quit at first line that matches given regex, 
              # given regex is empty so guaranteed match.         

C#, 277 bytes

Not the shortest, but what would you expect from C#?

Golfed

using System.Linq;using static System.IO.Directory;class P{static void Main(){var x=GetFiles(GetCurrentDirectory());var d=new long[]{}.ToList();foreach(var s in x){var b=new System.IO.FileInfo(s).Length;if(!d.Contains(b))d.Add(b);}System.Console.Write(x[d.IndexOf(d.Min())]);}}

Ungolfed

//Linq using for List.Min()
using System.Linq;
//Static using to save bytes on GetCurrentDirectory() and GetFiles()
using static System.IO.Directory;

class P
{
    static void Main()
    {
        //String array containing file paths
        var x = GetFiles(GetCurrentDirectory());
        //Creating a Long array and converting it to a list, less bytes than "new System.Collections.Generic.List<long>()"
        var d = new long[] { }.ToList();
        foreach (var s in x) //Loop through all file paths
        {
            //Getting file size in bytes
            var b = new System.IO.FileInfo(s).Length;
            if (!d.Contains(b))
                //If there isn't already a file with this size in our List, add the file path to list
                d.Add(b);

        }
        //Get index of the smallest Long in our List, which is also the index of the file path to the smallest file, then write that path
        System.Console.Write(x[d.IndexOf(d.Min())]);
    }
}

SH (Linux/Unix) 15 14 13 14 bytes

ls -aS|tail -1

-S sorts by size (descending),

-rreverses and tail -1 outputs the last file in the list.

@ Dennis Thanks for saving 1 byte @Dani_l Thanks for saving 1 byte.

PHP, 84 62 bytes

$t=array_map(filesize,$g=glob('*'));asort($t);echo$g[key($t)];

Since the question was updated with the assumption that there will be no folders in the current directory, I was able to remove the file check stuff and golf this down.


Here is my old answer:

$t=array_map(filesize,$g=array_filter(glob('*'),is_file));asort($t);echo$g[key($t)];

This is the best I could do. Maybe there is a better way I'm missing.

$t=array_map(              # visit each array element and...
    filesize,              # map each filename to its filesize...
    $g=array_filter(       # using an array of...
        glob('*'),         # all files and directories...
        is_file            # filtered by files...
    )                      # 
);                         # 
asort($t);                 # sort the array of filesizes, then...
echo$g[key($t)];           # print element from the array of files using the first key of the sorted array as an index

PowerShell, 30 24 21 bytes

(ls|sort le*)[0].Name

Try it online!

ls is an alias for Get-ChildItem. That's piped to sort-object with the length attribute, so the files are sorted by size. We index into that with the (...)[0] to get the first (i.e., smallest), and then take the .Name thereof. Output via implicit Write-Output happens at program completion.

Saved 6 bytes since we're guaranteed that only files exist in the directory. Saved an additional 3 thanks to ConnorLSW.

Groovy, 49 bytes

m={f->f.listFiles().sort{it.length()}[0].getName()}

Try it online!

Closure, usage: m(new File("location"))

R, 36 bytes

x=file.info(y<-dir())$s;y[x==min(x)]

Explained

file.info() returns a data.frame of "file information" when given a character or character vector of file/folder names which when used on the list of files/folders in the current directory (dir()), looks something like:

                                                               size isdir mode               mtime               ctime               atime exe
Polyspace_Workspace                                               0  TRUE  777 2014-11-28 17:29:25 2014-11-28 17:29:25 2014-11-28 17:29:25  no
Python Scripts                                                    0  TRUE  777 2016-03-21 23:59:41 2016-03-21 23:59:41 2016-03-21 23:59:41  no
R                                                                 0  TRUE  777 2015-12-23 20:11:02 2015-12-23 20:11:02 2015-12-23 20:11:02  no
Rockstar Games                                                    0  TRUE  777 2015-04-14 12:23:05 2015-04-14 12:23:03 2015-04-14 12:23:05  no
TrackmaniaTurbo                                                   0  TRUE  777 2016-03-24 17:15:05 2016-03-24 13:13:48 2016-03-24 17:15:05  no
ts3_clientui-win64-1394624943-2014-06-11 03_18_47.004772.dmp 314197 FALSE  666 2014-06-11 02:18:47 2014-06-11 02:18:47 2014-06-11 02:18:47  no

Subsequently we just have the find the name of the file for which the size column (abbreviated using $s) is the smallest. Consequently, if there are more than one file with the smallest size, all will be returned.

Bonus: if we also wanted to disregard folders in the current directory we could simply search for size when isdir == FALSE: x=file.info(y<-dir());y[x$s==min(x$s[!x$i])] which turns out to be 44 bytes.

Perl 6,  33 32 31  16 bytes

'.'.IO.dir.grep(*.f).min(*.s).put

Try it

put '.'.IO.dir.min:{try .s//Inf}

Try it

put $*CWD.dir.min:{try .s//Inf}

Try it

put dir.min: *.s

Try it

Expanded:

put        # print with trailing newline
dir        # the list of files in the current directory
.min:      # find the minimum by
  *.s      # calling the `s` method (size) in a Whatever lambda

Batch, 43 39 35 bytes

@dir/b/os|(set/pf=&call echo %%f%%)

Output includes a leading space for some reason, but fortunately that's allowed. Edit: Now assuming there are no directories to save 4 bytes.

Java 7, 149 142 bytes

String f(){String n="";long s=-1>>>1,p;for(java.io.File f:new java.io.File(".").listFiles())if((p=f.length())<s){n=f.getName();s=p;}return n;}

Try it online!

-7 bytes thanks to CAD97

Scala, 52 bytes

Old version, 79 bytes

new java.io.File(".").listFiles.map(a=>a.getName->a.length)sortBy(_._2)apply(0)

Adjusted according to jaxad0127's advice. It is only 52 bytes now.

new java.io.File(".").listFiles.sortBy(_.length)head

MATLAB / Octave, 52 48 bytes

d=dir;[~,n]=min([d.bytes]./~[d.isdir]);d(n).name

Explanation

This gets a directory listing of all files and folders in the current directory using dir. The output of dir is a struct containing the filename, whether it's a directory or not, the size (in bytes), etc.

We can then take an array of the sizes of each in bytes [d.bytes] and perform element-wise division with a boolean indicating whether it's a directory or not ~[d.isdir] which will yield Inf where it's a directory (division by zero) and the size in bytes otherwise (division by 1).

We find the index of the minimum of this array using the second output of min and use that to index into the initial struct and display the name with d(n).name

Python 2 3, 94 76 74 54 bytes

-18 bytes thanks to @orlp
-2 bytes thanks to @Jonathan Allan
-20 bytes thanks to a change in challenge specs

from os import*
print(min(listdir(),key=path.getsize))

Node.js (using walk), 114 bytes

Ignore newline:

require('walk').walk(__dirname).on('file',(r,s,n)=>
(m=s.size>m.size?m:s,n()),m=0).on('end',_=>console.log(m.name))

This invokes a walker that traverses through the current directory (__dirname) and for each file calls a function with its stat s and a function next n() that must be invoked to continue the traversal. Then at the end, it prints a filename with the minimum size in bytes found. s.size>m.size returns false when m.size is undefined, so after the first callback, m is equal to the first file found, and continues from there normally.

Mathematica, 35 bytes

FileNames[]~MinimalBy~FileByteCount

FileNames[] produces a list of names of all the files (and directories) in the current directory; ~MinimalBy~FileByteCount selects the name of the file whose byte count is smallest. FileByteCount throws a bunch of errors when it's applied to directories, but the errors don't derail the program.