Эта ошибка чаще всего встречается при попытке ссылаться на значение массива с помощью ключевого слова для интерполяции внутри строки с двумя кавычками , когда вся конструкция комплексной переменной не заключена в {}
.
Это приведет к Unexpected T_ENCAPSED_AND_WHITESPACE
:
echo "This is a double-quoted string with a quoted array key in $array['key']";
//---------------------------------------------------------------------^^^^^
В строке с двойными кавычками PHP разрешает использовать строки ключей ключей без кавычек и не выдаст E_NOTICE
. Таким образом, вышесказанное может быть записано как:
echo "This is a double-quoted string with an un-quoted array key in $array[key]";
//------------------------------------------------------------------------^^^^^
Вся сложная переменная массива и ключ (ы) могут быть заключены в {}
, и в этом случае они должны быть указаны чтобы избежать E_NOTICE
. Документация PHP рекомендует этот синтаксис для сложных переменных.
echo "This is a double-quoted string with a quoted array key in {$array['key']}";
//--------------------------------------------------------------^^^^^^^^^^^^^^^
// Or a complex array property of an object:
echo "This is a a double-quoted string with a complex {$object->property->array['key']}";
Конечно, альтернатива любой из вышеперечисленного заключается в объединении переменной массива in вместо интерполировать его:
echo "This is a double-quoted string with an array variable " . $array['key'] . " concatenated inside.";
//----------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^
Для справки см. раздел «Переменная синтаксический анализ» в странице руководства PHP Strings
Читайте до конца файла, затем ищите назад, пока Вы не найдете десять новых строк, и затем считаете вперед до конца учет различной кодировки. Обязательно обработайте случаи, где количество строк в файле - меньше чем десять. Ниже реализация (в C#, когда Вы отметили это), обобщенный для нахождения последнего numberOfTokens
в файле расположенным в path
закодированный в encoding
, где маркерный разделитель представлен tokenSeparator
; результат возвращается как string
(это могло быть улучшено путем возврата IEnumerable<string>
, который перечисляет маркеры).
public static string ReadEndTokens(string path, Int64 numberOfTokens, Encoding encoding, string tokenSeparator) {
int sizeOfChar = encoding.GetByteCount("\n");
byte[] buffer = encoding.GetBytes(tokenSeparator);
using (FileStream fs = new FileStream(path, FileMode.Open)) {
Int64 tokenCount = 0;
Int64 endPosition = fs.Length / sizeOfChar;
for (Int64 position = sizeOfChar; position < endPosition; position += sizeOfChar) {
fs.Seek(-position, SeekOrigin.End);
fs.Read(buffer, 0, buffer.Length);
if (encoding.GetString(buffer) == tokenSeparator) {
tokenCount++;
if (tokenCount == numberOfTokens) {
byte[] returnBuffer = new byte[fs.Length - fs.Position];
fs.Read(returnBuffer, 0, returnBuffer.Length);
return encoding.GetString(returnBuffer);
}
}
}
// handle case where number of tokens in file is less than numberOfTokens
fs.Seek(0, SeekOrigin.Begin);
buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
return encoding.GetString(buffer);
}
}
Почему бы не использовать file.readalllines, который возвращает строку []?
Тогда можно получить последние 10 строк (или члены массива), который был бы тривиальной задачей.
Этот подход не принимает во внимание проблем кодирования, и я не уверен в точной эффективности этого подхода (время, потраченное для завершения метода, и т.д.).
Откройте файл и начните читать строки. После чтения 10 строк, открытых другой указатель, запускающийся впереди файла, таким образом, второй указатель изолирует первое 10 строками. Продолжайте читать, перемещая эти два указателя в унисон, до первых пределов конец файла. Тогда используйте второй указатель для чтения результата. Это работает с любым файлом размера включая пустой и более короткое, чем длина хвоста. И легко корректироваться для любой длины хвоста. Недостаток, конечно, состоит в том, что Вы заканчиваете тем, что читали весь файл, и это может быть точно, чего Вы стараетесь избегать.
Я думаю, что другие плакаты все показали, что нет никакого реального ярлыка.
можно или использовать инструмент, такой как хвост (или powershell), или можно записать некоторый немой код, который ищет конец файла и затем оглядывается назад для n новых строк.
существует много реализаций хвоста там в сети - смотрят на исходный код, чтобы видеть, как они делают это. Хвост довольно эффективен (даже на очень очень больших файлах) и таким образом, у них должен быть он право, когда они записали его!
Если Вы открываете файл с FileMode. Добавьте его, будет искать до конца файла Вас. Тогда Вы могли искать назад число байтов, Вы хотите и читаете их. Это не могло бы быть быстро, хотя независимо от того, что Вы делаете, так как это - довольно крупный файл.
Один полезный метод FileInfo.Length
. Это дает размер файла в байтах.
, Какая структура является Вашим файлом? Вы уверены, что последние 10 строк будут около конца файла? Если у Вас будет файл с 12 строками текста и 10 ГБ 0s, то рассмотрение конца действительно не будет этим быстро. С другой стороны Вам, возможно, придется просмотреть целый файл.
, Если Вы уверены, что файл содержит многочисленные короткие строки каждый на новой строке, ищите до конца, затем перепроверьте, пока Вы не считали 11 концов строк. Тогда можно читать вперед для следующих 10 строк.
Вы могли использовать версию для Windows хвост команда, и просто pype это производится к текстовому файлу с> символ, или просмотрите его на экране в зависимости от того, каковы Ваши потребности.
Я думаю, что следующий код решит prblem с тонкой переаттестацией изменений, кодирующей
StreamReader reader = new StreamReader(@"c:\test.txt"); //pick appropriate Encoding
reader.BaseStream.Seek(0, SeekOrigin.End);
int count = 0;
while ((count < 10) && (reader.BaseStream.Position > 0))
{
reader.BaseStream.Position--;
int c = reader.BaseStream.ReadByte();
if (reader.BaseStream.Position > 0)
reader.BaseStream.Position--;
if (c == Convert.ToInt32('\n'))
{
++count;
}
}
string str = reader.ReadToEnd();
string[] arr = str.Replace("\r", "").Split('\n');
reader.Close();
Именно это делает команда хвоста Unix. См. http://en.wikipedia.org/wiki/Tail_ (Unix)
существует много реализаций с открытым исходным кодом в Интернете и здесь один для win32: Хвост для WIn32
Я не уверен, насколько эффективный это будет, но в Windows PowerShell, получая последние десять строк файла так же легко как
Get-Content file.txt | Select-Object -last 10
Необходимо быть в состоянии использовать FileStream. Ищите () , чтобы переместиться до конца файла, затем проложить себе путь назад, ища \n, пока у Вас не будет достаточного количества строк.
Как другие предположили, можно пойти до конца файла и читать назад, эффективно. Однако это немного хитро - особенно, потому что, если у Вас есть кодирование переменной длины (такое как UTF-8) необходимо быть хитростью о проверке, что Вы получаете "целые" символы.
Я, вероятно, просто открыл бы его как двоичный поток, искал бы до конца, затем обратно ища разрывы строки. Создайте резервную копию 10 (или 11 в зависимости от той последней строки) для нахождения 10 строк, тогда просто читайте до конца и Кодирование использования. GetString на том, что Вы читаете для получения его в формат строки. Разделение, как желаемый.
Хвост? Хвост является командой Unix, которая отобразит последние несколько строк файла. Существует версия Windows в набор ресурса Windows 2003 Server .
Я использовал этот код для маленькой утилиты когда-то назад, я надеюсь, что он может помочь Вам!
private string ReadRows(int offset) /*offset: how many lines it reads from the end (10 in your case)*/
{
/*no lines to read*/
if (offset == 0)
return result;
using (FileStream fs = new FileStream(FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 2048, true))
{
List<char> charBuilder = new List<char>(); /*StringBuilder doesn't work with Encoding: example char
Если у вас есть файл с четным форматом на строку (например, система daq), вы просто используйте streamreader, чтобы получить длину файла, затем возьмите одну из строк ( readline ()
).
Разделите общую длину на длину строки. Теперь у вас есть общее длинное число, представляющее количество строк в файле.
Ключ в том, что вы используете readline ()
до получения данных для вашего массива или чего-то еще. Это гарантирует, что вы начнете с начала новой строки и не получите каких-либо данных, оставшихся от предыдущей.
StreamReader leader = new StreamReader(GetReadFile);
leader.BaseStream.Position = 0;
StreamReader follower = new StreamReader(GetReadFile);
int count = 0;
string tmper = null;
while (count <= 12)
{
tmper = leader.ReadLine();
count++;
}
long total = follower.BaseStream.Length; // get total length of file
long step = tmper.Length; // get length of 1 line
long size = total / step; // divide to get number of lines
long go = step * (size - 12); // get the bit location
long cut = follower.BaseStream.Seek(go, SeekOrigin.Begin); // Go to that location
follower.BaseStream.Position = go;
string led = null;
string[] lead = null ;
List<string[]> samples = new List<string[]>();
follower.ReadLine();
while (!follower.EndOfStream)
{
led = follower.ReadLine();
lead = Tokenize(led);
samples.Add(lead);
}