Python 仅读取.txt文件中的最后一个字符
我正在使用读取txt文件并将结果发送到arduino的处理创建一个程序。 我可以让它发送字符串并保持更新,但一旦我尝试只发送最后一个字符,它将无法工作。。。有人能帮我吗?基本上,我需要从一个txt文件中读取最后一个字符,并通过串行方式将其作为字符发送到arduino、python或处理两者都可以 *这是我的代码[处理]Python 仅读取.txt文件中的最后一个字符,python,processing,Python,Processing,我正在使用读取txt文件并将结果发送到arduino的处理创建一个程序。 我可以让它发送字符串并保持更新,但一旦我尝试只发送最后一个字符,它将无法工作。。。有人能帮我吗?基本上,我需要从一个txt文件中读取最后一个字符,并通过串行方式将其作为字符发送到arduino、python或处理两者都可以 *这是我的代码[处理] import processing.serial.*; import java.io.*; int mySwitch=0; int counter=0; String [] s
import processing.serial.*;
import java.io.*;
int mySwitch=0;
int counter=0;
String [] subtext;
Serial myPort;
void setup(){
//Create a switch that will control the frequency of text file reads.
//When mySwitch=1, the program is setup to read the text file.
//This is turned off when mySwitch = 0
mySwitch=1;
//Open the serial port for communication with the Arduino
//Make sure the COM port is correct
myPort = new Serial(this, "COM4", 9600);
myPort.bufferUntil('\n');
}
void draw() {
if (mySwitch>0){
/*The readData function can be found later in the code. This is the call to read a CSV file on the computer hard-drive. */
readData("G:/Personal/control.txt");
/*The following switch prevents continuous reading of the text file, until we are ready to read the file again. */
mySwitch=0;
}
/*Only send new data. This IF statement will allow new data to be sent to the arduino. */
if(counter<subtext.length){
/* Write the next number to the Serial port and send it to the Arduino There will be a delay of half a second before the command is sent to turn the LED off : myPort.write('0'); */
myPort.write(subtext[counter]);
delay(500);
myPort.write('0');
delay(100);
//Increment the counter so that the next number is sent to the arduino.
counter++;
} else{
//If the text file has run out of numbers, then read the text file again in 5 seconds.
delay(5000);
mySwitch=1;
}
}
/* The following function will read from a CSV or TXT file */
void readData(String myFileName){
File file=new File(myFileName);
BufferedReader br=null;
try{
br=new BufferedReader(new FileReader(file));
String text=null;
/* keep reading each line until you get to the end of the file */
while((text=br.readLine())!=null){
* Spilt each line up into bits and pieces using a comma as a separator */
subtext = splitTokens(text,",");
}
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}finally{
try {
if (br != null){
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
import processing.serial.*;
导入java.io.*;
int-mySwitch=0;
int计数器=0;
字符串[]潜文本;
串行端口;
无效设置(){
//创建一个控制文本文件读取频率的开关。
//当mySwitch=1时,程序被设置为读取文本文件。
//当mySwitch=0时,此选项关闭
mySwitch=1;
//打开串行端口与Arduino进行通信
//确保COM端口正确
myPort=新序列号(此“COM4”,9600);
myPort.bufferUntil('\n');
}
作废提款(){
如果(mySwitch>0){
/*readData函数可以在代码后面找到。这是读取计算机硬盘上CSV文件的调用*/
readData(“G:/Personal/control.txt”);
/*下面的开关阻止连续读取文本文件,直到我们准备再次读取该文件*/
mySwitch=0;
}
/*仅发送新数据。此IF语句将允许向arduino发送新数据*/
如果(计数器从文件中读取最后一个字符:
打开(文件名为“rb+”)作为f的:
f、 seek(f.tell()-1,2)#f.seek(0,2)对于Python2和Python3中的最后一个字符是合法的
打印f.read()
用于Python 3
为了使其更通用,假设我们希望在不打开二进制模式的情况下读取文件的倒数第二个字符(可以是任何字符):
以open('file.txt','r')作为f的:
f、 寻找(0,2)
#seek到文件结尾;f.seek(0,os.seek_end)是合法的
f、 寻道(f.tell()-2,0)
#查找文件的最后一个字符;
#虽然f.seek(f.tell()-2,os.seek_SET)是合法的,
#f.seek(-2,0)将抛出错误。
打印(f.read())
Seek是一个处理注释的文件对象
file.seek(偏移量、位置)
偏移量
:需要多少字符(即1表示一个字符)
位置
:告诉您的文件读/写操作应该从哪里开始。
- 0表示文件的开始
- 1表示文件读/写光标的当前位置
- 2表示文件结束
f.seek(f.tell()-1,2)
表示转到文件末尾并向后遍历一个元素
print f.read()
打印从seek命令获得的值我所做的:
打开文件
把最后一行读作列表
将其转换为字符串,并读取最后一个字符并打印为
a=open('does&donts.txt','rb')
lines = a.readlines()
a.close()
if lines:
last_line = lines[-1]
print last_line
b="".join(last_line)
print b[-1:]
希望对您有所帮助。Stefan的回答很简单,是一种工作,但不考虑文本文件:
- UTF-8编码包含非英语字符(这是Python 3中文本文件的默认编码)
- 文件末尾的一个换行符(这是Linux编辑器中的默认值,如
vim
或gedit
)
如果文本文件包含非英语字符,那么到目前为止提供的两个答案都不起作用
下面的例子解决了这两个问题
import os
def get_last_utf8_char(filename, ignore_newlines=True):
"""
Reads the last character of a UTF-8 text file.
:param filename: The path to the text file to read
:param ignore_newlines: Set to true, if the newline character at the end of the file should be ignored
:return: Returns the last UTF-8 character in the file or None, if the file is empty
"""
with open(filename, 'rb') as f:
last_char = None
# Reads last 4 bytes, as the maximum size of an UTF-8 character is 4 bytes
num_bytes_to_read = 4
# If ignore_newlines is True, read two more bytes, as a newline character
# can be up to 2 bytes (eg. \r\n)
# and we might have a newline character at the end of file
# or size bytes, if file's size is less than 4 bytes
if ignore_newlines:
num_bytes_to_read += 2
size = os.fstat(f.fileno()).st_size
f.seek(-min(num_bytes_to_read, size), os.SEEK_END)
last_bytes = f.read()
# Find the first byte of a UTF-8 character, starting
# from the last byte
offset = -1
while abs(offset) <= len(last_bytes):
b = last_bytes[offset]
if ignore_newlines and b in b'\r\n':
offset -= 1
continue
if b & 0b10000000 == 0 or b & 0b11000000 == 0b11000000:
# If this is first byte of a UTF8 character,
# interpret this and all bytes after it as UTF-8
last_char = last_bytes[offset:].decode('utf-8')
break
offset -= 1
if last_char and ignore_newlines:
last_char = last_char.replace('\r', '').replace('\n', '')
return last_char
如何使用:
>>> get_last_utf8_char('bg.txt')
т
这适用于UTF-8和ASCII编码文件。我能想到的最简单的事情是:
s="".join(list(open(rfile_directory)))
pos=s[-1:]
步骤:
打开文件
将其转换为列表
已将列表加入str表单
最后一个角色
现在,如果需要int形式的字符,只需:
pos=int(s[-1:])
简单地说:
with open("file.txt", "r") as f:
file_str = str(f.read())
f.close()
last_chr = file_str[-1]
print(last_chr)
通过“r”而不是“rb”读取文件很重要。向我们展示您的代码和一个带有字符的示例文件我正在处理的代码和数据:)以f:f.seek(-1,2)print f.read(1)形式导入操作系统并打开('G:\Personal\control.txt','rb+')像这样?offset
参数的解释可以重写一点。目前它给人的印象是,offset
决定下一次调用read
读取多少字节,这仅在这个非常特定的上下文中是正确的(因为我们正在读取文件末尾的所有内容)。此外,2
可以替换为os.SEEK\u END以使其更具可读性,并且实际上不需要+
模式,因为文件未修改,仅读取。请注意,该模式在二进制模式下读取,并不适用于所有用例。如果您使用的是附加+读取(a+)模式,并且需要使用字符串,然后为了使代码更明确,可以在调用seek()时使用内置常量而不是2
不需要为了一个字符而读取整个文件,请使用file.seek
。想象一下,为了检索最后一个字符(例如,20个字符),必须在内存中加载2GB日志文件。
with open("file.txt", "r") as f:
file_str = str(f.read())
f.close()
last_chr = file_str[-1]
print(last_chr)