Asked  7 Months ago    Answers:  5   Viewed   35 times

What's the quickest, easiest way to read the first line only from a file? I know you can use file, but in my case there's no point in wasting the time loading the whole file.

Preferably a one-liner.



Well, you could do:

$f = fopen($file, 'r');
$line = fgets($f);

It's not one line, but if you made it one line you'd either be screwed for error checking, or be leaving resources open longer than you need them, so I'd say keep the multiple lines


If you ABSOLUTELY know the file exists, you can use a one-liner:

$line = fgets(fopen($file, 'r'));

The reason is that PHP implements RAII for resources.

That means that when the file handle goes out of scope (which happens immediately after the call to fgets in this case), it will be closed.

Wednesday, March 31, 2021
answered 7 Months ago

It happens because PHP CS Fixer modifies the file, as @LazyOne said, but you have empty value of "Output paths to refresh" so IDE cannot know about these changes.

Set the value of "Output paths to refresh" to $FileName$ - same as in arguments - to make PhpStorm aware about the changes (it depends on the "Working directory" value which has been set in Other Options - if it is set to $FileDir$ then you don't need to mention it in the paths to refresh).

Wednesday, March 31, 2021
answered 7 Months ago

Here's a general-purpose batch file to print the top n lines from a file like the GNU head utility, instead of just a single line.

@echo off

if [%1] == [] goto usage
if [%2] == [] goto usage

call :print_head %1 %2
goto :eof

REM print_head
REM Prints the first non-blank %1 lines in the file %2.
setlocal EnableDelayedExpansion
set /a counter=0

for /f ^"usebackq^ eol^=^

^ delims^=^" %%a in (%2) do (
        if "!counter!"=="%1" goto :eof
        echo %%a
        set /a counter+=1

goto :eof

echo Usage: head.bat COUNT FILENAME

For example:

Z:>head 1 "test file.c"
; this is line 1

Z:>head 3 "test file.c"
; this is line 1
    this is line 2
line 3 right here

It does not currently count blank lines. It is also subject to the batch-file line-length restriction of 8 KB.

Tuesday, June 1, 2021
answered 5 Months ago

I've started project called Big File Tools. It is proven to work on Linux, Mac and Windows (even 32-bit variants). It provides byte-precise results even for huge files (>4GB). Internally it uses brick/math - arbitrary-precision arithmetic library.

Install it using composer.

composer install jkuchar/BigFileTools

and use it:

$file = BigFileToolsBigFileTools::createDefault()->getFile(__FILE__);
echo $file->getSize() . " bytesn";

Result is BigInteger so you can compute with results

$sizeInBytes = $file->getSize();
$sizeInMegabytes = $sizeInBytes->toBigDecimal()->dividedBy(1024*1024, 2, BrickMathRoundingMode::HALF_DOWN);    
echo "Size is $sizeInMegabytes megabytesn";

Big File Tools internally uses drivers to reliably determine exact file size on all platforms. Here is list of available drivers (updated 2016-02-05)

| Driver           | Time (s) ?          | Runtime requirements | Platform 
| ---------------  | ------------------- | --------------       | ---------
| CurlDriver       | 0.00045299530029297 | CURL extension       | -
| NativeSeekDriver | 0.00052094459533691 | -                    | -
| ComDriver        | 0.0031449794769287  | COM+.NET extension   | Windows only
| ExecDriver       | 0.042937040328979   | exec() enabled       | Windows, Linux, OS X
| NativeRead       | 2.7670161724091     | -                    | -

You can use BigFileTools with any of these or fastest available is chosen by default (BigFileTools::createDefault())

 use BigFileToolsBigFileTools;
 use BigFileToolsDriver;
 $bigFileTools = new BigFileTools(new DriverCurlDriver());
Wednesday, June 2, 2021
answered 5 Months ago

I very much doubt that BufferedReader is going to cause a significant overhead. Adding your own code is likely to be at least as inefficient, and quite possibly wrong too.

For example, in the code that you've given you're calling new String(bytes) which is always going to create a string from 1024 bytes, using the platform default encoding... not a good idea. Sure, you clear the array afterwards, but your strings are still going to contain a bunch of '' characters - which means a lot of wasted space, apart from anything else. You should at least restrict the portion of the byte array the string is being created from (which also means you don't need to clear the array afterwards).

Have you actually tried using BufferedReader and found it to be too slow? You should usually write the simplest code which will meet your goals first, and then check whether it's fast enough... especially if your only reason for not doing so is an unspecified resource you "read on the internet". DO you want me to find hundreds of examples of people spouting incorrect performance suggestions? :)

As an alternative, you might want to look at Guava's overload of Files.readLines() which takes a LineProcessor.

Wednesday, August 4, 2021
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :